from math import inf
from itertools import permutations
city_distances = {
"v1":
{"v2": 2,
"v3": 9},
"v2":
{"v1": 1,
"v3": 6,
"v4": 4},
"v3":
{"v2": 7,
"v4": 8},
"v4":
{"v1": 6,
"v2": 3}
}
cities = list(city_distances.keys())
print(cities)
['v1', 'v2', 'v3', 'v4']
city_permutations
가 가리키는 값은 아래 6개의 항목으로 이루어진 이터러블 자료형city_permutations = permutations(cities[1:])
('v2', 'v3', 'v4'),
('v2', 'v4', 'v3'),
('v3', 'v2', 'v4'),
('v3', 'v4', 'v2'),
('v4', 'v2', 'v3'),
('v4', 'v3', 'v2')
tsp_paths = [(cities[0],) + c + (cities[0],) for c in city_permutations]
tsp_paths
는 $v_1$에서 시작하는 모든 일주경로의 목록을 담은 리스트.[('v1', 'v2', 'v3', 'v4', 'v1'),
('v1', 'v2', 'v4', 'v3', 'v1'),
('v1', 'v3', 'v2', 'v4', 'v1'),
('v1', 'v3', 'v4', 'v2', 'v1'),
('v1', 'v4', 'v2', 'v3', 'v1'),
('v1', 'v4', 'v3', 'v2', 'v1')]
best_path
: 최적일주경로 저장None
. best_distance
: 최적일주경로의 길이 저장inf
). inf
: 어떤 수보다 큰 값을 나타내는 기호.best_path = None
min_distance = inf
inf
)로 처리함.get
메서드가 None
을 반환하는 성질 활용last
와 next
를 차례대로 업데이트하면서 일주경로의 길이 계산last
: 경로상에서 외판원의 현재 위치next
: 경로상에서 외판원이 방문할 다음 위치for path in tsp_paths:
distance = 0
last = path[0]
for next in path[1:]:
last2next = city_distances[last].get(next)
if last2next: # last에서 next로의 경로가 존재하는 경우
distance += last2next
else: # last에서 next로의 경로가 존재하지 않는 경우 None 반환됨.
distance = inf # 무한대로 처리하며, 결국 최솟값 경쟁에서 제외됨.
last = next
if distance < min_distance: # 최단경로를 업데이트 해야 하는 경우
min_distance = distance
best_path = path
print(f"최적일주경로는 {best_path}이며 길이는 {min_distance}이다.")
최적일주경로는 ('v1', 'v3', 'v4', 'v2', 'v1')이며 길이는 21이다.
def tsp_bruteforce(city_distances:dict):
# v1에서 시작하는 모든 일주경로 확인
cities = list(city_distances.keys())
city_permutations = permutations(cities[1:])
# 최적경로와 최단길이 기억
best_path = None
min_distance = inf
# 각 일주경로의 길이확인. 동시에 최적경로와 최단길이 업데이트
for path in tsp_paths:
distance = 0
last = path[0]
for next in path[1:]:
last2next = city_distances[last].get(next)
if last2next: # last에서 next로의 경로가 존재하는 경우
distance += last2next
else: # last에서 next로의 경로가 존재하지 않는 경우 None 반환됨.
distance = inf # 무한대로 처리하며, 결국 최솟값 경쟁에서 제외됨.
last = next
if distance < min_distance: # 최단경로를 업데이트 해야 하는 경우
min_distance = distance
best_path = path
# 최적경로와 최단길이 반환
return best_path, min_distance
best_path, min_distance = tsp_bruteforce(city_distances)
print(f"최적일주경로는 {best_path}이며 길이는 {min_distance}이다.")
최적일주경로는 ('v1', 'v3', 'v4', 'v2', 'v1')이며 길이는 21이다.