지난 학기 학교 알고리즘 수업을 수강하며, 정리 해 놓았던 마크다운 문서입니다. 문제시 삭제하겠습니다
최적의 해를 찾는 문제
비용의 측면: 비용 최소화 하기
이득의 측면: 이득 최대화 하기
가장 best한 결과 찾아내자, 어떤 일련의 선택들 optimal 되도록 하자
선택할때 제일 이익이 되도록 선택
짧은 시간내에 best 찾기, 번복 불가
input: connected, undirected graph 주어짐
spanning tree = G'=(V', E')라 하면
V`=V and E'->E and connected, acyclic해야함
minimum weight 가지는 spanning tree찾기 -> b와 c만 만족 (최소 weight 6)
세개의 disjoint 상태로 나눔
I 정점 tree에 추가
I에 인접한 F, E, H 정점 확인
F는 기존에 7로 갈수 있었는데 I 통하면 5 에 갈 수있음, 5로 업데이트 (decrease key), H로 가는 경우는 4인데, 기존에 3이 더작음->pass
Fringe 정점 존재하지 않을 때 까지 이런 과정 수행
PrimMST(G,n) // OUTLINE (m=n-1)
Initialize all vertices as unseen. // O(N) time
Select an arbitrary vertex s to start the tree; reclassify it as tree.
Reclassify all vertices adjacent to s as fringe.
--------------------//초기화 단계 (T1 생성)
While there are fringe vertices; // O(N) 번 수행
Select an edge of minimum weight between
a tree vertex t and a fringe vertex v;
Reclassify v as tree; add edge tv to the tree;
Reclassify all unseen vertices adjacent to v as fringe. // deg(v)
unsorted sequence | sorted sequence | heap | |
---|---|---|---|
insert | O(1) | O(n) | O(logn) |
removeMin | O(n) | O(1) | O(logn) |
decreaseKey | O(1) | O(n) | O(logn) |
m=o(n) (sparse graph) 이면 heap 사용이 유리, m=O(n^2) (dense graph) 이면 unsorted sequence사용이 유리
minimum spanning tree 찾는 또 다른 알고리즘
sorting, min-heap이용가능 -> 두방법 모두 O(mlogm) time
KruskalMST(G,n)
R = E // R is remaining edges
F = {} // F is forest edges
while (R is not empty)
Remove the lightest (shortest) edge, vw, from R;
if (vw does not make a cycle in F) // 싸이클 발생 하지 않을때만 minimum spanning tree에 추가 (union-find ADT 사용 = disjoint set)
Add vw to F;
return F ;
// 먼저 모든 정점이 minimum spanning tree에 포함 되있다고 보는 것이고 싸이클이 발생하지 않으면 edge 를 minumum spanning tree에 추가
find(u): 어떤 정점 u가 주어졌을때 u를 포함하는 set이 무엇인지 알 수 있게해줌(set id(leader) 반환)
union(u,v): u, v 가 다른 집합이면 하나의 집합으로 merge해줌
그다음 weight 작은 187
양끝 정점 (JFK, BOS) 서로 다른 집합-> union
그다음 작은 weight 337
양끝 정점 (SFO, LAX) 서로 다른 집합-> union
그다음 weight 작은 621
양끝 정점 (ORD, BWI) 서로 다른 집합 -> union
그 다음 weight 작은 740
양끝 정점 (ORD, JFK) 서로 같은 집합 -> union X
그 다음 802
양끝 정점 (ORD, DFW) 서로 다른 집합 -> union
그 다음 849, 867
둘다 같은 집합 -> union X
(kruskal 알고리즘은 prim 알고리즘과 동일한 수행시간에 수행 가능함)
kruskal : O(mlogm)
prim : O(mlogn) (힙 이용)
-> m은 아무리 많아야 o(n^2), 로그의 성질에 의해
kruskal은 O(mlogn^2)이라고 볼수있고, O(2mlogn)으로 표현가능 따라서 O(mlogn)