출시·고도화 중
최단 경로와 최소 신장 트리 안내서 · 6/6
최단 경로와 신장 트리는 가장 널리 쓰이는 그래프 알고리즘에 속합니다. 이 장에서는 실제로 어디에서 돌아가는지, 어떤 라이브러리를 쓰면 되는지, 틀린 답을 내는 흔한 실수가 무엇인지 살펴봅니다.
-log(환율)로 두면 벨만-포드가 찾은 음수 사이클이 곧 환율 차익 거래 고리입니다.Python에서는 NetworkX가 프로토타입이나 간선 수십만 개 정도까지의 그래프에 편리합니다.
import networkx as nx
G = nx.Graph()
G.add_weighted_edges_from([("A", "B", 1), ("B", "C", 2), ("A", "C", 3), ("C", "D", 4), ("B", "D", 5)])
print(nx.dijkstra_path(G, "A", "D")) # ['A', 'B', 'D']
print(nx.dijkstra_path_length(G, "A", "D")) # 6
mst = nx.minimum_spanning_tree(G, algorithm="kruskal")
print(sorted(mst.edges(data="weight"))) # [('A', 'B', 1), ('B', 'C', 2), ('C', 'D', 4)]큰 수치 그래프라면 SciPy의 scipy.sparse.csgraph가 희소 행렬 위에서 컴파일된 코드로 동작합니다.
import numpy as np
from scipy.sparse import csr_matrix
from scipy.sparse.csgraph import dijkstra, minimum_spanning_tree
m = csr_matrix(np.array([
[0, 1, 3, 0],
[1, 0, 2, 5],
[3, 2, 0, 4],
[0, 5, 4, 0],
]))
dist = dijkstra(m, directed=False, indices=0)
print(dist) # [0. 1. 3. 6.]
print(minimum_spanning_tree(m).sum()) # 7.0C++에서는 Boost Graph Library가 dijkstra_shortest_paths, bellman_ford_shortest_paths, kruskal_minimum_spanning_tree, prim_minimum_spanning_tree를 제공합니다. 데이터베이스 쪽에서는 Neo4j의 Graph Data Science 라이브러리와 PostgreSQL의 pgRouting 확장이 데이터 가까이에서 이 알고리즘들을 돌립니다.
if d > dist[u] 빠뜨리기. 결과는 맞지만 밀집 그래프에서 크게 느려질 수 있습니다.INF + w가 값이 넘쳐 음수가 됩니다. 거리가 아직 무한대인 정점에서는 완화하지 말고 64비트 정수를 씁니다.heappush가 TypeError를 냅니다. 카운터를 동점 처리용으로 끼워 넣습니다.import heapq
from itertools import count
tie = count()
heap = []
heapq.heappush(heap, (5, next(tie), {"name": "warehouse"}))
heapq.heappush(heap, (5, next(tie), {"name": "store"})) # TypeError 없음: 카운터가 순서를 정함
print(heapq.heappop(heap)[2]) # {'name': 'warehouse'}V - 1개보다 적은 포레스트를 돌려줍니다. 트리로 다루기 전에 간선 수를 확인합니다.
댓글 0개
로그인 · 로그인하면 댓글을 남길 수 있습니다.
첫 댓글을 남겨 보세요.