动态规划求解TSP(旅行商)问题
来源:互联网 发布:淘宝家具安装工 编辑:程序博客网 时间:2024/04/27 13:26
某推销员要从城市v1出发,访问其它城市v2,v3,…,v6各一次且仅一次,最后返回v1。D为各城市间的距离矩阵。问:该推销员应如何选择路线,才能使总的行程最短?
1、变量设定
阶段k:已遍历过k个结点,k=1,2…6,7。
K=1表示刚从V1出发,k=7表示已回到起点V1
状态变量Xk=(i,Sk):已遍历k个结点,当前位于i结点,还未遍历的结点集合为Sk。则X1=(1,{2,3,4,5,6}),X6=(i,Φ),X7=(1,Φ)
决策变量Uk=(i,j):已遍历k个结点,当前位于i结点,下一个结点选择j。
状态转移方程:Xk+1 = T(Xk,Uk) = (j,Sk-{j})
第k阶段的指标函数Vk = D[i,j]。
最优指标函数Fk(Xk) = Fk(i,Sk):已遍历k个结点,当前从i结点出发,访问Sk中的结点一次且仅一次,最后返回起点V1的最短距离。
则Fk(i,Sk) = min{ D[i,j] + Fk+1(j,Sk-{j}) } 1≤k≤6
F7(X7)= F7(1,Φ) = 0
2、分析:
(1)k=6时,F6(i,Φ) = min{D[i,1] + F7(X7)} = D[i,1] i=2,3,4,5,6
X6=(i,Φ)
U6=(i,j)
X7=(1,Φ)
V6=D[i,j]
F7(1,Φ)
V6 + F7(X7)
(2,Φ)
(2,1)
(1,Φ)
12
0
12=F6(2,Φ)
(3,Φ)
(3,1)
(1,Φ)
23
0
23=F6(3,Φ)
(4,Φ)
(4,1)
(1,Φ)
34
0
34=F6(4,Φ)
(5,Φ)
(5,1)
(1,Φ)
45
0
45=F6(5,Φ)
(6,Φ)
(6,1)
(1,Φ)
56
0
56=F6(6,Φ)
即k=6时,对于每一种状态X6,都有唯一的决策U6。
(2)k=5时,F5(i,S5) = min{D[i,j] + F6(j,Φ)} i=2,3,4,5,6
X5=(i,S5)
U5=(i,j)
X6=(j, Φ)
V5=D[i,j]
F6(j,Φ)
V5 + F6(X6)
(2,{6}}
(2,6)
(6,Φ)
21
56
77=F5(2,{6})
(2,{5}}
(2,5)
(5,Φ)
25
45
70=F5(2,{5})
(2,{4}}
(2,4)
(4,Φ)
30
34
64=F5(2,{4})
(2,{3}}
(2,3)
(3,Φ)
18
23
41=F5(2,{3})
(3,{6})
(3,6)
(6,Φ)
15
56
71=F5(3,{6})
(3,{5})
(3,5)
(5,Φ)
10
45
55=F5(3,{5})
(3,{4})
(3,4)
(4,Φ)
5
34
39=F5(3,{4})
(3,{2})
(3,2)
(2,Φ)
19
12
31=F5(3,{2})
(4,{6})
(4,6)
(6,Φ)
16
56
72=F5(4,{6})
(4,{5})
(4,5)
(5,Φ)
8
45
53=F5(4,{5})
(4,{3})
(4,3)
(3,Φ)
4
23
27=F5(4,{3})
(4,{2})
(4,2)
(2,Φ)
32
12
44=F5(4,{2})
(5,{6})
(5,6)
(6,Φ)
18
56
74=F5(5,{6})
(5,{4})
(5,4)
(4,Φ)
10
34
44=F5(5,{4})
(5,{3})
(5,3)
(3,Φ)
11
23
34=F5(5,{3})
(5,{2})
(5,2)
(2,Φ)
27
12
39=F5(5,{2})
(6,{5})
(6,5)
(5,Φ)
12
45
57=F5(6,{5})
(6,{4})
(6,4)
(4,Φ)
20
34
54=F5(6,{4})
(6,{3})
(6,3)
(3,Φ)
16
23
39=F5(6,{3})
(6,{2})
(6,2)
(2,Φ)
22
12
34=F5(6,{2})
即k=时,对于每一种状态X5,都有唯一决策U5。
(3)k=4时,F4(i,S4) = min(D[i,j] + F5(j,S5) ) i=2,3,4,5,6
X4=(i,S4)
U4=(i,j)
X5=(j,S5)
V4=D[i,j]
F5(j,S5)
V4 + F5(j,S5)
(2,{3,4})
(2,3)
(3,{4})
18
39
57=F4(2,{3,4})
(2,4)
(4,{3})
30
27
57=F4(2,{3,4})
(2,{4,5})
(2,4)
(4,{5})
30
53
83
(2,5)
(5,{4})
25
44
69=F4(2,{4,5})
(2,{5,6})
(2,5)
(5,{6})
25
74
99
(2,6)
(6,{5})
21
57
78=F4(2,{5,6})
(2,{3,5})
(2,3)
(3,{5})
18
55
73
(2,5)
(5,{3})
25
34
59=F4(2,{3,5})
(2,{3,6})
(2,3)
(3,{6})
18
71
89
(2,6)
(6,{3})
21
39
60=F4(2,{3,6})
(2,{4,6})
(2,4)
(4,{6})
30
72
102
(2,6)
(6,{4})
21
54
75=F4(2,{4,6})
(3,{2,4})
(3,2)
(2,{4})
19
64
83
(3,4)
(4,{2})
5
44
49=F4(3,{2,4})
(3,{2,5})
(3,2)
(2,{5})
19
70
89
(3,5)
(5,{2})
10
39
49=F4(3,{2,5})
(3,{2,6})
(3,2)
(2,{6})
19
77
96
(3,6)
(6,{2})
15
34
49=F4(3,{2,6})
(3,{4,5})
(3,4)
(4,{5})
5
53
58
(3,5)
(5,{4})
10
44
54=F4(3,{4,5})
(3,{4,6})
(3,4)
(4,{6})
5
72
77
(3,6)
(6,{4})
15
54
69=F4(3,{4,6})
(3,{5,6})
(3,5)
(5,{6})
10
74
84
(3,6)
(6,{5})
15
57
72=F4(3,{5,6})
(4,{2,3})
(4,2)
(2,{3})
32
41
73
(4,3)
(3,{2})
4
31
34=F4(4,{2,3})
(4,{2,5})
(4,2)
(2,{5})
32
70
102
(4,5)
(5,{2})
8
39
47=F4(4,{2,5})
(4,{2,6})
(4,2)
(2,{6})
32
77
109
(4,6)
(6,{2})
16
34
50=F4(4,{2,6})
(4,{3,5})
(4,3)
(3,{5})
4
55
59
(4,5)
(5,{3})
8
34
42=F4(4,{3,5})
(4,{3,6})
(4,3)
(3,{6})
4
71
75
(4,6)
(6,{3})
16
39
55=F4(4,{3,6})
(4,{5,6})
(4,5)
(5,{6})
8
74
82
(4,6)
(6,{5})
16
57
73=F4(4,{5,6})
(5,{2,3})
(5,2)
(2,{3})
27
41
68
(5,3)
(3,{2})
11
31
42=F4(5,{2,3})
(5,{2,4})
(5,2)
(2,{4})
27
64
91
(5,4)
(4,{2})
10
44
54=F4(5,{2,4})
(5,{2,6})
(5,2)
(2,{6})
27
77
104
(5,6)
(6,{2})
18
34
52=F4(5,{2,6})
(5,{3,4})
(5,3)
(3,{4})
11
39
50
(5,4)
(4,{3})
10
27
37=F4(5,{3,4})
(5,{3,6})
(5,3)
(3,{6})
11
71
82
(5,6)
(6,{3})
18
39
57=F4(5,{3,6})
(5,{4,6})
(5,4)
(4,{6})
10
72
82
(5,6)
(6,{4})
18
54
72=F4(5,{4,6})
(6,{2,3})
(6,2)
(2,{3})
22
41
63
(6,3)
(3,{2})
16
31
47=F4(6,{2,3})
(6,{2,4})
(6,2)
(2,{4})
22
64
86
(6,4)
(4,{2})
20
44
64=F4(6,{2,4})
(6,{2,5})
(6,2)
(2,{5})
22
70
92
(6,5)
(5,{2})
12
39
51=F4(6,{2,5})
(6,{3,4})
(6,3)
(3,{4})
16
39
55
(6,4)
(4,{3})
20
27
47=F4(6,{3,4})
(6,{3,5})
(6,3)
(3,{5})
16
55
71
(6,5)
(5,{3})
12
34
46=F4(6,{3,5})
(6,{4,5})
(6,4)
(4,{5})
20
53
73
(6,5)
(5,{4})
12
44
56=F4(6,{4,5})
(4)k=3时,F3(i,S3) = min{D[i,j] + F4(j,S4)} i=2,3,4,5,6
X3=(i,S3)
U3=(i,j)
X4=(j,S4)
V3=D[i,j]
F4(j,S4)
V3 + F4(j,S4)
(2,{3,4,5})
(2,3)
(3,{4,5})
18
54
72
(2,4)
(4,{3,5})
30
42
72
(2,5)
(5,{3,4})
25
37
62=F3(2,{3,4,5})
(2,{3,4,6})
(2,3)
(3,{4,6})
18
69
87
(2,4)
(4,{3,6})
30
55
85
(2,6)
(6,{3,4})
21
47
68=F3(2,{3,4,6})
(2,{3,5,6})
(2,3)
(3,{5,6})
18
72
90
(2,5)
(5,{3,6})
25
57
82
(2,6)
(6,{3,5})
21
46
67=F3(2,{3,5,6})
(2,{4,5,6})
(2,4)
(4,{5,6})
30
73
103
(2,5)
(5,{4,6})
25
72
97
(2,6)
(6,{4,5})
21
56
77=F3(2,{4,5,6})
(3,{2,4,5})
(3,2)
(2,{4,5})
19
69
88
(3,4)
(4,{2,5})
5
47
52=F3(3,{2,4,5})
(3,5)
(5,{2,4})
10
54
64
(3,{2,4,6})
(3,2)
(2,{4,6})
19
75
94
(3,4)
(4,{2,6})
5
50
55=F3(3,{2,4,6})
(3,6)
(6,{2,4})
15
64
79
(3,{2,5,6})
(3,2)
(2,{5,6})
19
78
97
(3,5)
(5,{2,6})
10
52
62=F3(3,{2,5,6})
(3,6)
(6,{2,5})
15
51
66
(3,{4,5,6})
(3,4)
(4,{5,6})
5
73
78
(3,5)
(5,{4,6})
10
72
82
(3,6)
(6,{4,5})
15
56
71=F3(3,{4,5,6})
(4,{2,3,5})
(4,2)
(2,{3,5})
32
59
91
(4,3)
(3,{2,5})
4
49
53
(4,5)
(5,{2,3})
8
42
50=F3(4,{2,3,5})
(4,{2,3,6})
(4,2)
(2,{3,6})
32
60
92
(4,3)
(3,{2,6})
4
49
53=F3(4,{2,3,6})
(4,6)
(6,{2,3})
16
47
63
(4,{2,5,6})
(4,2)
(2,{5,6})
32
78
110
(4,5)
(5,{2,6})
8
52
60=F3(4,{2,5,6})
(4,6)
(6,{2,5})
16
51
67
(4,{3,5,6})
(4,3)
(3,{5,6})
4
72
76
(4,5)
(5,{3,6})
8
57
65
(4,6)
(6,{3,5})
16
46
62=F3(4,{3,5,6})
(5,{2,3,4})
(5,2)
(2,{3,4})
27
57
84
(5,3)
(3,{2,4})
11
49
60
(5,4)
(4,{2,3})
10
34
44=F3(5,{2,3,4})
(5,{2,3,6})
(5,2)
(2,{3,6})
27
60
87
(5,3)
(3,{2,6})
11
49
60=F3(5,{2,3,6})
(5,6)
(6,{2,3})
18
47
65
(5,{2,4,6})
(5,2)
(2,{4,6})
27
75
102
(5,4)
(4,{2,6})
10
50
60=F3(5,{2,4,6})
(5,6)
(6,{2,4})
18
64
82
(5,{3,4,6})
(5,3)
(3,{4,6})
11
69
80
(5,4)
(4,{3,6})
10
55
65=F3(5,{3,4,6})
(5,6)
(6,{3,4})
18
47
65=F3(5,{3,4,6})
(6,{2,3,4})
(6,2)
(2,{3,4})
22
57
79
(6,3)
(3,{2,4})
16
49
65
(6,4)
(4,{2,3})
20
34
54=F3(6,{2,3,4})
(6,{2,3,5})
(6,2)
(2,{3,5})
22
59
81
(6,3)
(3,{2,5})
16
49
65
(6,5)
(5,{2,3})
12
42
54=F3(6,{2,3,5})
(6,{2,4,5})
(6,2)
(2,{4,5})
22
69
91
(6,4)
(4,{2,5})
20
47
67
(6,5)
(5,{2,4})
12
54
66=F3(6,{2,4,5})
(6,{3,4,5})
(6,3)
(3,{4,5})
16
54
70
(6,4)
(4,{3,5})
20
42
62
(6,5)
(5,{3,4})
12
37
49=F3(6,{3,4,5})
(5)k=2时,F2(i,S2) = min{D[i,j] + F3(j,S3)} i=2,3,4,5,6
X2=(i,S2)
U2=(i,j)
X3=(j,S3)
V2=D[i,j]
F3(j,S3)
V2 + F3(j,S3)
(2,{3,4,5,6})
(2,3)
(3,{4,5,6})
18
71
89
(2,4)
(4,{3,5,6})
30
62
92
(2,5)
(5,{3,4,6})
25
65
90
(2,6)
(6,{3,4,5})
21
49
70=F2(2,{3,4,5,6})
(3,{2,4,5,6})
(3,2)
(2,{4,5,6})
19
77
96
(3,4)
(4,{2,5,6})
5
60
65=F2(3,{2,4,5,6})
(3,5)
(5,{2,4,6})
10
60
70
(3,6)
(6,{2,4,5})
15
66
81
(4,{2,3,5,6})
(4,2)
(2,{3,5,6})
32
67
99
(4,3)
(3,{2,5,6})
4
62
66=F2(4,{2,3,5,6})
(4,5)
(5,{2,3,6})
8
60
68
(4,6)
(6,{2,3,5})
16
54
70
(5,{2,3,4,6})
(5,2)
(2,{3,4,6})
27
68
95
(5,3)
(3,{2,4,6})
11
55
66
(5,4)
(4,{2,3,6})
10
53
63=F2(5,{2,3,4,6})
(5,6)
(6,{2,3,4})
18
54
72
(6,{2,3,4,5})
(6,2)
(2,{3,4,5})
22
62
84
(6,3)
(3,{2,4,5})
16
52
68
(6,4)
(4,{2,3,5})
20
50
70
(6,5)
(5,{2,3,4})
12
44
56=F2(6,{2,3,4,5})
(6)k=1时,F1(1,S1) = min{D[1,j] + F2(j,S2)}
X1=(1,S1)
U1=(1,j)
X2=(j,S2)
V1=D[1,j]
F2(j,S2)
V1 + F2(j,S2)
(1,{2,3,4,5,6})
(1,2)
(2,{3,4,5,6})
10
70
80=F1(1,{2,3,4,5,6})
(1,3)
(3,{2,4,5,6})
20
65
85
(1,4)
(4,{2,3,5,6})
30
66
96
(1,5)
(5,{2,3,4,6})
40
63
103
(1,6)
(6,{2,3,4,5})
50
56
106
3、伪代码和C++源码
为方便计算,结点编号改为0到5.
(1)用一张二维表格F[][]表示F(i,Sk),行数是n,列数是2n-1。
(2)行号表示当前所在的结点i。
列号对应的五位二进制表示表示{V5,V4,V3,V2,V1}的一个子集,1表示在集合中,0表示不在集合中。
例如:00110表示的集合为{V3,V2},00000表示空集
(3)再用一张n*2n-1的表格M[][]存储对应每个状态(i,Sk)所做的最优决策,以便回溯找最短路线。
伪代码:
TSP(int D[][],int n)
//输入n个顶点的有向图,矩阵D[][]是有向图的邻接矩阵
//D[][]是原图的邻接矩阵
//F[][]中存储阶段最短路径,M[][]中存储阶段最优策略,行数是n,列数是2n-1
//找到从V0出发,遍历所有城市一次且仅一次再回到V0的最短路径长度
//并输出最短路径
{
for(i=0; i<n; i++)
F[i][0] = D[i][0]; //初始化第0列,F6(i,Φ)= D[i,0]
for(i=1; i<2n-1-1; i++) //列
for(j=1;j<n; j++) //行
if(j不在i的二进制表示对应的集合中)
对于i对应集合中的每一个点k
{
计算D[j][k]+F[k][i-2k-1]并选择使之取得最小值min的k*;
F[k][i]= min ; //填表,记录阶段最优值
M[k][i]= k* ; //记录每个状态的最优决策k*
}
//i==2n-1-1 时
对于i中的每个节点k
计算D[0][k] + F[k][ [i-2k-1]并选择使之取得最小值min的k*
F[0][ 2n-1-1] = min; //总最短路径
M[0][ 2n-1-1] = k*;
//回溯查表M输出最短路径
输出V0
for(2n-1-1,j=0; i>0; )
{
j =M[j][i];//下一步去往哪个结点
i = i –2j-1;//从i表示的集合中删除j
输出Vj
}
}
C++源码:
#include<iostream.h>#include<fstream.h>#include<stdlib.h>#include<math.h>#define n 6 //结点个数void main(){int i,j,k,min,temp;int b=(int)pow(2,n-1);int D[20][20];//原图的邻接矩阵fstream fin("TSPinput1.txt",ios::in);//打开输入文件fstream fout("TSPoutput.txt",ios::out);//打开输出文件//读入数据到邻接矩阵D中for(i=0;i<n;i++)for(j=0;j<n;j++)fin>>D[i][j];//申请二维数组F和Mint ** F = new int* [n];//n行b列的二维数组,存放阶段最优值int ** M = new int* [n];//n行b列的二维数组,存放最优策略for(i=0;i<n;i++){F[i] = new int[b];//每行有2的n-1次方列M[i] = new int[b];}//初始化F[][]和M[][]for(i=0;i<b;i++)for(j=0;j<n;j++){F[j][i] = -1;M[j][i] = -1;}//给F的第0列赋初值for(i=0;i<n;i++)F[i][0] = D[i][0];//遍历并填表for(i=1;i<b-1;i++)//最后一列不在循环里计算for(j=1;j<n;j++){//int p=(int)pow(2,j-1);//int res=p & i;if( ((int)pow(2,j-1) & i) == 0)//结点j不在i表示的集合中{min=65535;for(k=1;k<n;k++)if( (int)pow(2,k-1) & i )//非零表示结点k在集合中{temp = D[j][k] + F[k][i-(int)pow(2,k-1)]; if(temp < min){min = temp;F[j][i] = min;//保存阶段最优值M[j][i] = k;//保存最优决策}}}}//最后一列,即总最优值的计算min=65535;for(k=1;k<n;k++){//b-1的二进制全1,表示集合{1,2,3,4,5},从中去掉k结点即将k对应的二进制位置0temp = D[0][k] + F[k][b-1 - (int)pow(2,k-1)];if(temp < min){min = temp;F[0][b-1] = min;//总最优解M[0][b-1] = k;}}fout<<"最短路径长度:"<<F[0][b-1]<<endl;//最短路径长度//回溯查表M输出最短路径(编号0~n-1)fout<<"最短路径(编号0—n-1):"<<"0";for(i=b-1,j=0; i>0; )//i的二进制是5个1,表示集合{1,2,3,4,5}{j = M[j][i];//下一步去往哪个结点i = i - (int)pow(2,j-1);//从i中去掉j结点fout<<"->"<<j;}fout<<"->0"<<endl;//输出表格F到文件for(i=0;i<n;i++){for(j=0;j<b;j++)fout<<F[i][j]<<" ";fout<<endl;}}
源码及测试数据下载地址:http://download.csdn.net/detail/masikkk/4822942
- 动态规划求解TSP(旅行商)问题
- 动态规划 解TSP旅行商问题
- 利用动态规划法求解旅行商问题(TSP)的C语言实现(一)
- 使用动态规划求解旅行商问题
- 用动态规划方法旅行商问题(TSP问题)
- 用动态规划方法旅行商问题(TSP问题)
- HDU 5067 动态规划---旅行商(tsp)问题
- TSP:旅行商问题与内存优化的动态规划
- 动态规划法解旅行商问题(TSP)问题的java实现
- 动态规划方法解旅行商问题(TSP Traveling Salesperson Problem)
- 经典动态规划算法-(TSP)双调欧几里得旅行商问题-hdu2224
- (C语言)分支界限法求解旅行商(TSP)问题
- 遗传算法求解旅行商(TSP)问题
- 遗传算法 求解旅行商 TSP 问题,matlab代码
- TSP问题 动态规划实现
- TSP问题动态规划解决
- 旅行商问题的动态规划解决
- 旅行商问题(动态规划)
- 使用ant打包
- 二分搜素以及扩展 循环递增数组的搜索
- byte[]转字符串编码问题
- com.sun.awt.AWTUtilities的使用
- Map的遍历方法
- 动态规划求解TSP(旅行商)问题
- 黑马程序员_面向对象_static
- ant 混淆打包build.xml配置
- Windows系统编程(五):Windows内存
- 操作系统真实的虚拟内存是什么样的(一)
- 常见jsp出现的页面错误(404,500等)与捕捉办法
- elua跑起来了
- Fusioncharts 参数
- 链表翻转的两种方法(递归+非递归)