[英]Using BFS algorithm to find the shortest path
std::list <int> q;
std::vector<bool> visited(cols + 1);
for(int i = 1; i <= cols; i++) visited[i] = false;
visited[x] = true;
if(!l[x].empty())
{
for(std::list<int>::iterator i = l[x].begin(); i != l[x].end(); i++)
{
q.push_back(x); q.push_back(* i);
}
while(!q.empty())
{
y = q.back(); q.pop_back();
x = q.back(); q.pop_back();
if(!visited[y])
{
visited[y] = true;
if(!l[y].empty())
for(std::list<int>::iterator i = l[y].begin(); i != l[y].end(); i++)
{
if(!visited[*i])
{q.push_back(y); q.push_back(* i);}
}
dfst[x].push_back(y);
if(flag != 0) dfst[y].push_back(x);
}
}
}
这是我的DFS算法,用于在图形中查找生成树。 我需要将其转换为BFS算法,以找到两个顶点之间的最短路径。 好吧...我该怎么做? BFS算法与上面的算法有点相似吗? 还是我需要从头开始编写?
l-邻接表dfst-在末尾保留生成树的数组x-起始顶点y-帮助程序变量
DFS和BFS本质上是相同的算法。 诀窍在于您使用的是哪种数据结构,或更确切地说是您首先探索的节点。
深度优先搜索会利用堆栈,因此会在移回算法之前尽可能下降。
要使用广度优先搜索,您将需要使用节点队列,并浏览每个节点,将其邻居(如果尚未访问)添加到队列中,然后处理父节点的其余邻居,然后继续。
这不会对代码进行大刀阔斧的改变,而只是从列表中获取节点的方式的改变。
与其从后面弹出,不如直接使用q.pop_front()
获取节点。
BFS与DFS类似。 而不是尽可能地深入,回溯和重复,而是查看深度1的所有节点,然后查看深度2的所有节点,依此类推,直到您访问了所有节点。
基本算法:
-Choose a starting node and add to LookQueue
-look at all nodes directly touching and add them to LookQueue
-when you've looked at them all
-look at all nodes in LookQueue (removing them as you do)
and look at all nodes touching them (adding them as you do)
-repeat until all nodes are visited
用于查找最短路径 (用C ++ / C ++ 11编写)
我认为这很重要,尤其是因为标题在最短的路径上! (下面的代码实际上可以让您找到一个)另外:如上所述(在第二个回复的评论中),DFS和BFS几乎没有(!)相同的算法,代码中的相似之处在于替换了排成一排,让您从一个跳到另一个并不会使它们“基本上相同”。 到目前为止,BFS是在未加权图中找到最短路径的更好/最合适的方法(两者之间)。 BFS从源头开始构建层,而DFS则尽可能深入。
实际上,在运行BFS(以查找最短路径)时,您应该使用一个带有很大数字的“距离”参数初始化节点,而不是使用访问的DS,将其更新为父级的距离+ 1(仅当它仍然与初始化值)。
一个简单的例子是:
#include <iostream>
#include <vector>
#include <queue>
#include <limits>
using namespace std;
const int imax = std::numeric_limits<int>::max();
using vi = vector<int>;
/* printPath - implementation at the end */
void
printPath(int s, int t, const vi &path);
/*input:
* n is number of the nodes in the Graph
* adjList holds a neighbors vector for each Node
* s is the source node
*/
void dfs(int n, vector<vi> adjList, int s)
{
//imax declared above as the max value for int (in C++)
vector<int> distance(n, imax);
vi path;
queue<int> q; q.push(s); distance[s] = 0;
while (!q.empty()) {
auto curr = q.front(); q.pop();
for (int i = 0; i < (int)adjList[curr].size(); ++i) {
if (distance[i] == imax) {
distance[i] = distance[curr] + 1;
//save the parent to have the path at the end of the algo.
path[i] = curr;
}
}//for
}//while
/* t can be anything you want */
int t = 5;
printPath(s, t, path); cout << endl;
}
/* print the shortest path from s to t */
void
printPath(int s, int t, const vi &path)
{
if (t == s) {
return;
}
printPath(s, path[t], path);
cout << path[t];
}
受Steven&Felix的启发,来自: 竞争编程3
不,您不必在代码中进行太多更改。 如果使用Queue将DFS替换为replace stack,它将变为BFS。
BFS和DFS的实现方式不同之处在于“ BFS是使用Queue实现的,而DFS是使用Stack的”(原因很明显,DFS的深度就像迷宫一样。)
自己查看更改:
DFS:
void dfs(int start)
{
int j,temp;
stack<int> s; //STACK
s.push(start);
vector<int>:: iterator it;
while(s.empty()==0)
{
temp=s.top(); // Top element from Stack
s.pop();
status[temp]=1; // marked as visited , 0 means unvisited
cout<<temp<<endl; // visited element
for(it=list[temp].begin();it!=list[temp].end();it++)
{
j=*it;
if(status[j]==0)
{
s.push(j);
status[j]=2; // means that it is in stack
}
}
}
}
BFS:
void bfs(int start)
{
int j,temp;
queue<int> q; // QUEUE
q.push(start);
vector<int>:: iterator it;
while(q.empty()==0)
{
temp=q.front(); // Front element from Queue
q.pop();
status[temp]=1; // marked as visited , 0 means unvisited
cout<<temp<<endl; // visited element
for(it=list[temp].begin();it!=list[temp].end();it++)
{
j=*it;
if(status[j]==0)
{
q.push(j);
status[j]=2; // means that it is in queue
}
}
}
}
如您所见,两者的实现仅在“使用STACK和QUEUE”方面有所不同。
希望这可以帮助 !
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.