旅行商问题(动态规划 |
您所在的位置:网站首页 › 爬山法与算法式区别在哪 › 旅行商问题(动态规划 |
问题描述
旅行商问题(Travelling Salesman Problem, 简记TSP,亦称货郎担问题):设有n个城市和距离矩阵D=[dij],其中dij表示城市i到城市j的距离,i,j=1,2 … n,则问题是要找出遍访每个城市恰好一次的一条回路并使其路径长度为最短。 一、动态规划解决旅行商问题 要使用动态规划,需要问题本身有最优子结构,我们需要找到要解决的问题的子问题。题目要求,从0(a)出发,经过[1(b),2©,3(d)]这几个城市,然后回到0,使得花费最少。要实现这个要求,需要从下面三个实现方案中选择花费最少的方案。 从0出发,到1,然后再从1出发,经过[2,3]这几个城市,然后回到0,使得花费最少。 从0出发,到2,然后再从2出发,经过[1,3]这几个城市,然后回到0,使得花费最少。 从0出发,到3,然后再从3出发,经过[1,2]这几个城市,然后回到0,使得花费最少。 可以发现,三个小的解决方案的最优解,构成了大的解决方案,所以这个问题具有最优子结构,可以用动态规划来实现。 设置一个二维的动态规划表dp,定义符号{1,2,3}表示经过[1,2,3]这几个城市,然后回到0。 设置一个二维数组l保存两个城市之间的距离。 那么题目就是求dp[0][{1,2,3}]。将{1,2,3}表示成二进制,就是111,对应10进制的7,所以题目是在求dp[0][7]; 要求三个方案的最小值意味: dp[0][{1,2,3}] = min{l[0][1]+dp[1][{2,3}] ,l[0][2]+dp[2][{1,3}] ,l[0][3]+dp[3][{1,2}]} dp[1][{2,3}] = min{ l[1][2]+dp[2][{3}] ,l[1][3]+dp[3][{2}]} dp[2][{3}] = l[2][3]+dp[3][{}] dp[3][{}]就是从3出发,不经过任何城市,回到0的花费,所以dp[3][{}] = l[3][0] 1.1 相关代码: #确定结点个数和权值 def prepare(self): # 初始化dp和权值矩阵value Max = 1000 temp = [] tmp = [] for i in range(Max): for j in range(Max): temp.append(0x7ffff) tmp.append(0) # print(temp) self.dp.append(copy.deepcopy(temp)) self.value.append(copy.deepcopy(tmp)) temp.clear() tmp.clear() self.value[0][1] = self.value[1][0] = 2 self.value[0][2] = self.value[2][0] = 5 self.value[0][3] = self.value[3][0] = 7 self.value[1][2] = self.value[2][1] = 8 self.value[1][3] = self.value[3][1] = 3 self.value[2][3] = self.value[3][2] = 1 #动态规划求解旅行商问题 ''' dp[0][{1,2,3}] = min{l[0][1]+dp[1][{2,3}] ,l[0][2]+dp[2][{1,3}] ,l[0][3]+dp[3][{1,2}]} dp[1][{2,3}] = min{ l[1][2]+dp[2][{3}] ,l[1][3]+dp[3][{2}]} dp[2][{3}] = l[2][3]+dp[3][{}] = l[2][3]+ l[3][0] ''' def dp_method(self): #初始化dp数组第一列 for i in range(self.n): self.dp[i][0] = self.value[i][0] col = 1 (i-1) & 1: continue ''' 从2出发,要去{1,3}。 先看去1的路,去了1集合{1,3}中只剩下{3} ,{3}对应4,所以要求的dp表就是dp[1][4],这个4可以通过(101) ^ (1)得到,(1) = 1(2-1)) &1==1。而且也由于从2出发,就更不能去了。 最后看去3的路,去了3集合{1,3}中只剩下{1},{1}对应这1,所以要求的dp表就是dp[3][1],1通过(101) ^ (100)得到。(100) = 1 |
今日新闻 |
点击排行 |
|
推荐新闻 |
图片新闻 |
|
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭 |