python - 列出所有 TSP 路由组合(5 个顶点)
问题描述
我想列出所有 TSP 路由组合。
所有边缘如下:
edges = [('A', 'B'), ('A', 'C'), ('A', 'D'), ('A', 'E'), ('B', 'C'), ('B', 'D'), ('B', 'E'), ('C', 'D'), ('C', 'E'), ('D', 'E')]
注意:('A', 'B')
与 相同('B', 'A')
,其他边也一样。我想列出您从 A 开始并相互访问并在 A 结束的所有路线组合。
这是我到目前为止得到的:
edges = [('A', 'B'), ('A', 'C'), ('A', 'D'), ('A', 'E'), ('B', 'C'), ('B', 'D'), ('B', 'E'), ('C', 'D'), ('C', 'E'), ('D', 'E')]
x = list(itertools.permutations(['A','B','C','D','E', 'A'], 6))
b = 1
for i in x:
if i[-1] == 'A' and i[0] == 'A':
print(i, b)
b += 1
但是,我不想要重复的路线。我该如何整理这些?例如。A->B->C->A 与 A->C->B->A 相同,不应计算/列出两次。
解决方案
您可以将递归与生成器一起使用:
edges = [('A', 'B'), ('A', 'C'), ('A', 'D'), ('A', 'E'), ('B', 'C'), ('B', 'D'), ('B', 'E'), ('C', 'D'), ('C', 'E'), ('D', 'E')]
def all_paths(graph, start, end=None, _flag = None, _pool = [], _seen= []):
if start == end:
yield _pool
else:
for a, b in graph:
if a == start and a not in _seen:
yield from all_paths(graph, b, end=_flag, _flag=_flag, _pool = _pool+[b], _seen =_seen+[a])
results = list(all_paths(edges+[(b, a) for a, b in edges], 'A', _flag = 'A'))
filtered = [a for i, a in enumerate(results) if not any(len(c) == len(a) and all(h in c for h in a) for c in results[:i])]
输出:
[['B', 'C', 'D', 'E', 'A'], ['B', 'C', 'D', 'A'], ['B', 'C', 'E', 'A'], ['B', 'C', 'A'], ['B', 'D', 'E', 'A'], ['B', 'D', 'A'], ['B', 'E', 'A'], ['B', 'A'], ['C', 'D', 'E', 'A'], ['C', 'D', 'A'], ['C', 'E', 'A'], ['C', 'A'], ['D', 'E', 'A'], ['D', 'A'], ['E', 'A']]
推荐阅读
- excel - 按钮上的范围背景颜色更改
- python - 如何避免正则表达式匹配“Revert”“Revert”
- kubernetes - kubelet如何计算nodefs,imagefs?然后驱逐一个 Pod
- javascript - 如何注入 Adsense
- python - 如何将字典的文本文件读入 DataFrame
- c++ - 从其他类的静态数据成员初始化映射
- android - 完成创建广告的所有步骤后,插页式广告不会显示在 Android 模拟器上
- python - 如何从数组中获取完整的单词而不是python中的第一个字母
- jquery - Bootstrap 4 导航栏折叠正确但无法展开
- java - 如何从 Java 运行 C++ exe 文件?