๐Ÿ‘ฉ๐Ÿปโ€๐ŸŒพ

Chap 4. The Greedy Approach ๋ณธ๋ฌธ

Study/Algorithm

Chap 4. The Greedy Approach

์ฅฌ์Šค์ด 2023. 6. 1. 17:32
728x90
Greedy Algorithm
-๋งค ์ˆœ๊ฐ„ ๊ฐ€์žฅ ์ข‹์•„๋ณด์ด๋Š” ๊ฒƒ์„ ๊ณ ๋ฅด๋Š” ๋ฐฉ๋ฒ•
General Greedy Approach
- ๋นˆ ์ง‘ํ•ฉ์œผ๋กœ ์‹œ์ž‘ํ•˜์—ฌ ์ง‘ํ•ฉ ์ธ์Šคํ„ด์Šค์— ๋Œ€ํ•œ ๋‹ต์„ ๋‚˜ํƒ€๋‚ผ ๋•Œ๊นŒ์ง€ ์ง‘ํ•ฉ์— ์•„์ดํ…œ์„ ์ˆœ์„œ๋Œ€๋กœ ์ถ”๊ฐ€
  • ์„ ํƒ ์ ˆ์ฐจ ( = Selection Procedure)
    • ๊ทธ๋ฆฌ๋”” ๊ธฐ์ค€์— ๋”ฐ๋ผ ์ง‘ํ•ฉ์— ์ถ”๊ฐ€ํ•  ๋‹ค์Œ ์•„์ดํ…œ์„ ์„ ํƒ
  •  ํƒ€๋‹น์„ฑ ํ™•์ธ ( = Feasibility Check)
    • ์ธ์Šคํ„ด์Šค์— ๋‹ต์„ ์ œ๊ณตํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ง‘ํ•ฉ์„ ์™„๋ฃŒํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ํ™•์ธ
  • ๋‹ต ํ™•์ธ ( = Solution Check)
    • ์ƒˆ ์ง‘ํ•ฉ์ด ์ธ์Šคํ„ด์Šค์— ๋Œ€ํ•œ ๋‹ต์„ ๊ตฌ์„ฑํ•˜๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •
Minimum Spanning Trees

 

์ •์˜

  • Undirected Graph
  • Connected Graph
  • Acyclic Graph
  • Tree
  • Spanning Tree for undirected graph
    • G์˜ ๋ชจ๋“  ์ •์ ์„ ํฌํ•จํ•˜๊ณ  ํŠธ๋ฆฌ์ธ ์—ฐ๊ฒฐ๋œ ์„œ๋ธŒ๊ทธ๋ž˜ํ”„
  • Minimum Spanning Tree for undirected graph
    • ์ตœ์†Œ ๋ฌด๊ฒŒ๋ฅผ ๊ฐ€์ง„ G์˜ Spanning Tree

์™ผ์ชฝ์— ์‚ฌ์ง„์„ ๋ณด๋ฉด G1 ๊ทธ๋ž˜ํ”„์—์„œ ๋‚˜์˜ฌ ์ˆ˜ ์žˆ๋Š” 4๊ฐœ์˜ subgraph (= G2, G3, G4, G5)๊ฐ€ ์žˆ๋‹ค.

 

G2 : V3-V4-V5๊ฐ€ cycle์„ ํ˜•์„ฑํ•˜๋ฏ€๋กœ spanning tree X

G3, G4, G5 : spanning tree์˜ ์กฐ๊ฑด์„ ๋ชจ๋‘ ๋งŒ์กฑ -> G3์˜ weight = 15, G4, G5์˜ weight = 10

 

๋”ฐ๋ผ์„œ, G1์˜ Minimum Spanning Tree๋Š” G4์™€ G5๊ฐ€ ๋œ๋‹ค.

 

 

 

Prim's Algorithm
- MST๊ตฌํ˜„์— ์‚ฌ์šฉ๋˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ ์‹œ์ž‘ ์ •์ ์—์„œ ์ •์ ์„ ์ถ”๊ฐ€ํ•ด๊ฐ€๋ฉฐ ๋‹จ๊ณ„์ ์œผ๋กœ ํŠธ๋ฆฌ๋ฅผ ํ™•์žฅํ•˜๋Š” ๊ธฐ๋ฒ•
- ํƒ์ƒ‰ ์ •์ ์— ๋Œ€ํ•ด ์—ฐ๊ฒฐ๋œ ์ธ์ ‘ ์ •์ ๋“ค ์ค‘ ๋ฌด๊ฒŒ๊ฐ€ ๊ฐ€์žฅ ์ž‘์€ ๊ฐ„์„ ์œผ๋กœ ์—ฐ๊ฒฐ๋œ ์ •์ ์„ ์„ ํƒ

์œ„ ์‚ฌ์ง„์œผ๋กœ Prim's Algorithm์„ ์ดํ•ดํ•ด๋ณด์ž.

  1. V1์„ ์‹œ์ž‘ ์ •์ ์œผ๋กœ V1์— ์—ฐ๊ฒฐ๋œ ๊ฐ„์„  ์ค‘ ๋ฌด๊ฒŒ๊ฐ€ 1๋กœ ๊ฐ€์žฅ ์ž‘์€ ๊ฐ„์„ ์œผ๋กœ ์—ฐ๊ฒฐ๋œ V2๋ฅผ ์„ ํƒํ•œ๋‹ค.
  2. ์ด์ œ V1๊ณผ V2์— ์—ฐ๊ฒฐ๋œ ์ •์ ๋“ค ์ค‘ ๋ฌด๊ฒŒ๊ฐ€ ๊ฐ€์žฅ ์ž‘์€ ๊ฐ„์„ ์œผ๋กœ ์—ฐ๊ฒฐ๋œ ์ •์ ์ธ V3์„ ์„ ํƒํ•œ๋‹ค. ์ด๋•Œ, ๊ฐ„์„ ์„ ์„ ํƒํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ๋Š” 2๊ฐ€์ง€์ด๋ฏ€๋กœ ๋‘˜ ์ค‘ ํ•˜๋‚˜๋ฅผ ์„ ํƒํ•˜๋ฉด ๋œ๋‹ค.
  3. ํƒ์ƒ‰ ์ •์ ์— ์—ฐ๊ฒฐ๋œ ์ธ์ ‘ ์ •์ ๋“ค ์ค‘ ๋ฌด๊ฒŒ๊ฐ€ ๊ฐ€์žฅ ์ž‘์€ ๊ฐ„์„ ์œผ๋กœ ์—ฐ๊ฒฐ๋œ ์ •์ ์„ ์„ ํƒํ•˜๋Š” ๊ณผ์ •์„ ๋ฐ˜๋ณตํ•˜์—ฌ ๋ชจ๋“  ์ •์ ๋“ค์ด ์„ ํƒ๋˜๋„๋ก ํ•œ๋‹ค.

Prim's Algorithm์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฐฐ์—ด๋“ค์„ ์‚ฌ์šฉํ•œ๋‹ค.

  • W[i][j] : ๋ฌด๊ฒŒ ์ •๋ณด (symmetric)
  • nearest[i] : Vi์— ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด Y์— ์กด์žฌํ•˜๋Š” ์ •์ ์˜ ์ธ๋ฑ์Šค
  • distance[i] : Vi์™€ nearest[i] ์‚ฌ์ด์˜ ๋ฌด๊ฒŒ
public static set_of_edges prim(int n, const number W[][]){
    index i, vnear;
    index [] nearest = new index[2...n];
    number min;
    number[] distance = new number[2..n];
    edge e;
    set_of_edges F = โˆ…;
    
    for(i = 2; i <= n; i++){
    	nearest[i] = 1;
        distance[i] = W[1][i];
    }
    repeat(n-1) times {		// ์—ฃ์ง€๋ฅผ n-1๊ฐœ ๋„ฃ์œผ๋ฉด ๋ผ์„œ
    	min = โˆž;
        for(i =2; i <= n; i++){
            if(0 <= distance[i] < min){
                min = distance[i];
                vnear = i;
            }
        e = edge connecting vertices indexed by vnear and nearest[vnear];
        add e to F;
        distance[vnear] = -1;	// ๊ณ ๋ฅธ ์ •์  ํ‘œ์‹œ
        for(i = 2; i<= n; i++)
            if(W[i][vnear] < distance[i]){
                distance[i] = W[i][vnear];
                nearest[i] = vnear;
        }
        
	return F;
}

Time Complexity of Prim's Algorithm

Basic Operation : ๋‘ ๊ฐœ์˜ for๋ฌธ ๋‚ด๋ถ€์— ์กด์žฌํ•˜๋Š” if๋ฌธ

Input Size : n ( = ์ •์ ์˜ ๊ฐœ์ˆ˜)

T(n) = 2 * (n-1) * (n-1) โˆˆ ๐šฏ (n^2)

 

Kruskal's Algorithm
- ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ MST๊ตฌํ˜„์— ์‚ฌ์šฉ๋˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜
- ๊ทธ๋ž˜ํ”„์˜ ๊ฐ„์„ ๋“ค์„ ๊ฐ€์ค‘์น˜ ๊ธฐ์ค€์œผ๋กœ ์˜ค๋ฆ„์ฐจ์ˆœ ์ •๋ ฌํ•œ ๋’ค, ์ •๋ ฌ๋œ ๊ฐ„์„ ๋“ค ์ค‘ ์ˆœ์„œ๋Œ€๋กœ ์‚ฌ์ดํด์„ ํ˜•์„ฑํ•˜์ง€ ์•Š๋„๋ก ๊ฐ„์„ ๋“ค์„ ์„ ํƒ

์œ„ ์‚ฌ์ง„์œผ๋กœ Kruskal's Algorithm์„ ์ดํ•ดํ•ด๋ณด์ž.

  1. ๊ฐ„์„ ๋“ค์„ ๊ฐ€์ค‘์น˜ ๊ธฐ์ค€์œผ๋กœ ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌํ•œ๋‹ค
  2. (v1,v2)์˜ ๊ฐ€์ค‘์น˜๊ฐ€ ๊ฐ€์žฅ ์ž‘์œผ๋ฏ€๋กœ ํ•ด๋‹น ๊ฐ„์„ ์„ MST ์ง‘ํ•ฉ์— ๋„ฃ๋Š”๋‹ค.
  3. ๊ทธ ๋‹ค์Œ์œผ๋กœ ๊ฐ€์ค‘์น˜๊ฐ€ ์ ์€ (v3, v5) ๊ฐ„์„ ์„ MST ์ง‘ํ•ฉ์— ๋„ฃ๋Š”๋‹ค.
  4. ๋‹ค์Œ์€ (v1, v3)์™€ (v2, v3)์˜ ๊ฐ€์ค‘์น˜ ๊ฐ’์ด ๊ฐ™์œผ๋ฏ€๋กœ (v1, v3) ๊ฐ„์„ ์„ MST ์ง‘ํ•ฉ์— ๋„ฃ๊ณ , (v2, v3) ๊ฐ„์„ ์€ ๊ณ ๋ ค๋งŒ ํ•˜๊ณ  ๋ฒ„๋ฆฐ๋‹ค.
  5. MST ์ง‘ํ•ฉ์— (n-1)๊ฐœ์˜ ๊ฐ„์„ ๋“ค์ด ์กด์žฌํ•  ๋•Œ๊นŒ์ง€ ๊ฐ„์„  ์„ ํƒ์„ ๋ฐ˜๋ณตํ•œ๋‹ค.

Kruskal's Algorithm์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ•จ์ˆ˜๋“ค์„ ์‚ฌ์šฉํ•œ๋‹ค.

  • Initial(n) : n๊ฐœ์˜ disjoing subset์„ ๋งŒ๋“ค์–ด์ฃผ๋Š” ํ•จ์ˆ˜
  • p = find(i) :  ์ธ๋ฑ์Šค๊ฐ€ i์ธ ์ •์ ์ด ์–ด๋А disjoint set์— ํฌํ•จ๋˜์–ด ์žˆ๋Š”์ง€ ์•Œ๋ ค์ฃผ๋Š” ํ•จ์ˆ˜
  • merge(p, q) : ๋‘ subset์„ ๋ณ‘ํ•ฉํ•˜๋Š” ํ•จ์ˆ˜ 
  • equal(p, q) : ๋‘ subset์ด ๊ฐ™์€ ์ง‘ํ•ฉ์— ์†ํ•˜๋Š”์ง€ ์•Œ๋ ค์ฃผ๋Š” ํ•จ์ˆ˜, true ๋˜๋Š” false ๋ฐ˜ํ™˜
public static set_of_edges kruskal(int n, int m, set_of_edges E){
    index i, j;
    set_pointer p, q;
    edge e;
    set_of_edges F = โˆ…;
    
    Sort the m edges in E by weight in nondecreasing order;
    
    initial(n);
    while(|F| < n-1){
        e = edge with the least weight not yet considered;
        i, j = indicesof vertices connected by e;
        
        p = find(i);
        q = find(j);
        if(!Equal(p,q)){
            merge(p, q);
            add e to F;
        }
    }
    return F;
}

Time Complexity of Kruskal's Algorithm

Basic Operation : ๋น„๊ต ์—ฐ์‚ฐ์ž

Input Size : n ( = ์ •์ ์˜ ๊ฐœ์ˆ˜), m ( = ๊ฐ„์„ ์˜ ๊ฐœ์ˆ˜)

  • Time to sort the edges
    • W(m) โˆˆ ๐šฏ (m lg m) using MergeSort
  • Time in the while loop
    • W(m) โˆˆ ๐šฏ(m lg m) using DisjoingSet implementation
  • Time to initialize n disjoint sets
    • T(n) โˆˆ ๐šฏ(n)

 ์œ„ 3๊ฐœ์˜ Time์˜ ํ•ฉ

โžก๏ธ W(m, n) โˆˆ ๐šฏ(m lg m), n-1 โ‰ค m โ‰ค n(n-1) / 2

โžก๏ธ worst case : W(m, n) โˆˆ ๐šฏ(m lg m) = ๐šฏ(n^2 * lg n^2) = ๐šฏ(n^2 * lg n)

 

Huffman Code
- ๋ฐ์ดํ„ฐ ์••์ถ•์„ ์œ„ํ•œ ํšจ์œจ์ ์ธ ์ธ์ฝ”๋”ฉ ๋ฐฉ๋ฒ•
- ๊ฐ€๋ณ€ ๊ธธ์ด ์ด์ง„ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ…์ŠคํŠธ ํŒŒ์ผ์„ ๋‚˜ํƒ€๋ƒ„

ํ…์ŠคํŠธ ํŒŒ์ผ์„ ์ธ์ฝ”๋”ฉํ•˜๊ธฐ ์œ„ํ•œ ๋น„ํŠธ ์ˆ˜ = minimize โˆ‘frequency(v) * depth(v)

for(i = 1; i < n; i++){
    remove(PQ, p);
    remove(PQ, q);
    r = new nodetype();
    r.left = p;
    r.right = q;
    r.frequency = p.frequency + q.frequency;
    insert(PQ, r);
}
remove(PQ, r);
return r;

// nodetype info
Public class nodetype{
    char symbol;
    int frequency;
    
    nodetype left;
    nodetype right;
}

remove() ํ•จ์ˆ˜ time complexity -> log n

insert() ํ•จ์ˆ˜ time complexity -> log n

 

Time complexity of Huffman Code

n * (3 * log n) ๐šฏ n log n

728x90

'Study > Algorithm' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

Chap 9. Introduction to the Theory of NP  (0) 2023.06.11
Chap 7. Introduction to Computational Complexity: The Sorting Problem  (0) 2023.06.08
Chap 6. Branch and Bound  (0) 2023.06.06
Chap 5. Backtracking  (0) 2023.06.04
Chap 3. Dynamic Programming  (0) 2023.04.20