Scala 检测图中的循环,一个实现

Scala 检测图中的循环,一个实现,scala,data-structures,graph,Scala,Data Structures,Graph,这是我第一次尝试了解如何在图中检测循环。我尝试实现这个伪代码来检测图中的循环(有向或无向): 下面是我在Scala中的代码: def containsCycle(g: Graph): Boolean = { for (v <- g.vertices) v.mark = "WHITE" for (v <- g.vertices) { if (v.mark == "WHITE") { if (visit(g, v)) ret

这是我第一次尝试了解如何在图中检测循环。我尝试实现这个伪代码来检测图中的循环(有向或无向):

下面是我在Scala中的代码:

def containsCycle(g: Graph): Boolean = {
    for (v <- g.vertices) v.mark = "WHITE"
    for (v <- g.vertices) {
      if (v.mark == "WHITE") {
        if (visit(g, v))
          return true
      }
    }
    return false
  }

  def visit(g: Graph, v: Vertex): Boolean = {
    v.mark = "GREY"
    for (e <- g.edges) {
      if (e.destination.mark == "GREY"){
        return true
      }
      else {

        if (e.destination.mark == "WHITE") {
          if (visit(g, e.destination))
            return true
        }
      }
    }
    v.mark = "BLACK"
    return false
  }
def containsCycle(g:Graph):布尔={

对于(vI),我还使用着色方法将节点分类为未探测(W)、探测(G)和已完成(B)探测

下面是我的代码,用于检测图中的循环(连接和断开连接)。虽然效率不高,但它提供了正确的DFS输出,并指示图中是否存在循环

要检测循环,必须考虑两个条件:

  • 自循环

  • 我们尝试探索已经在递归堆栈(灰色)/(后缘)中的顶点

  • 对于第二个条件,我使用了递归堆栈(RecurStack)

    我使用了这里给出的想法
    遵循这个例子

    虽然我使用了着色方法来理解DFS,但我没有添加algo中给出的时间特性

    我希望下面的代码能回答您的问题

    import collections
    
    class Vertex:
        def __init__(self,val):
            self.color="W"
    
    class Graph:
        def __init__(self):
            self.master_vertex={}                                                                        
            self.Q=[]                                                                                    
            self.visit=[]                                                                                
            self.adj_vertex=collections.defaultdict(list)                                                
            self.cycle=0                                                                                 
    
        def add_vertex(self,vert):
            nv=Vertex(vert)
            self.master_vertex[vert]=nv
    
        def add_edge(self,src,dest):                                                                     
            self.adj_vertex[src].append(dest)
    
    
    
    def DFS_Visit(graph):
            for ver in list(graph.master_vertex.keys()):
                if ver not in graph.visit and graph.master_vertex[ver].color=="W":
                DFS_iterative(graph,ver)
            if graph.cycle==1:
                return True
            else:
                return False
    
    
    def DFS_iterative(graph,start):
        recur_stack=[]                                                                                      
        graph.Q.append(start)
    
        while len(graph.Q)>0:
            start=graph.Q[len(graph.Q)-1]                                                               
            recur_stack.append((graph.Q.pop()))
            graph.master_vertex[start].color="G"  
    
            if len(graph.adj_vertex[start])==0:                                                         
                graph.master_vertex[start].color="B"   
            for ver in graph.adj_vertex[start]:
                if start==ver or (graph.master_vertex[ver].color=="G" and ver in recur_stack):          
                    graph.cycle=1
                if graph.master_vertex[ver].color=="W" and ver not in graph.Q:
                    graph.Q.append(ver)
            graph.visit.append(start)
    
        while len(recur_stack)>0:
            x=recur_stack.pop()
            if graph.master_vertex[x].color=="G":
                graph.master_vertex[x].color="B"   
    
    
    if __name__=='__main__':
    
        g=Graph()
        for i in range(1,7):
            g.add_vertex(str(input()))
    
        g.add_edge('u','v')
        g.add_edge('u','x')
        g.add_edge('v','y')
        g.add_edge('y','x')
        g.add_edge('x','v')
        g.add_edge('w','y')
        g.add_edge('w','z')
        g.add_edge('z','z')
        print g.adj_vertex
        print "Iterative DFS: "
        if DFS_Visit(g):
            print "graph contains cycle"
        else:
            print "graph does not contain cycle"
        print g.visit
    
    上述代码的输出:

    访问
    中,不应该
    对于(e@DavidDuponchel),第一个错误是我使用了
    返回
    表达式,并且我的程序在第一个被删除的边缘终止:(我使用一个矩阵来表示边,所以我现在将尝试按照您的建议迭代每个边的邻居。谢谢这不是更好地匹配stackexchange代码审阅站点吗?如果您提供一些关于什么不起作用的线索,这会有所帮助。
    import collections
    
    class Vertex:
        def __init__(self,val):
            self.color="W"
    
    class Graph:
        def __init__(self):
            self.master_vertex={}                                                                        
            self.Q=[]                                                                                    
            self.visit=[]                                                                                
            self.adj_vertex=collections.defaultdict(list)                                                
            self.cycle=0                                                                                 
    
        def add_vertex(self,vert):
            nv=Vertex(vert)
            self.master_vertex[vert]=nv
    
        def add_edge(self,src,dest):                                                                     
            self.adj_vertex[src].append(dest)
    
    
    
    def DFS_Visit(graph):
            for ver in list(graph.master_vertex.keys()):
                if ver not in graph.visit and graph.master_vertex[ver].color=="W":
                DFS_iterative(graph,ver)
            if graph.cycle==1:
                return True
            else:
                return False
    
    
    def DFS_iterative(graph,start):
        recur_stack=[]                                                                                      
        graph.Q.append(start)
    
        while len(graph.Q)>0:
            start=graph.Q[len(graph.Q)-1]                                                               
            recur_stack.append((graph.Q.pop()))
            graph.master_vertex[start].color="G"  
    
            if len(graph.adj_vertex[start])==0:                                                         
                graph.master_vertex[start].color="B"   
            for ver in graph.adj_vertex[start]:
                if start==ver or (graph.master_vertex[ver].color=="G" and ver in recur_stack):          
                    graph.cycle=1
                if graph.master_vertex[ver].color=="W" and ver not in graph.Q:
                    graph.Q.append(ver)
            graph.visit.append(start)
    
        while len(recur_stack)>0:
            x=recur_stack.pop()
            if graph.master_vertex[x].color=="G":
                graph.master_vertex[x].color="B"   
    
    
    if __name__=='__main__':
    
        g=Graph()
        for i in range(1,7):
            g.add_vertex(str(input()))
    
        g.add_edge('u','v')
        g.add_edge('u','x')
        g.add_edge('v','y')
        g.add_edge('y','x')
        g.add_edge('x','v')
        g.add_edge('w','y')
        g.add_edge('w','z')
        g.add_edge('z','z')
        print g.adj_vertex
        print "Iterative DFS: "
        if DFS_Visit(g):
            print "graph contains cycle"
        else:
            print "graph does not contain cycle"
        print g.visit