[英]Overall shortest path to selected nodes
我已經被困在以下問題上一段時間了。 這個問題是一個經典的階梯問題,稍作修改。 我需要寫這將返回的索引的函數first_word
在一些給定的無向圖(其中每個邊緣具有重量1),使得它創建的整體最短字梯子每個詞語的desired_words
(更精確地說,它返回一個單詞的索引,其中到desired_words
任何單詞的最長單詞階梯盡可能短); 如果可能有多個單詞,它只會返回其中一個。
假設我有以下列表, lst = ["aaa","aad","dad","daa","aca","acc","aab","abb"]
,然后我們創建一個實例圖的類。 例如,如果我們的desired_words
是dad, abb, acc
那么我們的函數將返回 0,因為在這種情況下最好的first_word
將是aaa
。 如果我們在aaa, aca, acc
上運行我們的函數aaa, aca, acc
那么它將返回 4 因為在這種情況下最好的first_word
將是aca
。
我在考慮各種方法:在每個節點上運行 Dijkstra 算法,然后找到到每個desired_words
的最短距離,或者找到一個圖(約旦)中心,找到節點之間的最低共同祖先,但沒有一個對我來說似乎很有意義。 我只是不知道如何應用任何已知的算法,以便它返回最佳節點。
誰能建議解決這個問題的正確方法是什么? 只是一個一般的想法,或者一些逐步的算法。 非常感謝。
PS python 代碼會有所幫助,但不是必需的。
您可以在每個所需節點上啟動一個單獨的 BFS,但要同步。 一旦你找到一個從所有 BFS 源訪問過的節點,你就找到了解決方案。
因此,關鍵是為每個節點維護每個源的visited
標志。 這可能是一組源節點(源節點位於 BFS 的開頭)。
這是一個實現。 第一部分構建圖(作為鄰接表),第二部分執行多個 BFS:
from collections import defaultdict
def ladder(words):
# Group words when they share a n-1 subsequence
common = [defaultdict(list) for _ in words[0]]
for word in words:
for i, ch in enumerate(word):
# i-th character removed is key
common[i][word[:i] + word[i+1:]].append(word)
# Create the graph from those word groups:
graph = defaultdict(list)
for dct in common:
for words in dct.values():
for i, word in enumerate(words):
graph[word].extend(words[:i] + words[i+1:])
return dict(graph)
def getfirstword(ladder, desiredwords):
visited = { # For each word: one flag per BFS source
word: set()
for word in graph
}
desiredwords = set(desiredwords) # Remove duplicates
n = len(desiredwords)
frontiers = { # One entry per BFS source
word: [word]
for word in desiredwords
}
for word in desiredwords:
visited[word].add(word)
while any(frontiers): # If ever False, then graph is disconnected
for source, words in frontiers.items():
frontier = []
for word in words:
for neighbor in graph[word]:
if source not in visited[neighbor]:
visited[neighbor].add(source)
if len(visited[neighbor]) == n:
return neighbor
frontier.append(neighbor)
frontiers[source] = frontier
您的示例圖創建如下:
words = ["aaa","aad","dad","daa","aca","acc","aab","abb"]
graph = ladder(words)
print("Adjacency list:")
for word, neighbors in graph.items():
print(f"'{word}': {neighbors}")
這輸出:
Adjacency list:
'aaa': ['daa', 'aca', 'aad', 'aab']
'daa': ['aaa', 'dad']
'aad': ['dad', 'aaa', 'aab']
'dad': ['aad', 'daa']
'aca': ['aaa', 'acc']
'acc': ['aca']
'aab': ['abb', 'aaa', 'aad']
'abb': ['aab']
您討論的兩個示例查詢可以按如下方式進行:
queries = [
["dad", "abb", "acc"],
["aaa", "aca", "acc"]
]
for query in queries:
print(f"For desired words {query} a solution is: '{getfirstword(graph, query)}'")
這輸出:
For desired words ['dad', 'abb', 'acc'] a solution is: 'aaa'
For desired words ['aaa', 'aca', 'acc'] a solution is: 'aca'
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.