christofides算法与networkx

r3i60tvu  于 2021-07-13  发布在  Java
关注(0)|答案(0)|浏览(173)

我最近在学习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
我的代码有什么问题吗?

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题