2013-05-25 14 views
6

Biorąc pod uwagę ten kod ...Python przeszukiwanie wszerz optymalizacja

import Queue 

def breadthFirstSearch(graph, start, end): 
    q = Queue.Queue() 
    path = [start] 
    q.put(path) 
    while not q.empty(): 
     path = q.get() 
     lastNode = path[len(path) - 1] 
     if lastNode == end: 
      return path 
     for linkNode in graph[lastNode]: 
      if linkNode not in path: 
       newPath = [] 
       newPath = path + [linkNode] 
       q.put(newPath) 

Jeżeli wykres jest słownikiem reprezentującej graf skierowany, np {'stack':['overflow'], 'foo':['bar']} czyli stos skierowaną do przepełnienia i foo jest skierowaną do baru.

Czy ta szerokość pierwszego wyszukiwania może być zoptymalizowana bardziej? Ponieważ planuję użyć go na bardzo dużym słowniku.

+2

Chociaż prawdopodobnie nie jest to duża optymalizacja, 'Queue.Queue' jest przeznaczony do synchronizacji wielu wątków. Jeśli potrzebujesz prostej struktury danych kolejek, użyj zamiast niej 'collections.deque' i unikaj narzutu synchronizacji. – Blckknght

+0

Kiedy używam tego, otrzymuję inną odpowiedź, nie wiem dlaczego ... – Ogen

Odpowiedz

9

Dlaczego nie przechowywać zestawu odwiedzanych węzłów, aby nie uderzać w te same węzły? To powinno działać, ponieważ nie wygląda na to, że używasz ważonego wykresu. Coś takiego:

import Queue 

def bfs(graph, start, end): 
    q = Queue.Queue() 
    path = [start] 
    q.put(path) 
    visited = set([start]) 

    while not q.empty(): 
     path = q.get() 
     last_node = path[-1] 
     if last_node == end: 
      return path 
     for node in graph[last_node]: 
      if node not in visited: 
       visited.add(node) 
       q.put(path + [node]) 
+0

Dzięki za odpowiedź, zamierzam przetestować to teraz i wrócić do ciebie. Dzięki jeszcze raz. – Ogen

+0

Nie wiem dlaczego, ale kod utknął na linii: ** while not q.empty(): ** – Ogen

+0

@Clay I zupełnie zapomniałem dodać 'path = q.get()' do mojego kodu, który prawdopodobnie nie pomoże ... –