找到BFS的最长路径

时间:2016-09-19 11:13:48

标签: python python-3.x python-3.5

我有一个包含794个三字母长单词的列表。我的任务是找到具有给定单词最长路径的单词。

定义(儿童):
父母单词中的子项是父单词,其中只有一个单词被替换。

示例:
'can','run','rap'等等是'ran'这个词的孩子(假设这些词存在于列表中)。

定义(路径):
路径是一系列单词,其中每个单词都是通过交换前一个单个字母生成的。

#Pseudo code
Given a word 
    Put the word in a queue
    Keep a list with all visited words
    As long as the queue is not empty
        Get the first word in the queue
        Generate a list with all the children to this word
        For every children in that list
            If the child is not in the list of visited words
                Append the child to the list of visited words
                Put the child in the queue
    Print the path to the last grandchild.

我的想法是,这将是最长的路径,因为我们继续产生新的孩子,直到我们可能的孩子(即尚未访问过的孩子)用完为止。

问题:
我的想法有效吗?如何测试它是否真的有效?

下面可以查看实际代码,但没有评论可能没有任何意义。

修改
由于树和列表可能有点慢,我用套替换它们。

from Queue import Queuenode; import Bintree
with open('word3',encoding='utf-8') as f:
    lista=f.readlines()
    lista=[x.strip('\n') for x in lista]
alfabet='abcdefghijklmnopqrstuvwxyzåäö'
class Word:
    def __init__(self, w, f = None):
        self.word = w
        self.parent = f
children=Bintree.Bintree()
for i in lista:
    children.put(i)
def barn(far):
    barnlista=[]
    for i in range(3):
        for j in range(29):
            empty=''
            empty+=far[0:i]+alfabet[j]+far[i+1:]
            if empty!=far and children._exists(empty):
                barnlista+=[empty]
    return barnlista
ko=Queuenode()
def vag(item):
    start=item
    counter=0
    while start!=None:
        counter+=1
        print(start.word)
        start=start.parent
    print(counter)
def bfsx(startord):
    ko.put(Word(startord))
    besokta=[startord]
    while not ko.isempty():
        first=ko.get()
        lista=barn(first.word)
        for child in lista:
            if child not in besokta:
                besokta+=[child]
                ko.put(Word(child,first))
    vag(first)

1 个答案:

答案 0 :(得分:1)

IIUC,这不能保证有效(事实上,你可以建立它没有的案例)。

假设您从节点 a 开始;有一条直接路径 a→b ;还有一个直接路径 a→c 和一个间接路径c⇒b

假设当你遍历 a 的孩子时,你会在 c 之前遇到 b 。您处理 b 并将其标记为已访问。稍后您会遇到 c ,并最终再次重新考虑 b 。但是,此时, b 已被视为已访问,因此您的算法将考虑较短的子路径 a→b 而不是较长的 a→c⇒b

你也不能摆脱"访问过的"标记,因为图表背后的故事清楚地表明它不是DAG。如果你删除"访问过"逻辑,你会遇到无限循环。

相关问题