dfs和bfs在求解最优解问题上的互通与差异

     我们都知道,dfs和bfs在大多数情况下是能够互通的,所以今天我将用例题的形式来分析两个思路的互通和差异之处,帮助我们更好的理解搜索在求解最优路线中的应用思想。

1.背景介绍

奇怪的电梯

分析:题目还是比较简单的,就是要我们在尽可能少的步骤下,从起点到达目的地,首先,我们要明确,最优路线一定是不能重复经过某个点的,也就是说,我们可以通过设置已访问数组来达到剪枝优化算法时间的效果,我们就从起点出发,搜索每一种可能得走法,并且每走一步就判断当前是否已经到达终点,注意,此时我们的判断就是基于最优视角判断的,同时出发搜索,谁先到达终点,谁就是最优解。接着我们来分析bfs和dfs两者在求解同一个问题上的差异。

 法1:dfs

  dfs:dfs是深度优先遍历,也就是从起点出发,直到达到终止条件方才结束此过程,我们可以从起点出发,dfs遍历每个点,如果这个点的下一个点是合法的就继续到这个点上使用dfs,相当于分不同的路径并行遍历,直到有一条路找到结果,dfs就会结束,并返回这个值,最先找到的也就是最小步骤数;

//dfs
#include <bits/stdc++.h>
using namespace std;
int n, a, b;
int d[210];
int vis[205];
int flag = 0;
void dfs(int cur, int next, int count)
{
	if (cur == b)
	{
		flag = 1;
		printf("%d\n", count);
		return;
	}
	else
	{
		int next = 0;
		for (int i = 0; i < 2; i++)
		{
			if (i == 0)
				next = cur + d[cur];
			else
				next = cur - d[cur];
			if (vis[next] || next<1 || next>n)
				continue;
            vis[next] = 1;
			dfs(next, d[next], count + 1);
		}
	}
}
int main()
{
	cin >> n >> a >> b;
	memset(vis, 0, sizeof(vis));
	for (int i = 1; i <= n; i++)
		cin >> d[i];
	vis[a] = 1;
	dfs(a, d[a], 0);
	if (!flag)
		printf("-1\n");
	return 0;
}

法2:bfs

    bfs:bfs一般要配合栈或者队列来使用,在思路上,我们需要将起点压入栈或者队列,每次取出栈顶或者队首元素,通过判断该元素的下一个合法操作的点,再将下一层点依次进行入队操作,这样,每一层都将可能的情况压入队列,这里注意,对于同一个元素的下一层次的不同种情况,他们的路径虽然不同,但是他们经过的步骤是一致的,在同一层依次遍历不同的情况的时候的时候,对于每一个入队元素,其步骤数都是来自同一个上层的点,还要注意搭配已访问标记数组来进行剪枝操作,提高运行效率。

//bfs
#include <bits/stdc++.h>
using namespace std;
int n, a, b;
int flag = 0;
int vis[205];
struct data {
	int cur, oper, count;
	data(int curr = 0, int operr = 0, int countt = 0)
	{
		cur = curr, oper = operr, count = countt;
	}
}d[210];
int main()
{
	cin >> n >> a >> b;
	memset(vis, 0, sizeof(vis));

	for (int i = 1; i <= n; i++)
	{
		cin >> d[i].oper;
		d[i].cur = i;
		d[i].count = 0;
	}
	queue<struct data> m;
	struct data temp2(d[a].cur, d[a].oper, d[a].count);
	vis[a] = 1;
	m.push(temp2);
	while (!m.empty())
	{
		struct data temp = m.front();
		m.pop();
		if (temp.cur == b)
		{
			cout << temp.count << endl;
			flag = 1;
			return 0;
		}
		for (int i = 0; i < 2; i++)
		{
			struct data next(temp.cur, temp.oper, temp.count + 1);
			if (i == 0)
			{
				next.cur = temp.cur + temp.oper;
			}
			if (i == 1)
			{
				next.cur = temp.cur - temp.oper;
			}
			if (vis[next.cur]==1||next.cur<1 || next.cur>n)
				continue;
			next.oper = d[next.cur].oper;//后赋值,防止非法访问
			m.push(next);
			vis[next.cur] = 1;
		}
	}
	if (!flag)
		cout << "-1" << endl;
	return 0;
}

总结:dfs和bfs的时间复杂度相差不大,但是在空间复杂度上来说,bfs使用的空间一般要比dfs大,dfs更适合找到任意一个可行解,而bfs更适合找到全局最优解。

2.金句省身

时间对于每个人来说都是公平的,全在于自己如何去把握,新的一天,克服拖延,专注努力,在无人问津的地方努力,在万众瞩目的地方闪耀。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值