在python中查找networkx图是不是可追溯
Posted
技术标签:
【中文标题】在python中查找networkx图是不是可追溯【英文标题】:Finding if a networkx graph is traceable in python在python中查找networkx图是否可追溯 【发布时间】:2018-06-22 06:32:38 【问题描述】:我试图证明下图是可追溯的:
n = 50
nodes = range(1, n + 1)
graph = nx.Graph()
graph.add_nodes_from(nodes)
for i in nodes:
for j in nodes:
if i != j and is_perfect_square(i + j):
graph.add_edge(i, j)
我试图在互联网上找到一种算法,但似乎没有。我试过networkx.algorithms.tournament.hamiltonian_path,但它只适用于有向图。所以我不得不选择以下非常低效的解决方案:
def is_traceable(G):
"""
:type G: nx.Graph
"""
needed = len(G.nodes)
for i in G.nodes:
for j in G.nodes:
for path in nx.all_simple_paths(G, i, j):
if len(path) == needed:
return True
return False
这适用于n <= 45
,但从n = 46
开始,需要很长时间才能返回。为什么会这样,我该如何提高效率,以使n
数百个的时间合理?
【问题讨论】:
根据文档,networkx.algorithms.tournament
中的算法仅适用于锦标赛图表,因此它们无论如何都不适用于您的图表。
【参考方案1】:
是的,图表是可追溯的。路径是:
[1, 3, 6, 19, 30, 34, 47, 17, 8, 28, 36, 45, 4, 32, 49, 15, 21, 43, 38, 26, 10, 39, 42, 22, 27, 9, 16, 48, 33, 31, 50, 14, 11, 25, 24, 40, 41, 23, 13, 12, 37, 44, 5, 20, 29, 35, 46, 18, 7, 2]
通过一个小的优化,您的代码在我的机器上大约在 3 分钟内完成。正如您在下面看到的,我只评估每对 i
,j
一次,并且我跳过 i == j
的对。如果您想进一步加快速度(无需任何算法改进),您可以使用joblib
并行化嵌套循环。
import numpy as np
import matplotlib.pyplot as plt
import networkx as nx
def is_traceable(G):
"""
:type G: nx.Graph
"""
nodes = G.nodes()
needed = len(nodes)
for ii, v in enumerate(nodes):
for w in nodes[(ii+1):]:
for path in nx.all_simple_paths(G, v, w):
if len(path) == needed:
return True, path
return False
def is_perfect_square(num):
if np.isclose(num, int(np.sqrt(num))**2):
return True
else:
return False
def get_graph(n):
nodes = range(1, n + 1)
graph = nx.Graph()
graph.add_nodes_from(nodes)
for i in nodes:
for j in nodes:
if i != j and is_perfect_square(i + j):
graph.add_edge(i, j)
return graph
if __name__ == "__main__":
n = 50
g = get_graph(n)
print(is_traceable(g))
【讨论】:
以上是关于在python中查找networkx图是不是可追溯的主要内容,如果未能解决你的问题,请参考以下文章