【问题描述】
一销售商从n个城市中的某一城市出发,不重复地走完其余n—1个城市并回到原出发点,在所有可能的路径中求出路径长度最短的一条。本题假定该旅行商从第1个城市出发。
输入
对每个测试例,第1行有两个整数:n(4≤n≤10)和m(4≤m≤20 ) ,n是结点数,m是边数。
接下来m行,描述边的关系,每行3个整数:(i,j),length,表示结点i到结点j的长度是length。
当n=0时,表示输入结束。
输出
对每个测试例,输出最短路径长度所经历的结点,最短的长度。
输入样例
4 6
1 2 20
1 4 4
1 3 6
2 3 5
2 4 10
3 4 15
0
输出样例
1 3 2 4
25
【算法分析】
旅行商问题的解空间是一棵排列树。 开始时,x={1,2,…,n},相应的排列树由x的全排列构成。
TSP问题(Traveling Salesman Problem)通常称为旅行商问题,也称为旅行售货员问题、货担郎问题等,是组合优化中的著名难题,也是计算复杂性理论、图论、运筹学、最优化理论等领域中的一个经典问题,具有广泛的应用背景。
问题的一般描述为:旅行商从n个城市中的某一城市出发,经过每个城市仅有一次,最后回到原出发点,在所有可能的路径中求出路径长度最短的一条。
设G=(V, E)是一个带权图,其每一条边(u, v)∈E的费用(权)为正数w(u, v)。目的是要找出G的一条经过每个顶点一次且仅经过一次的回路,即汉密尔顿(Hamilton)回路v1,v2 ,…,vn ,使回路的总权值最小:文章来源:https://www.toymoban.com/news/detail-481171.html
文章来源地址https://www.toymoban.com/news/detail-481171.html
【代码部分】
//旅行商问题回溯算法的数据结构
#define NUM 100
int n; //图G的顶点数量
int m; //图G的边数
int a[NUM][NUM]; //图G的邻接矩阵
int x[NUM]; //当前解
int bestx[NUM]; //当前最优解向量
int cc; //当前费用
int bestc; //当前最优值
int NoEdge = -1; //无边标记
//在构造邻接矩阵a时,其初始值应为NoEdge:
for (i=0; i<NUM; i++)
for (j=1; j<NUM; j++)
a[i][j] = NoEdge;
//最优值和向量x的初始化数值如下:
bestc = NoEdge;
for(i=1; i<=n; i++)
x[i] = i;
//旅行商问题回溯算法的实现
//形参t是回溯的深度,从2开始
void Backtrack(int t)
{
//到达叶子结点的父结点
if(t==n)
{
if(a[x[n-1]][x[n]]!= NoEdge && a[x[n]][1]!= NoEdge &&
(cc + a[x[n-1]][x[n]]+a[x[n]][1]<bestc||bestc== NoEdge))
{
for(int i=1; i<=n; i++)
bestx[i] = x[i];
bestc = cc + a[x[n-1]][x[n]] + a[x[n]][1];
}
return;
}
else
{
for(int i=t; i<=n; i++)
{
if(a[x[t-1]][x[i]]!= NoEdge &&
(cc + a[x[t-1]][x[i]]< bestc||bestc == NoEdge))
{
swap(x[t],x[i]);
cc += a[x[t-1]][x[t]];
Backtrack(t+1);
cc -= a[x[t-1]][x[t]];
swap(x[t],x[i]);
}
}
}
}
//完整实现
#include <iostream>
using namespace std;
#define NUM 100
int n;
int m;
int a[NUM][NUM];
int x[NUM];
int bestx[NUM];
int cc;
int bestc;
int NoEdge = -1;
void Backtrack(int t)
{
if(t==n)
{
if(a[x[n-1]][x[n]]!= NoEdge && a[x[n]][1]!= NoEdge &&
(cc + a[x[n-1]][x[n]]+a[x[n]][1]<bestc||bestc== NoEdge))
{
for(int i=1; i<=n; i++)
bestx[i] = x[i];
bestc = cc + a[x[n-1]][x[n]] + a[x[n]][1];
}
return;
}
else
{
for(int i=t; i<=n; i++)
{
if(a[x[t-1]][x[i]]!= NoEdge &&
(cc + a[x[t-1]][x[i]]< bestc||bestc == NoEdge))
{
swap(x[t],x[i]);
cc += a[x[t-1]][x[t]];
Backtrack(t+1);
cc -= a[x[t-1]][x[t]];
swap(x[t],x[i]);
}
}
}
}
int main()
{
int i, j;
int from, to, length;
while (scanf("%d%d", &n, &m) && n)
{
for (i=0; i<NUM; i++)
for (j=1; j<NUM; j++)
a[i][j] = NoEdge;
for (i=0; i<m; i++)
{
scanf("%d%d%d", &from, &to, &length);
a[from][to] = length;
a[to][from] = length;
}
bestc = NoEdge;
for(i=1; i<=n; i++)
x[i] = i;
Backtrack(2);
for(j=1; j<=n; j++)
printf("%d ", bestx[j]);
printf("\n%d\n", bestc);
}
return 0;
}
到了这里,关于【回溯算法】旅行商问题--TSP问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!