一、问题描述
TSP问题(Travelling Salesman Problem)即旅行商问题,是NP-hard的经典问题之一。可描述为:一销售商从n个城市中的某一城市出发,不重复地走完其余n—1个城市并回到原出发点,在所有可能的路径中求出路径长度最短的一条。本题假定该旅行商从第1个城市出发。
二、算法说明
这里我们尝试用穷举法解决TSP问题。即将每一个城市编号为0~n-1,通过生成随机数种子的方法生成城市之间的代价,调用next_permutation()函数生成城市编号的全排列,然后计算每种排列的代价,选取代价最小的路径输出。
三、源码示例
#include<iostream>
#include<vector>
#include<algorithm>
#include<chrono>
#include<random>
using namespace std;
#define MAX_DOUBLE_NUM 1e20
typedef vector<vector<int>> VVT; //定义代价矩阵的数据结构
unsigned seed1 = std::chrono::high_resolution_clock::now()
.time_since_epoch().count();
std::mt19937 mt(seed1); //生成随机数种子
//城市个数n,代价矩阵c
//旅行路线tpath[],最小费用min
void salesman_problem(int n, double &min, int path[], VVT c) {
int *p=new int [n];
int i = 1;
double cost;
for (i = 0; i < n; i++)
p[i] = i;
min = MAX_DOUBLE_NUM;
for (i = 0; i < n; i++)
for (int j = 0; j < n; j++)
{
c[i][j] = 100 + mt() % 100;
if(i!=j)
cout << i << "城市和" << j << "城市之间的代价:" << c[i][j] << endl;
}
do{
//产生n个城市的全排列
cost = 0;// 最优解路径的代价
for (i = 0; i < n - 1; i++)
cost += c[p[i]][p[i + 1]];
cost += c[p[n - 1]][p[0]];
if (cost < min) {//若当前路径的代价比cost小,保留当前路径并更新cost
for (i = 0; i < n; i++)
path[i] = p[i];
min = cost;
}
} while (next_permutation(p+1, p + n));
}
int main() {
int n,path[100];
double mincost;
VVT c(10, vector<int>(10));
cout << "********************************************************************************" << endl;
cout << "***程序说明:输入城市数目(请尽可能小),程序随机生成城市之间代价并输出最优解***" << endl;
cout << "********************************************************************************" << endl;
cout << "输入城市数目:" << endl;
cin >> n;
salesman_problem(n, mincost, path, c);
cout << "最小代价:"<<mincost << endl;
cout << "最优路径:" << endl;
for (int i = 0; i < n; i++)
cout << path[i] << "-->";
cout << path[0] << endl;
return 0;
}