python中的深度优先搜索(DFS)代码

时间:2017-04-15 19:23:48

标签: python depth-first-search

请告诉我以下DFS代码中的错误。它给出了正确的结果AFAIK,但我不知道什么时候会失败。

graph1 = {
    'A' : ['B','S'],
    'B' : ['A'],
    'C' : ['D','E','F','S'],
    'D' : ['C'],
    'E' : ['C','H'],
    'F' : ['C','G'],
    'G' : ['F','S'],
    'H' : ['E','G'],
    'S' : ['A','C','G']
}

visited = []

def dfs(graph,node):
    global visited
    if node not in visited:
        visited.append(node)
        for n in graph[node]:
            dfs(graph,n)

    dfs(graph1,'A')
    print(visited)

输出:

['A', 'B', 'S', 'C', 'D', 'E', 'H', 'G', 'F']

9 个答案:

答案 0 :(得分:6)

我认为那里有缩进问题。假设您的代码如下所示:

<p:dataTable var="projectMaterial"  id="projectMaterial" paginator="true" paginatorAlwaysVisible="true" paginatorTemplate="{CurrentPageReport}  {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}" rows="12" rowsPerPageTemplate="5,10,15" rowSelectMode="true" selection="#{pprMaterialAuthorizationBean.selectedMaterialList}" rowKey="#{projectMaterial.id}" value="#{pprMaterialAuthorizationBean.materialList}">
    <p:column  headerText="#{lang.labelMaterial}" filterBy="#{lang[projectMaterial.materialLangPrm]}" sortBy="#{lang[projectMaterial.materialLangPrm]}" width="40%">
        <h:outputText value="#{lang[projectMaterial.materialLangPrm]}" />
    </p:column>
    <p:ajax  event="toggleSelect" listener="#{pprMaterialAuthorizationBean.onToggleSelect}" update=":form1 :msgs"/> 
    <p:column id="columnId" selectionMode="multiple" width="40%"/>
</p:dataTable>

我想说几件事:

  • 如果可以,请避免使用全局
  • 使用集合
  • 代替访问列表

加:

  • 这对森林不起作用,但我假设你已经知道了
  • 如果引用不存在的节点,则会失败。

更新的代码:

graph1 = {
    'A' : ['B','S'],
    'B' : ['A'],
    'C' : ['D','E','F','S'],
    'D' : ['C'],
    'E' : ['C','H'],
    'F' : ['C','G'],
    'G' : ['F','S'],
    'H' : ['E','G'],
    'S' : ['A','C','G']
}

visited = []

def dfs(graph,node):
    global visited
    if node not in visited:
        visited.append(node)
        for n in graph[node]:
            dfs(graph,n)

dfs(graph1,'A')
print(visited)

答案 1 :(得分:2)

这是DFS的迭代(非递归)实现:

def dfs_iterative(graph, start_vertex):
    visited = set()
    traversal = []
    stack = [start_vertex]
    while stack:
        vertex = stack.pop()
        if vertex not in visited:
            visited.add(vertex)
            traversal.append(vertex)
            stack.extend(reversed(graph[vertex]))   # add vertex in the same order as visited
    return traversal

test_graph = {
    'A' : ['B','S'],
    'B' : ['A'],
    'C' : ['D','E','F','S'],
    'D' : ['C'],
    'E' : ['C','H'],
    'F' : ['C','G'],
    'G' : ['F','S'],
    'H' : ['E','G'],
    'S' : ['A','C','G']
}

print(dfs_iterative(test_graph, 'A'))

输出:

['A', 'B', 'S', 'C', 'D', 'E', 'H', 'G', 'F']

答案 2 :(得分:1)

无递归:

def dfs(graph, node):
visited = [node]
stack = [node]
while stack:
    node = stack[-1]
    if node not in visited:
        visited.extend(node)
    remove_from_stack = True
    for next in graph[node]:
       if next not in visited:
          stack.extend(next)
          remove_from_stack = False
          break
    if remove_from_stack:
        stack.pop()
return visited

答案 3 :(得分:0)

Python中的DFS实现

from collections import defaultdict

class Graph:
    def __init__(self):
        self.graph = defaultdict(list)

    def addEdge(self, u, v):
        self.graph[u].append(v)

    def DFSUtil(self, v, visited):
        visited[v]=True
        print(v)

        for i in self.graph[v]:
            if visited[i] == False:
                self.DFSUtil(i, visited)

    def DFS(self):
        V = len(self.graph)

        visited = [False]*(V)

        for i in range(V):
            if visited[i] == False:
                self.DFSUtil(i, visited)

# Driver code
# Create a graph given in the above diagram
g = Graph()
g.addEdge(0, 1)
g.addEdge(0, 2)
g.addEdge(1, 2)
g.addEdge(2, 0)
g.addEdge(2, 3)
g.addEdge(3, 3)

print("Following is Depth First Traversal")
g.DFS()

来源:: this

答案 4 :(得分:0)

 graph = {'A': ['B', 'C'],
         'B': ['A', 'D', 'E'],
         'C': ['A', 'F'],
         'D': ['B'],
         'E': ['B', 'F'],
         'F': ['C', 'E']}

   def dfs(s,d):
    def dfs_helper(s,d):
        if s == d:
            return True
        if  s in visited :
            return False
        visited.add(s)
        for c in graph[s]:
            dfs_helper(c,d)
        return False
    visited = set()
    return dfs_helper(s,d) 
dfs('A','E') ---- True
dfs('A','M') ---- False

答案 5 :(得分:0)

from collections import defaultdict

class Graph:
    def __init__(self):
        self.graph = defaultdict(list)

    def addEdge(self,u,v):
        self.graph[u].append(v)

    def DFS(self,v,vertex):
        visited = [False]*vertex
        print(self. graph)
        # print(len(self.graph),"+++")
        self.DFSUtil(v,visited)

    def DFSUtil(self,v,visited):
        visited[v]=True
        print(v)

        for i in self.graph[v]:
            if visited[i] == False:
                # print(visited)
                self.DFSUtil(i,visited)
g= Graph()

vertex=7

g.addEdge(0,1)
g.addEdge(0,2)
g.addEdge(0,6)
g.addEdge(0,5)
g.addEdge(5,3)
g.addEdge(5,4)
g.addEdge(4,3)
g.addEdge(6,4)

g.DFS(0,vertex) 

这是对以上代码的修改,因为它并非在所有情况下都适用。
我们必须指定向量的数量,然后手动赋予边缘。

答案 6 :(得分:0)

这是一种更加通用的算法,问题中提出的算法仅适用于无向图。但这有望对他们俩都起作用。 签出

graph1= {
'A' : ['B','S'],
'B' : [],
'C' : ['E','S'],
'D' : ['C'],
'E' : ['H'],
'F' : ['C'],
'G' : ['F','S'],
'H' : ['G'],
'S' : []
}
visited = []

def dfs_visit(graph, s):
    global visited
    for v in graph[s]:
        if v not in visited:
            visited.append(v)
            dfs_visit(graph, v)


def dfs(graph):
    global visited
    for v in [*graph]:
        if v not in visited:
            visited.append(v)
            dfs_visit(graph,v)

dfs(graph1)
print(visited)

答案 7 :(得分:0)

    def DFS(graph,pointer,visit):
          visit.add(pointer)
          print(pointer,end=' ')

    for travel in graph[pointer]-visit:
        if travel not in visit:
            DFS(graph,travel,visit)


graph={'0':set(['1','2','3']),'1':set(['0','2']),'2':set(['0','1','4']),'3':set(['0']),'4':set(['2'])}
visit=set()
print("DFS for graph: ",graph)
DFS(graph,'0',visit)

输出

DFS for graph:  {'0': {'1', '3', '2'}, '1': {'0', '2'}, '2': {'1', '0', '4'}, '3': {'0'}, '4': {'2'}}
0 1 2 4 3 

答案 8 :(得分:0)

递归实现:

def dfs(G, u, visited=[]):
    """Recursion version for depth-first search (DFS).
    Args:
        G: a graph
        u: start
        visited: a list containing all visited nodes in G
    Return:
        visited
    """
    visited.append(u)
    for v in G[u]:
        if v not in visited:
            dfs(G, v, visited)
    return visited

使用堆栈的迭代实现:

def dfs_iterative(G, u, visited=[]):
    stack = [u, ] #initialize
    while stack:
        u = stack.pop()
        if u not in visited:
            visited.append(u)
            stack.extend(reversed(G[u])) #reversed() is used as the same traversal as recursive DFS
    return visited