์๋ฃ๊ตฌ์กฐ/๐์๊ณ ๋ฆฌ์ฆ - 27
์ค๋ ๋ค์ ๊ฐ์ ๋ชฉ๋ก
- ํ๋ฆผ - 4
- ๊ฐ์ ํ๋ฆผ - 1
ํ๋ฆผ ์๊ฐ๋ณต์ก๋
while connected_e:
next_e = heappop(connected_e)
if next_e[2] not in connected_n:
tree.append(next_e)
connected_n.add(next_e[2])
for edge in edgesOf[next_e[2]]: # E, ๋ค ์ถ๊ฐ
if edge[2] not in connected_n:
heappush(connected_e, edge) # log E
๋ชจ๋ ๊ฐ์ ์ถ๊ฐ -> $E$
ํ push -> $log E$
์๊ฐ๋ณต์ก๋ : $O(E log E)$
ํ๋ฆผ ์๊ณ ๋ฆฌ์ฆ ๊ฐ์
๋๋ถ๋ถ $O(E log V)$์ ์๊ฐ๋ณต์ก๋๋ฅผ ๊ฐ์ง๋ ํ๋ฆผ ์๊ณ ๋ฆฌ์ฆ
๊ฐ์ ์ด ์๋ ๋ ธ๋๋ฅผ ์ค์ฌ์ผ๋ก ์ฐ์ ์์ ํ๋ฅผ ์ ์ฉ
- ํ์ ๋ชจ๋ ๋ ธ๋๋ฅผ ๋ฃ๊ณ , key๋ ๋ฌดํ๋๋ก ์ด๊ธฐํ (key = ๊ฐ์ค์น)
- ํ์ ์๋ ์์ ๋
ธ๋์ key๋ฅผ 0์ผ๋ก ์ด๊ธฐํ(heapdict๋ฅผ ์ด์ฉ, decrease-key)
์ด๋ ์ด์ ๋ ธ๋๋ฅผ ์ ์ฅํ ๋ ์ด์ ๋ ธ๋๋ฅผ ์์๋ ธ๋๋ก ํ๋ค. - ํ์์ ๋ ธ๋๋ฅผ ๋ฝ๊ณ , ์ ํํ๋ค.
- ์ ํํ ๋ ธ๋์ ์ฐ๊ฒฐ๋ ๊ฐ์ ๋ค์ ๋ํด 5๋ฒ์ ์งํํ๋ค.
- ๊ฐ ๊ฐ์ ์ ์ฐ๊ฒฐ๋ ๋
ธ๋๋ฅผ ํ์ธํ๊ณ ,
ํด๋น ๊ฐ์ ์ ๊ฐ์ค์น๊ฐ ํ์ ์๋ ํด๋น ๋ ธ๋์ ๊ฐ์ค์น๋ณด๋ค ์์ผ๋ฉด, ํ์ ๊ฐ์ค์น๋ฅผ ์ ๋ฐ์ดํธ ํ๋ค. - ํ์ ๋ ธ๋๊ฐ ์์ ๋๊น์ง 3๋ฒ~5๋ฒ์ ๋ฐ๋ณตํ๋ค.
from heapdict import heapdict
def advprim(edges, start_node):
tree = []
# ๊ฐ ๋
ธ๋๋ณ๋ก ์ฐ๊ฒฐ๋ ๊ฐ์ ์ ์ ๋ฆฌ
# ๊ทธ๋ํ ๊ตฌ์กฐ๋ฅผ ๋ง๋ค๋ ์ด๋ฐ ๊ตฌ์กฐ๋ก ๋ง๋๋๊ฒ ๊ตญ๋ฃฐ์ด์ง๋ง ์ด์ ์ฝ๋ ์ฌ์ฌ์ฉํ๋๋ผ..
edgesOf = defaultdict(list)
for weight, n1, n2 in edges:
edgesOf[n1].append((weight, n1, n2))
edgesOf[n2].append((weight, n2, n1))
# ๋
ธ๋๊ฐ ๋ค์ด์๋ ํ ์ด๊ธฐํ
n_heap = heapdict()
for node in edgesOf:
n_heap[node] = float('inf')
n_heap[start_node] = 0
before = {node : None for node in edgesOf}
before[start_node] = start_node
while n_heap:
cur_n, cur_k = n_heap.popitem()
prev_n = before[cur_n]
tree.append([prev_n, cur_n, cur_k])
for w, c, n in edgesOf[cur_n]:
if n in n_heap and w < n_heap[n]:
n_heap[n] = w
before[n] = cur_n
return tree
์คํ ๊ฒฐ๊ณผ๋ ์ด์ ์ ๊ธฐ๋ณธ ํ๋ฆผ ์๊ณ ๋ฆฌ์ฆ๊ณผ๋ ์กฐ๊ธ ๋ค๋ฅด๊ฒ ๋์๋ค.
๊ฒ์์์ผ๋ก ์น ํ 7์ ๊ฐ์ค์น๋ฅผ ๊ฐ์ง ๊ฐ์ ๋์ ,
ํ๋์์ผ๋ก ์น ํ 7์ ๊ฐ์ค์น๋ฅผ ๊ฐ์ง ๊ฐ์ ์ด ์ถ๊ฐ๋์๋ค.
๊ทธ๋ฌ๋ ๊ฐ์ค์น๊ฐ ๊ฐ์์ mst์ ๊ฐ์ค์น ํฉ์ ๊ฐ๋ค.
heapdict?
ํ ๊ตฌ์กฐ์์ ์ด๋ฏธ ์ฝ์
๋์ด์๋ ๋
ธ๋์ key๊ฐ ๋ณ๊ฒฝ๋์์ ๋, ํ ๊ตฌ์กฐ๊ฐ ๋ณ๊ฒฝ๋์ด์ผ ํ ๋๋ฅผ ์ํด ์ฌ์ฉํ๋ ๋ชจ๋
์ฐ์ ์์๊ฐ ๋ณ๊ฒฝ๋์ด๋ ํ ๊ตฌ์กฐ๋ฅผ ์ ์งํ๋ค.(decrease-key)
hd = heapdict()
hd[obj1] = priority1
hd[obj2] = priority2
print(hd.peakitem())
(obj, priority) = hd.popitem()
์์ ์์์ฒ๋ผ ์ฌ์ฉํ ์ ์๋ค.
๋ง์ง๋ง
ํ๋ฆผ ์๊ณ ๋ฆฌ์ฆ์ ์ฒ์๊ตฌํํด๋ด์ ๊ฐ์์์ ์ฃผ์ด์ง ์ฝ๋๋ฅผ ์ฐธ๊ณ ํ๋ค.
๊ทธ๋ฆฌ๊ณ ์ฃผ์์ผ๋ก ์์ฑํ๋ฏ์ด ๊ทธ๋ํ ๊ตฌ์กฐ๋ฅผ ๊ตฌํํ ๋,(ํจ์์ ๋๊ฒจ์ฃผ๊ธฐ ์ ์)
๊ตฌ์กฐ๋ฅผ ์ ๋ง๋ค์ด์ ํจ์ ๋ด์์ ๋ค์ ๊ณ ์น์ง ์๋๋ก ํ๋๊ฒ ์ข๋ค๊ณ ์๊ฐํ๋ค.
๋๊ธ๋จ๊ธฐ๊ธฐ