问题描述
我正在编写一种算法,以在给定源和目标时遍历图形。该算法应遍历并在图中显示从源到目的地的所有可能路径。我正在使用广度优先搜索来做到这一点,它在小图中起作用。但是,当提供了一个巨大的图形(具有超过1000个顶点)时,该程序似乎被冻结,并且在很长一段时间后不会显示任何输出。我可以知道如何解决这个问题吗?
我进行的一项简单测试(小图)
@H_502_5@ graph.addVertex("A",25); graph.addVertex("B",60); graph.addVertex("C",45); graph.addVertex("D",75); graph.addVertex("E",95); graph.addVertex("F",85); graph.addVertex("G",105); graph.addEdge("A","B","AB",""); graph.addEdge("A","D","AD","C","AC","E","AE",""); graph.addEdge("B","BE",""); graph.addEdge("E","F","EF","G","EG",""); graph.addEdge("D","DC","DF",""); graph.addEdge("F","FG",""); graph.addEdge("C","CF",""); String str = graph.bfs("A","G"); System.out.println(str);
我的广度优先搜索算法
@H_502_5@// SUBMODULE: bfs // IMPORT: src (String),dest (String) // EXPORT: T (String) public String bfs( String src,String dest ) { String T = ""; DSAQueue Q = new DSAQueue(); // The queue will store linked list DSALinkedList path = null; // This is the list for queue DSALinkedList adj = null; // Adjacency for src adj = getAdjacent( src ); // Make adjacent to linked list first and store in queue for( Object o : adj ) { DSALinkedList ll = new DSALinkedList(); // Creating list for every iteration DSAGraphVertex vertex = (DSAGraphVertex) o; ll.insertLast( vertex ); // Every adjacent vertex is ele of list Q.enqueue( ll ); // Store the list to queue } // ASSERTION: We Iterate until Q is empty,Q will store all L[V] while( !Q.isEmpty() ) { path = (DSALinkedList) Q.dequeue(); // Dequeue a linked list // Get the tail of list DSAGraphVertex v = (DSAGraphVertex) path.peekLast(); // We found the complete list path when the tail is dest if( v.getLabel().equals(dest) ) { T += src + " -> "; for( Object o : path ) { DSAGraphVertex pathVertex = (DSAGraphVertex) o; T += pathVertex.getLabel() + " -> "; } T += "(END)\n"; } else { // If v.getLabel() is not dest,we need to do bfs from adj of tail DSALinkedList tailAdj = v.getAdjacent(); // Check the number of paths in this vertex if( v.getSize() == 1 ) { /* If only one path found,simply traverse to the only one path */ DSAGraphVertex headVertex = (DSAGraphVertex) tailAdj.peekFirst(); // head of the tailAdj path.insertLast( headVertex ); Q.enqueue( path ); headVertex = null; } else { /* If the vertex has more than one path,copy all the existing paths for every single connection,then insert the new node to each list */ for( Object o : tailAdj ) { DSALinkedList newList = new DSALinkedList(); newList = copyList( path ); // copy the existing // Then add the new node into the copied list DSAGraphVertex currVertex = (DSAGraphVertex) o; newList.insertLast( currVertex ); // The queue Now has a new list of paths Q.enqueue( newList ); newList = null; } } tailAdj = null; } path = null; } return T; }
解决方法
1000个节点在图形中不是很大。我想象您的代码中某处有一个无限循环。让我们在这里看到一个无限循环的可能位置:while( !Q.isEmpty() )
是的,我看不到阻止将节点添加到队列中的任何内容。队列仅应处理每个节点一次。您需要保留一个已添加到队列中并且不允许再次添加的节点的列表。
它不会很快停止,因为您永远不会停止向队列中添加内容,因此它永远不会为空。
当天的课程:只要您的循环只有在满足条件时才结束,所以请双重确保有可能满足该条件。