双向BFS搜索和A*算法

双向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 nodes
	queue<int> q[2]; //newly expanded nodes, to be expanded
	int level[2] {0, 0}; //how many levels that has finished expanding
	q[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 smaller
	for (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  found
			if (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 nodes
	vector<int> prev[2] {vector<int>(G.size()), vector<int>(G.size())}; //predecessor
	queue<int> q[2]; //newly expanded nodes, to be expanded
	q[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 smaller
	for (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 found
			if (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)的,只是期望目标节点尽可能排在前面。 还有一些搜索是可以排除、丢弃一部分节点的搜索,比如局部择优搜索、二分搜索。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值