一、前言
【旅行商问题】旅行商问题(TravelingSalesmanProblem,TSP)是一个经典的组合优化问题。经典的TSP可以描述为:一个商品推销员要去若干个城市推销商品,该推销员从一个城市出发,需要经过所有城市后,回到出发地。应如何选择行进路线,以使总的行程最短。从图论的角度来看,该问题实质是在一个带权完全无向图中,找一个权值最小的Hamilton回路。由于该问题的可行解是所有顶点的全排列,随着顶点数的增加,会产生组合爆炸,它是一个NP完全问题。由于其在交通运输、电路板线路设计以及物流配送等领域内有着广泛的应用,国内外学者对其进行了大量的研究。早期的研究者使用精确算法求解该问题,常用的方法包括:分枝定界法、线性规划法、动态规划法等。但是,随着问题规模的增大,精确算法将变得无能为力,因此,在后来的研究中,国内外学者重点使用近似算法或启发式算法,主要有遗传算法、模拟退火法、蚁群算法、禁忌搜索算法、贪婪算法和神经网络等。【参考百度百科】。
二、本文概要
本文基于蛮力法(此处采用深度优先遍历,DFS)解决旅行商问题。通过遍历出所有满足条件的路径情况,并保持更新最优解,直到所有情况都遍历完,得到全局最优解。但是,使用蛮力法需要遍历的城市个数高达city_num的阶乘,当city_num=12的时候,需遍历479001600种情况,程序所需时间以小时为单位。
运行结果
代码:
#include <iostream>
#include <cstring>
using namespace std;
const int maxSize = 999;
int arcNum,vertexNum,pathNum,pathIndex = 1,bestLength = maxSize;//pathIndex表示当前已经经过的点数
int vertex[maxSize],visited[maxSize];
int arc[maxSize][maxSize];
int path_DFS[maxSize][maxSize];//存放走过的路径
int length_DFS[maxSize];//存放每条路径对应的长度
void DFS(int index)
{
if(pathIndex == vertexNum&&arc[index][1] != 0)
{
path_DFS[pathNum][pathIndex] = index;//当前到达的点
path_DFS[pathNum][pathIndex + 1] = 1; // 最后一个到达的位置为1号点
length_DFS[pathNum] = 0; // 存储最短路径
//计算最短的路径
for(int i = 1;i <= vertexNum;i++)
{
//当前点到下一个点的距离
length_DFS[pathNum] += arc[path_DFS[pathNum][i]][path_DFS[pathNum][i + 1]];
}
if(bestLength > length_DFS[pathNum])
{
bestLength = length_DFS[pathNum];
}
for(int i = 1;i <= vertexNum + 1;i++)
{
cout << path_DFS[pathNum][i] << " ";
path_DFS[pathNum + 1][i] = path_DFS[pathNum][i];
}
cout << endl << "length"<< length_DFS[pathNum] <<endl;
pathNum++;
return;
}
else
{
for(int i = 1;i <= vertexNum;i++)
{
if(arc[index][i] > 0&&visited[i] == 0)
{
visited[i] = 1;
path_DFS[pathNum][pathIndex] = index;
pathIndex++;
DFS(i);
visited[i] = 0;
pathIndex--;
}
}
}
}
int main()
{
memset(visited,0,sizeof(visited));
cin >> arcNum >> vertexNum;
for(int i = 1;i <= vertexNum;i++)
{
vertex[i] = i;
}
for(int k = 0;k < arcNum;k++)
{
int i,j,weight;
cin >> i >> j >> weight;
arc[i][j] = weight;
arc[j][i] = weight;
}
//一号点已经走过了
visited[1] = 1;
DFS(1);
cout << bestLength << endl;
return 0;
}