我正在尝试使用BFS实现最短路径算法。那就是我试图找到从指定顶点到每个其他顶点的最短路径。但是,它是一种特殊情况,所有边缘权重都是1或2。 我知道可以用Dijkstra算法完成,但我必须使用广度优先搜索。
到目前为止,我有一个BFS的工作版本,它首先搜索与权重1的边连接的顶点。如果找不到它,则返回一个与权重2的边连接的顶点。在考虑之后,这个找不到最短路径的方法不正确。 问题是我无法想到任何理由为什么BFS可以使用权重1或2,而不是任何权重。
以下是代码:
public void addEdge(int start, int end, int weight)
{
adjMat[start][end] = 1;
adjMat[end][start] = 1;
edge_weight[start][end] = weight;
edge_weight[end][start] = weight;
}
// -------------------------------------------------------------
public void bfs() // breadth-first search
{ // begin at vertex 0
vertexList[0].wasVisited = true; // mark it
displayVertex(0); // display it
theQueue.insert(0); // insert at tail
int v2;
while( !theQueue.isEmpty() ) // until queue empty,
{
int v1 = theQueue.remove(); // remove vertex at head
// until it has no unvisited neighbors
while( (v2=getAdjUnvisitedVertex(v1)) != -1 ){// get one,
vertexList[v2].wasVisited = true; // mark it
displayVertex(v2); // display it
theQueue.insert(v2); // insert it
}
} // end while(queue not empty)
// queue is empty, so we're done
for(int j=0; j<nVerts; j++) // reset flags
vertexList[j].wasVisited = false;
} // end bfs()
// -------------------------------------------------------------
// returns an unvisited vertex adj to v -- ****WITH WEIGHT 1****
public int getAdjUnvisitedVertex(int v) {
for (int j = 0; j < nVerts; j++)
if (adjMat[v][j] == 1 && vertexList[j].wasVisited == false && edge_weight[v][j] == 1){
//System.out.println("Vertex found with 1:"+ vertexList[j].label);
return j;
}
for (int k = 0; k < nVerts; k++)
if (adjMat[v][k] == 1 && vertexList[k].wasVisited == false && edge_weight[v][k] == 2){
//System.out.println("Vertex found with 2:"+vertexList[k].label);
return k;
}
return -1;
} // end getAdjUnvisitedVertex()
// -------------------------------------------------------------
}
////////////////////////////////////////////////////////////////
public class BFS{
public static void main(String[] args)
{
Graph theGraph = new Graph();
theGraph.addVertex('A'); // 0 (start for bfs)
theGraph.addVertex('B'); // 1
theGraph.addVertex('C'); // 2
theGraph.addEdge(0, 1,2); // AB
theGraph.addEdge(1, 2,1); // BC
theGraph.addEdge(2, 0,1); // AD
System.out.print("Visits: ");
theGraph.bfs(); // breadth-first search
System.out.println();
} // end main()
}
问题在于,我不知道为什么BFS可以解决权重1或2的边缘的最短路径问题,而不是任何权重的任何边缘。
感谢任何帮助。 谢谢!
编辑:问题在于:您希望找到从s到其余顶点的最短路径。这可以使用Dijkstra算法完成,但您需要使用广度优先搜索策略。您应该能够这样做,因为任何边缘权重都是1或2.描述可以解决问题的BFS更改
答案 0 :(得分:1)
边缘权重限制对BFS的重要性在于它确保如果从A到B存在边缘,则从A到B没有更短的路径.AB边缘的最大权重是2.最小总数从A到C到B的路径的权重也是2.
答案 1 :(得分:0)
因为您专门询问未访问的边缘且权重为1或2:
/ returns an unvisited vertex adj to v -- ****WITH WEIGHT 1****
public int getAdjUnvisitedVertex(int v) {
...
if (adjMat[v][j] == 1 && vertexList[j].wasVisited == false &&
edge_weight[v][j] == 1
...
if (adjMat[v][k] == 1 && vertexList[k].wasVisited == false &&
edge_weight[v][k] == 2)
...
}
如果根据实际代码将weight_weight设置为权重不同于1和2,则方法getAdjUnvisitedVertex
将始终返回-1。因此:
while( (v2=getAdjUnvisitedVertex(v1)) != -1 ){// get one,
vertexList[v2].wasVisited = true; // mark it
displayVertex(v2); // display it
theQueue.insert(v2); // insert it
}
while内的计算永远不会被执行。
BFS用于从起始顶点查找最小边数的路径。因此,BFS找到最短路径,假设每条边具有相同的权重。一种算法用于图的特殊情况(非权重图)。
为了找到权重图上的最短路径,您可以使用另一组算法,例如Dijkstra’s算法和Prim。