回溯法解旅行推销员问题

    [问题]某推销员要到若干城市去推销商品,各城市之间的路程如下图所示。他要选定一条从驻地1出发,经过每个城市一次,最后回到驻地的路线,并使总路程最短。

    

     [解析]将该问题的解空间组织如下:

     这棵解空间树中从根节点B到任一叶节点的路径均定义了图的一条周游路线,而图的每一条周游路线都恰好对应于解空间树中从根节点B到某一叶节点的路径。

     最后从根节点B开始,对解空间树进行DFS。所选用的剪枝函数为判断当前已花费的路程是否小于当前已找到的最短周游路径的长度,属于限界函数。搜索过程中每到达一个叶节点,则记录当前周游路径的总路程,并与已找到的最小值进行比较,根据比较结果来更新最小值。

     代码如下:

// 推销员当前所在的城市,初始化为出发地1
static int currentLocation = 1;

// 存储各城市之间距离,其中i地与j地之间的距离为distance[i][j],n=3
static int distance[n+1][n+1];

// 标识第i站(i从0开始)为哪个城市,即当前路径在解空间树中层次为i的节点处选择的子链接代表的是哪个城市,其中根节点的层次为0,数组初始化为{2,3,4}
static int station[n];

// 存储当前已找到的最优周游路线
static int optimal[n];

// 当前已找到的最短路程,初始化为正无穷大
static int minTotalDiatance = MAX_INFINITY;

// 当前已花费的路程,初始化为0
static int distanceGone = 0;

// 对解空间树中层次为i的当前节点进行DFS
void BackTrack(int i)
{
	// 检查是否已到达叶节点
    if(i == n)
	{
		// 如果已到达叶节点,则对当前路径所表示的周游方案进行处理
		if(distanceGone < minTotalDiatance)
		{
			// 存储当前已找到的最优周游方案
			Copy(station,optimal,n);

			// 更新最短路程
			minTotalDiatance = distanceGone;
		}
	}
	else // 如果尚未到达叶节点,则沿着当前节点的各条子链接分别进行DFS
	{
		for(int j = i;j < n;j++)
		{
			distanceGone += distance[currentLocation][station[j]];
			
			// 检查当前节点的当前子节点是否满足限界条件,即当前已花费的路程是否小于当前已找到的最短周游路径的长度
			if(distanceGone < minTotalDiatance)
			{
				// 如果满足,则推进到当前节点的当前子节点
				Exchange(station,i,j);
	
				// 对新的当前节点进行DFS
				BackTrack(i + 1);

				// 对新的当前节点进行DFS完毕后,回溯到其父节点,即原来的当前节点
				Exchange(station,i,j);
				distanceGone -= distance[currentLocation][station[j]];
			}
			else
			{
				// 如果不满足,则直接回溯到当前节点
				distanceGone -= distance[currentLocation][station[j]];
			}
		}
	}
}

  

转载于:https://www.cnblogs.com/laifeiyao/p/3492758.html

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 回溯法旅行售货员问题时的空间树是一棵树形结构,其中每个节点表示一个可能的,从根节点开始,每个节点都有多个子节点,代表在当前状态下可以进行的所有选择。在旅行售货员问题中,每个节点表示当前已经走过的路径,每个子节点表示下一步可以走的城市,直到找到一条完整的路径,或者发现当前路径不可能是最优为止。通过回溯法,可以遍历整个空间树,找到最优。 ### 回答2: 回溯法是一种常用的求问题的方法,在求旅行售货员问题时同样如此。我们可以将问题看作是在一个图上求遍历全部顶点,然而每个顶点只能被经过一次的问题。由此,我们将空间树作为回溯法该问题的主要数据结构,以便更好地理问题的求过程。 首先,我们可以将图中的每个顶点看作是一个节点,而每条边则表示两个节点之间的连接。在回溯法的求过程中,我们需要不断地在空间树上遍历,找到合适的路径。在这个过程中,我们需要对已经经过的顶点进行标记,以避免重复经过同一个节点。 当我们找到一条满足条件(即经过所有顶点恰好一次)的路径时,我们就得到了一个回溯法会继续遍历所有的节点,直到找到所有可能的,或者找到一个最优为止。 因此,空间树的结构很简单。根节点表示初始状态,而每个子节点则表示向前扩展某个顶点后的状态。子节点的深度表示当前顶点的序列长度,而每个节点可能有若干个子节点,分别对应于可以扩展的下一个顶点。 总之,回溯法决旅行售货员问题时的空间树可以看作是一个二叉树结构,以初始状态为根节点,每个子节点表示向前扩展某个顶点后的状态。在深度搜索的过程中,我们需要对已经访问的顶点进行标记,以避免重复访问。求过程中,遍历所有可能的路径,直到找到所有可能的或者找到一个满足条件的最优为止。 ### 回答3: 旅行售货员问题是指一个售货员需要拜访n个城市并返回原点,求他经过的最短路径。在题过程中,我们可以使用回溯法来求回溯法是一种基于深度优先搜索的算法,将问题的空间看作一棵树,搜索整棵树得到答案。对于旅行售货员问题而言,我们可以将每一个城市看做空间树的一个节点,售货员从一个城市出发,会有n-1个城市作为下一个节点进行访问,这些子节点会再次向下展开,直到访问完所有城市后返回原点。因此,空间树的深度为n,每个节点下有n-1个子节点。 回溯法在搜索过程中有两个核心操作,分别是“剪枝”和“回溯”。剪枝指的是在搜索将节点向下展开之前,判断当前节点是否合法,如果不合法就及时返回。而回溯则是在搜索到某个节点并返回它的父节点之后,将该节点的状态恢复到初始状态,以继续搜索其他的节点。 在旅行售货员问题中,我们可以通过剪枝来避免不必要的搜索,每当我们经过一个城市时,将该城市标记为“已经访问过”,并检查当前路径是否已经大于之前求得的最小路径长度,如果是,则终止搜索。同样,在回溯的过程中,我们需要将之前标记为“已经访问过”的城市恢复为未访问状态,以便继续搜索其他的路径。 总的来说,回溯法旅行售货员问题时的空间树是一棵高度为n,每个节点下有n-1个子节点的树,通过剪枝和回溯操作,搜索整棵树得到售货员所需走的最短路径

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值