簡體   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