用动态规划方法旅行商问题(TSP问题)

某推销员要从城市v1 出发,访问其它城市v2,v3,…,v6 各一次且仅一次,最后返回v1。D
为各城市间的距离矩阵。
问:该推销员应如何选择路线,才能使总的行程最短?

   以下是用动态规划方法,Linux下g++编译通过
#include  < iostream >
#include 
< set >
#include 
< vector >

#define  MAX 6

using   namespace  std;

int  dis[MAX][MAX] = {
        
01020304050,
        
120 ,18302521,
        
231905,  1015,
        
343240,  8,  16,
        
452711,100,  18,
        
562216,2012,  0
}
;

typedef 
struct
{
    
int curcity;//当前所在的城市
    vector<int> unvisited;//当前未访问的城市
    set<int> type;//由于set自动排序,相同状态的vector可能不同,但set必然相同
    int distance;//从当前城市到终点回到起点的距离
}
status;

/*测试用*/
void  printVec( vector < status >  vec)
{
    vector
<status>::iterator iter;
    vector
<int>::iterator it;
  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
旅行商问题是一个经典的组合优化问题,它的目标是找到一条路径,使得一个旅行商能够访问一组城市,同时最小化总距离或总成本。动态规划是解决旅行商问题的一种常见方法。下面是一个Python实现的动态规划TSP算法: ```python import sys from itertools import permutations def tsp_dp(cities): # 计算城市之间的距离矩阵 n = len(cities) dist = [[0] * n for i in range(n)] for i in range(n): for j in range(n): dist[i][j] = distance(cities[i], cities[j]) # 初始化动态规划表 dp = [[-1] * (1 << n) for i in range(n)] for i in range(n): dp[i][1 << i] = 0 # 动态规划 for mask in range(1, 1 << n): for i in range(n): if mask & (1 << i) == 0: continue for j in range(n): if i == j or mask & (1 << j) == 0: continue prev_mask = mask ^ (1 << i) if dp[i][mask] == -1: continue if dp[j][prev_mask] == -1: dp[j][prev_mask] = dp[i][mask] + dist[i][j] else: dp[j][prev_mask] = min(dp[j][prev_mask], dp[i][mask] + dist[i][j]) # 找到最小旅行距离 min_dist = sys.maxsize for i in range(n): if dp[i][(1 << n) - 1] == -1: continue min_dist = min(min_dist, dp[i][(1 << n) - 1] + dist[i][0]) return min_dist def distance(city1, city2): return ((city1[0] - city2[0]) ** 2 + (city1[1] - city2[1]) ** 2) ** 0.5 # 示例 cities = [(0, 0), (1, 2), (3, 4), (5, 6)] print(tsp_dp(cities)) ``` 该算法使用动态规划来计算从每个城市开始的最小旅行距离。它首先计算城市之间的距离矩阵,然后初始化一个动态规划表。每个单元格表示从一个城市出发,访问特定子集的城市的最小距离。然后,它使用一个循环来填充动态规划表,直到所有子集都被处理。最后,找到最小旅行距离并返回。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值