500원: 0개
250원: 1개
100원: 1개
50원: 0개
10원: 1개
120원: 1개
100원: 0개
50원: 0개
10원: 4개
120원: 0개
100원: 1개
50원: 1개
10원: 1개
1) 선택과정: 지정된 기준에 따라 집합에 추가할 최적의 원소 선택.
2) 적절성 검사: 선택된 원소가 추가된 새로운 집합의 적절성 판단
3) 해답점검: 새로운 집합이 문제의 해답인지 여부 판단.
$G = (V, E)$
$Y = \{ v_1 \}$
$F = \emptyset$
while (사례 미해결):
$(V-Y)$에 속한 마디 중에서 $Y$와 가장 가까운(최소거리) 마디 선택
해당 마디를 $Y$에 추가
해당 마디 선택에 사용된 이음선을 $F$에 추가
if ($Y == V$):
사례해결
전제:
$$G = (V, E) \quad\text{이고}\quad F \subseteq E$$
from math import inf
from collections import defaultdict
def prim(W):
V = len(W) # 마디: 그래프 행의 인덱스를 마디 이름으로 사용
F = defaultdict(list) # 신장트리에 포함될 이음선들의 집합.
# 키: 마디,
# 키값: 추가되는 이음선에 사용된 다른 마디들의 리스트
nearest = [0] * V # i번 인덱스 값: 신장트리에 속한 마디 중 가장 가까운 마디
distance = [W[0][i] for i in range(V)] # i번 인덱스 값: nearest[i]와 i를 잇는
# 이음선의 가중치. -1이면 이미 신장트리에 포함된 것으로 간주
distance[0] = -1 # V0 는 이미 포함되어 있다고 가정
for _ in range(V-1): # 신장트리에 속할 이음선을 모든 마디가 선택될 때가지 하나씩 추가
# distance 정보를 이용하여 아직 신장트리에 속하지 않으면서 가장 가까운 마디 선택
min = inf
for i in range(1, V):
if (0 < distance[i] < min):
min = distance[i]
vnear = i
# 선택된 마디와 가장 가까운 마디 사이의 이음선을 신장트리에 추가
F[nearest[vnear]].append(vnear)
distance[vnear] = -1 # 선택된 마디 표시
# 모든 마디를 대상으로 distance와 nearest 업데이트 (F가 수정되었기 때문)
for i in range(1, V):
if W[i][vnear] < distance[i]:
distance[i] = W[i][vnear]
nearest[i] = vnear
return F # 신장트리 반환
W = [[0, 1, 3, inf, inf],
[1, 0, 3, 6, inf],
[3, 3, 0, 4, 2 ],
[inf, 6, 4, 0, 5 ],
[inf, inf, 2, 5, 0 ]]
prim(W)
defaultdict(list, {0: [1, 2], 2: [4, 3]})
V = len(W) # 마디: 그래프 행의 인덱스를 마디 이름으로 사용
F = defaultdict(list) # 신장트리에 포함될 이음선들의 집합.
# 키: 마디,
# 키값: 추가되는 이음선에 사용된 다른 마디들의 리스트
nearest = [0] * V # i번 인덱스 값: 신장트리에 속한 마디 중 가장 가까운 마디
distance = [W[0][i] for i in range(V)] # i번 인덱스 값: nearest[i]와 i를 잇는 이음선의 가중치
# -1 이면 이미 신장트리에 포함된 것으로 간주
distance[0] = -1 # V0 는 이미 포함되어 있다고 가정
for _ in range(V-1): # 신장트리에 속할 이음선을 모든 마디가 선택될 때가지 하나씩 추가
# distance 정보를 이용하여 아직 신장트리에 속하지 않으면서 가장 가까운 마디 선택
min = inf
for i in range(1, V):
if (0 < distance[i] < min):
min = distance[i]
vnear = i
# 선택된 마디와 가장 가까운 마디 사이의 이음선을 신장트리에 추가
F[nearest[vnear]].append(vnear)
distance[vnear] = -1 # 선택된 마디 표시
# 모든 마디를 대상으로 distance와 nearest 업데이트 (F가 수정되었기 때문)
for i in range(1, V):
if W[i][vnear] < distance[i]:
distance[i] = W[i][vnear]
nearest[i] = vnear
아래 비방향그래프의 최소신장트리를 찾는 과정을 단계별로 묘사하라.
신장트리에 추가되는 이음선의 순서는 다음과 같음:
W = [[ 0, 32, inf, 17, inf, inf, inf, inf, inf, inf],
[ 32, 0, inf, inf, 45, inf, inf, inf, inf, inf],
[inf, inf, 0, 18, inf, inf, 5, inf, inf, inf],
[ 17, inf, 18, 0, 10, inf, inf, 3, inf, inf],
[inf, 45, inf, 10, 0, 28, inf, inf, 25, inf],
[inf, inf, inf, inf, 28, 0, inf, inf, inf, 6],
[inf, inf, 5, inf, inf, inf, 0, 59, inf, inf],
[inf, inf, inf, 3, inf, inf, 59, 0, 4, inf],
[inf, inf, inf, inf, 25, inf, inf, 4, 0, 12],
[inf, inf, inf, inf, inf, 6, inf, inf, 12, 0]]
prim(W)
defaultdict(list, {0: [3, 1], 3: [7, 4, 2], 7: [8], 8: [9], 9: [5], 2: [6]})