双向BFS搜索和A*算法

来源:互联网 发布:淘宝明星zero距离签名 编辑:程序博客网 时间:2024/06/05 20:21

双向BFS适合给出起点和终点,求最短路径的问题

分别从起点和终点扩展,找交点。每次选择待扩展节点少的那个方向进行扩展,一次扩展一层。

扩展一个节点的时候,如果节点也在另一个方向的待扩展队列里,找到交点。

int doubleBFS(vector<vector<int>> &G, int start, int end) {vector<vector<bool>> marked(2, vector<bool>(G.size()));//dead and to-be-expanded nodesqueue<int> q[2]; //newly expanded nodes, to be expandedint level[2] {0, 0}; //how many levels that has finished expandingq[0].push(start), marked[0][start] = true, marked[1][end] = true, q[1].push(end);//expand one level. choose next direction at end: whose to-be-expand list is smallerfor (int t = 0; q[t].size() > 0; ++level[t], t = q[0].size() <= q[1].size() ? 0 : 1) {for (int sz = q[t].size(), i = 0; i < sz; ++i) {int v = q[t].front(); q[t].pop();//in the other direction's queue, intersection  foundif (marked[!t][v]) return level[0] + level[1] + 1;for (int w : G[v]) {if (!marked[t][w]) {marked[t][w] = true;q[t].push(w);}}}}return -1; //the given nodes are not connected}



具体求出路径

vector<int> doubleBFS(vector<vector<int>> &G, int start, int end) {vector<vector<bool>> marked(2, vector<bool>(G.size())); //dead and to-be-expand nodesvector<int> prev[2] {vector<int>(G.size()), vector<int>(G.size())}; //predecessorqueue<int> q[2]; //newly expanded nodes, to be expandedq[0].push(start), marked[0][start] = true, marked[1][end] = true, q[1].push(end);//expand one level, determine next direction at end: whose queue is smallerfor (int t = 0; q[t].size() > 0; t = q[0].size() <= q[1].size() ? 0 : 1) {for (int sz = q[t].size(), i = 0; i < sz; ++i) {int v = q[t].front(); q[t].pop();// in the other direction's to-be-extended list, intersection foundif (marked[!t][v]) {deque<int> path;for (int x = v; x != start; x = prev[0][x]) path.push_front(prev[0][x]);path.push_back(v);for (int x = v; x != end; x = prev[1][x]) path.push_back(prev[1][x]);return vector<int>(path.begin(), path.end());}for (int w : G[v]) {if (!marked[t][w]) {marked[t][w] = true;prev[t][w] = v;q[t].push(w);}}}}return {}; //the given nodes are not connected}


BFS,DFS,A*分别是三种不同的搜索(遍历)顺序:

BFS:宽度优先

DFS:深度优先

A* :  估价优先

A*是带一点启发式的搜索,对新扩展出来的节点用估价函数 f(v) = g(v) + h(v)进行估价,按估价排序,然后选择下一个扩展节点。A*是dfs、bfs之外的另一种遍历顺序——按估价。对应的容器分别是stack, queue, priority_queue。

BFS,DFS,A*只是搜索顺序不同,并没有排除、丢弃任何节点,都是O(n)的,只是期望目标节点尽可能排在前面。 还有一些搜索是可以排除、丢弃一部分节点的搜索,比如局部择优搜索、二分搜索。

0 0
原创粉丝点击