2016-09-19 6 views
2

나는 794 개의 3 글자 긴 단어가있는 목록이 있습니다. 내 임무는 주어진 단어에 대한 가장 긴 경로를 가진 단어를 찾는 것이다.BFS에서 가장 긴 경로 찾기

정의 (어린이) : 부모 단어
아이들은 부모 한 단어 교체 하나의 편지입니다.

예 :
'수'(그 단어가 목록에 있는지 주어진) 단어 '실행'에 자녀 등등 '실행', '랩'.

정의 (경로)
경로는 각각의 워드는 이전에 단일 문자를 교환함으로써 생성되는 일련의 단어이다.

#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

IIUC,이은 (그렇지 않은 경우 사실, 당신이 사례를 구축 할 수 있습니다) 작동하지 않을 수 있습니다.

노드 에서 시작하여; 직접 경로가있다 → b; 직접 경로 → c 및 간접 경로 c ⇒b도 있습니다.

당신이의 자식들에 대해 반복 할 때, 당신은 C 전에 B가 발생한다고 가정하자. b을 방문하여 방문한 것으로 표시합니다. 나중에 어느 시점에 c이 발생하고 결국 b을 다시 생각해보십시오. 알고리즘은 더 이상 하나의 → C ⇒ B보다는 짧은 서브 패스 → B을 고려할 것입니다 그래서 그 시점에서, 그러나, B는 이미 방문 간주됩니다.

그래프 뒤에있는 이야기는 DAG가 아니므로 "방문한"표시도 제거 할 수 없습니다. "방문한"논리를 제거하면 무한 루프가 발생합니다.

+0

그게 유효한 지적입니다.새로운 아이디어로 업데이트하겠습니다. – Lozansky

+0

사실, 당신의 요점이 유효하지 않을 수도 있습니다. 이는 a (즉, b 및 c)에 자식을 생성 할 때 루프에서 멈추지 않도록 이들을 추적해야하기 때문입니다. 그래서 b와 c가 생성되면, c가 자식을 생성하는 방법이 없어야합니다. – Lozansky

+0

@Lozansky 나는 당신의 요점을 따르지 않거나, 오히려 정확하게 내가하려는 부분입니다. 누군가가 그래프에서 가장 긴 경로를 가리키며 'a-> c-> b-> d'라고 가정합니다. 그런 다음, 알고리즘이 'a'의 첫 번째 자식으로 'b'를 만날 때, 그것을 건너 뛰고 'c'에서 도달 할 때까지 기다리는 것이 좋습니다. 문제는 알고리즘이이를 알지 못한다는 것입니다. 방문한 'b'를 표시 할 것이고이 경로를 고려하는 데 동의하지 않을 것입니다. 내가 뭔가를 놓친다면, 그것을 지적하는 것이 좋습니다. –