动态规划 TSP 问题

本文探讨了如何使用动态规划解决旅行商问题(TSP),证明了TSP的最优子结构,并详细描述了算法过程,包括问题假设、算法描述和实现代码。通过全排列和子集生成方法,逐步求解城市间的最短路径。
摘要由CSDN通过智能技术生成

    TSP 问题是旅行商从一个城市出发,各个城市仅经过一次,最后回到出发的城市,求出最短的路径的距离。使用动态规划解决问题,首先需要证明问题具有最优子结构性质。可以使用反证法证明TSP 问题具有最优子结构性质。

    1. 问题假设

        假设有4个城市,编号分别为0、1、2、3。设distance(k,V')  且V' = V-k 表示从顶点i出发,经过V'集合中的每个点,并且只经过一次最后回到出发点i的最短距离。所以可以有下面的表达式:

           d(k,{}) = cki  以及d(i,V') = min(cik+d(k,V'-{k}))  (k 属于V')

    2. 算法描述

        首先使用n*n的二维矩阵表示城市之间的距离,如1行2列表示城市1到城市2的距离。将城市到自己的距离设为最大值。使用另一个矩阵,行表示各个城市,列表示城市集合的各个子集,按照子集的大小排列。求解某个点开始经过集合中的所有的点一次的最短距离可以通过比较各个自问题获得。即:distance(i,V') = min(cik,distance(k,V''))  其中k 为V' 集合中任意取出的一个顶点,V'表示从总集合中减去i点的集合,V'' 表示在V' 的基础上减去取出的顶点k的集合。

    3. 实现代码

        代码实现中,在集合的表示与子集的获得上遇到了一些问题。之后先通过全排列获得所有的组合,之后再全排列中加上判断,即当前附加的顶点的编号必须大于前面的编号,最后就获得了某个集合的所有的子集。之后再对子集拍一下序就可以了。下面是获得所有子集的方法:

	void getSubsets(deque<int> &seq,bool *visited,int depth,int n) {
		if (depth == 0) {
			subsets.push_back(deque<int>());	//加入空集合
			getSubsets(seq, visited, depth + 1, n);
		}
		else if (depth >= n) {
			//已经达到了最大的深度
			return;
		}
		else {
			for (int i = 1; i < n; ++i) {
				//判断是否访问过,比较大小,防止出现顺序不同但集合元素相同的情况
				if (!visited[i]) {
					if (!seq.empty() && i < seq.back())
						continue;
					visited[i] = true;
					seq.push_back(i);
					subsets.push_back(*new deque<int>(seq));	//保存当前的序列
					getSubsets(seq, visited, depth + 1, n);
					visited[i] = false;
					seq.pop_back();
				}
			}
		}
	}

下面是具体的实现代码。在求解的前面的各个阶段,集合中没有包括起始顶点v0,直到最后才求解distance(v0,V)。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值