繁体   English   中英

所有有效可能的组合

[英]All Valid Possible Combinations

我有5个公共汽车站的路线图:

a --_       _--b
     \--c--/
d ---/     \---e

我需要获得所有可能的有效路径。 有效路径是两个公交车站之间的路径,而不会跳过中间的任何公交车站。

例如,如果我们用二进制列表表示公交车站

            a b c d e
Stations = [1,1,1,1,1]

以下路径有效:

P1 = [1,0,1,0,1] # a <-> c <-> e
P2 = [0,0,1,1,0] # c <-> b 
P3 = [0,0,0,0,1] # e

这些都是无效的:

P4 = [1,1,0,0,0]
P5 = [0,1,0,1,0]

我创建了一个有效连接矩阵:

  a b c d e
a 1   1
b   1 1
c 1 1 1 1 1
d     1 1
e     1   1

我创造了所有可能的组合

c = list(itertools.product([0, 1], repeat=len(stations))

并将每条路径乘以上面的矩阵,但我没有得到任何有意义的东西。 有谁知道获得所有有效路径的方法? 我们的地图上可能有任意数量的巴士站。

这个答案包含一个简单的DFS解决方案(对于大图不一定非常有效)。

设置图表:

graph = {
    'a': {'c'},
    'b': {'c'},
    'c': {'a', 'b', 'd', 'e'},
    'd': {'c'},
    'e': {'c'},
}

给定节点和受访节点列表,枚举所有可能的子路径:

def list_paths(node, excluded_nodes):
    excluded_nodes = set(excluded_nodes)
    excluded_nodes.add(node)
    yield [node]
    yield from [[node] + p
        for x in graph[node] - excluded_nodes
        for p in list_paths(x, excluded_nodes)]

对所有起始节点执行此操作:

def list_all_paths():
    for k in graph:
        yield from list_paths(k, set())

最后,运行这个我们得到:

>>> from pprint import pprint
>>> pprint(list(list_all_paths()))
[['a'],
 ['a', 'c'],
 ['a', 'c', 'b'],
 ['a', 'c', 'd'],
 ['a', 'c', 'e'],
 ['b'],
 ['b', 'c'],
 ['b', 'c', 'a'],
 ['b', 'c', 'd'],
 ['b', 'c', 'e'],
 ['c'],
 ['c', 'a'],
 ['c', 'd'],
 ['c', 'b'],
 ['c', 'e'],
 ['d'],
 ['d', 'c'],
 ['d', 'c', 'a'],
 ['d', 'c', 'b'],
 ['d', 'c', 'e'],
 ['e'],
 ['e', 'c'],
 ['e', 'c', 'a'],
 ['e', 'c', 'd'],
 ['e', 'c', 'b']]

当然,你可以非常简单地将它们嵌入到你自己的载体中:

def list_all_vectors():
    embedding = {'a': 0, 'b': 1, 'c': 2, 'd': 3, 'e': 4}
    zero = [0 for x in range(len(embedding))]
    for path in list_all_paths():
        v = list(zero)
        for x in path:
            v[embedding[x]] = 1
        yield v

pprint(list(list_all_vectors()))

您会注意到,对于较大的图形,这很容易一遍又一遍地重新计算相同的子路径。 对此的快速修复可能是某种记忆,但通常情况下,可能有更好的算法。 (尝试谷歌搜索“枚举所有汉密尔顿路径”。)

这看起来像一个树算法。

从任何起点,列出所有可直接到达的巴士站。

从A开始,给出AD和AC

从这些中重复,除了不停止我们已经去过。 (如果它已经在我们去过的站点列表中,请不要添加一个字母)

AD - C(来自AD,然后添加C)

AC-D,AC-B,AC-E

再说一遍

ADC-B,ADC-E

ACD - (分支结束)

ACB-E(分支机构结束)

剩余起点的重复过程,可能的总路线,是所有发现路径的并集。

不要将其视为数组问题,而应将其视为构建一组字符串。 如果您创建表示问题的数据结构,则算法通常更容易理解和实现。

您需要首先输入路线图,以便为您提供所有邻居停靠点

答:C,D

B:C,E

C:A,B,D,E

D:A,C

E:B,C

希望这可以帮助。 那是我现在所有的时间。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM