我最近在学习tsp问题。
我尝试使用python networkx lib folling wiki可视化christofides算法
但我没有得到很好的解决(比其他任何方法都糟糕)
这是我的代码(你可以运行jupyter lab/notebook中的每个块来查看图表)
import numpy as np
a = np.array([
[0, 7, 4, 5, 8, 6, 12, 13, 11, 18],
[7, 0, 3, 10, 9, 14, 5, 14, 17, 17],
[4, 3, 0, 5, 9, 10, 21, 8, 27, 12],
[5, 10, 5, 0, 14, 9, 10, 9, 23, 16],
[8, 9, 9, 14, 0, 7, 8, 7, 20, 19],
[6, 14, 10, 9, 7, 0, 13, 5, 25, 13],
[12, 5, 21, 10, 8, 13, 0, 23, 21, 18],
[13, 14, 8, 9, 7, 5, 23, 0, 18, 12],
[11, 17, 27, 23, 20, 25, 21, 18, 0, 16],
[18, 17, 12, 16, 19, 13, 18, 12, 16, 0]] )
# complete graph
import networkx as nx
import matplotlib.pyplot as plt
G = nx.Graph(a)
def draw_with_labels(G, pos=nx.spring_layout(G)):
nx.draw(G,pos)
nx.draw(G, pos, with_labels=True)
labels = nx.get_edge_attributes(G,'weight')
nx.draw_networkx_edge_labels(G,pos,edge_labels=labels)
plt.show()
draw_with_labels(G)
# minimum spanning tree
T = nx.minimum_spanning_tree(G)
draw_with_labels(T, nx.spring_layout(T))
# odd nodes in spanning tree
O = nx.Graph()
for node, degree in nx.degree(T):
if(degree % 2 == 1):
O.add_node(node)
draw_with_labels(O, nx.spring_layout(O))
# subgraph from the tree
node_with_weights = list()
for nodes, weight in dict(nx.get_edge_attributes(G, 'weight')).items():
if nodes[0] in O.nodes() and nodes[1] in O.nodes():
node_with_weights.append((nodes[0], nodes[1], weight))
O.add_weighted_edges_from(node_with_weights, weight='weight')
draw_with_labels(O, nx.spring_layout(O))
# minimum-weight perfect matching
import networkx.algorithms.approximation as naa
edges = naa.matching.min_maximal_matching(O)
matching = nx.Graph()
for nodes in edges:
matching.add_node(nodes[0])
matching.add_node(nodes[1])
matching.add_edge(nodes[0], nodes[1])
edges_with_weight3 = list()
for edge, weight in nx.get_edge_attributes(O, 'weight').items():
if edge in matching.edges():
edges_with_weight3.append((edge[0], edge[1], weight))
matching.add_weighted_edges_from(edges_with_weight3, weight='weight')
draw_with_labels(matching, nx.random_layout(matching))
# Eulerian multigraph
def eulerian_multigraph(tree, matching):
E = nx.MultiGraph(tree)
for node in tree.nodes():
E.add_node(node)
for edge, weight in dict(nx.get_edge_attributes(matching, 'weight')).items():
E.add_edge(edge[0], edge[1])
return E
E = eulerian_multigraph(T, matching)
nx.draw(E, pos=nx.spring_layout(E), with_labels=True)
但欧拉之旅
[(0, 8), (8, 9), (9, 2), (2, 3), (3, 0), (0, 5), (5, 4), (4, 5), (5, 7), (7, 6), (6, 1), (1, 2), (2, 0)]
删除重复的顶点之后
0 -> 8 -> 9 -> 2 -> 3 -> 5 -> 4 -> 7-> 6 -> 1 -> 0
但是,解决方案应该是(使用goole或tools中的christofides算法):
0 -> 3 -> 2 -> 1 -> 6 -> 4 -> 5 -> 7 -> 9 -> 8 -> 0
我的代码有什么问题吗?
暂无答案!
目前还没有任何答案,快来回答吧!