Python / Graphs:查找连接所有节点的特定长度的所有路径组合

时间:2017-01-24 16:20:28

标签: python graph networkx

问题定义

我有一个连接的无向图,有n个节点和根r。我需要找到路径的所有组合,其长度在范围(l)中,用于连接所有节点。

最后,我想找到最佳的路径组合,其中边缘的权重由长度及其在序列中的位置决定。

我已经尝试了一些解决方案,但最终有这么多选项,它变成了计算的噩梦。 在我的例子中,n = 35,所有节点的度数为8到10,路径长度应为7或8。

我正在使用Python 3.5。

可能的解决方案

在所有情况下,我都从定义所有可能的路径开始。因此,我使用NetworkX软件包的解决方案,如下所示: All paths of length L from node n using python

# Create a random graph that looks like the real one
G = nx.dense_gnm_random_graph(n=35, m=164, seed=0)

# Find all paths from root with length 0 to 8
n = 0
L = 8
no_n_node = G.nodes()
no_n_node.remove(n)
result = []

for paths in (nx.all_simple_paths(G=G, source=n, target=target, cutoff=L) for target in no_n_node):
    result+=paths

# Only keep paths of length 7 or 8
res78 = []
for path in result:
    if len(path) >= 8:
        res78.append(path[1:])

这导致24,383,690个路径,减少到'仅'3,181,622个7或8个点的集合(路径忽略的节点顺序)

这是我陷入困境的地方,因为我现在想要找到所有节点的所有路径,但只有一次。

如何进行,选项1

我的第一个想法是蛮力: - 对于所有唯一路径,从图中删除节点 - 计算剩余图中范围(l)中所有长度的路径 - 等等 但这是太多的计算

如何进行,选项2

我的另一个想法是,独立于它们的连接,找到组合包含所有节点一次的所有可能节点组合(跨越集)。 如何计算生成集,我基于Algorithm to generate (not quite) spanning set in Python

data = G.nodes()
data.remove[0]

from itertools import combinations

def cut(lst, indexes):
    last = 0
    for i in indexes:
        yield tuple(lst[last:i])
        last = i
    yield tuple(lst[last:])

def generate(lst, n):
    for indexes in combinations(tuple(range(1,len(lst))), n - 1):
        yield (tuple(cut(lst, indexes)))

这导致2 ^ n的列表。我试图制作一个只有长度为7或8的子集的生成集,但不知道该怎么做。

我猜它仍然计算太重,但我当时想做的是: - 退出生成集,只包含那些只包含也可以在路径中找到的集合的集合 - 对于所有这个子集,从根(旅行商问题)

开始,找到集合中的最短路径

修改/添加

方向不同

我睡了一夜之后想到的另一个方向就是找到所有的生树,只保留那些没有分支的树,只有一定长度的树枝。 剩下的问题:如何找到所有生成树? 我发现How to efficiently generate all possible spanning trees from a graph可能会让我开始。

编辑结束

有没有人有关于如何优化我使用的算法的建议,或者知道我错过了NetworkX中的一个功能但是会让一切变得容易一些?

0 个答案:

没有答案