旅行商问题(C++)
运用优先队列分支限界法
-
问题描述
旅行商问题(Traveling Salesman Problem,TSP)又译为旅行推销员问题、货郎担问题,简称为TSP问题,是最基本的路线问题,该推销员从一个城市出发,需要求得经过所有城市后,回到出发地的最小路径成本。 -
该问题的实质是从图论的角度来看,该问题实质是在一个带权完全无向图中,找一个权值最小的哈密顿回路。
-
解决方法
分支限界法:利用贪心方法求得上界,,优先队列式分支限界法用优先队列存储活结点表 -
算法分析
-对于TSP(旅行商问题),我们需要利用上界和下界来对BFS(解空间树)进行剪枝,通过不断更新上界和下界,尽可能的排除不符合需求的child(子树),以实现剪枝。最终,当上限和下限等同时,我们可以获得最优解,以解决TSP问题 -
解题步骤
定义队列的优先级。 以zl为优先级,zl值越小,越优先
计算下界(即每个景点最小出边权值之和)
利用优先队列分支限界法,不断更新上界和路径和,如果大于上界就不加入队列,否则加入队列求出最优解。
部分代码如下:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
#include<time.h>
using namespace std;
const int INF=1e7; //设置无穷大的值为107
const int N=100;
double g[N][N]; //旅行地图邻接矩阵战争
double minout[N]; //记录每个城市的最少出边
double minsum; //记录所有城市的最少出边之和
int bestx[N]; //记录当前最优路径
double bestl; //当前最优路径长度
int n,m; //城市个数n,边数m
struct Node//定义结点,记录当前结点的解信息
{
double cl; //当前已走过的路径长度
double rl; //剩余路径长度的下界
double zl; //当前路径长度的下界zl=rl+cl
int id; //城市序号
int x[N];//记录当前解向量
Node() {
}
Node(double _cl,double _rl,double _zl,int _id)
{
cl = _cl;
rl = _rl;
zl = _zl;
id = _id;
}
};
//定义队列的优先级。 以zl为优先级,zl值越小,越优先
bool operator <(const Node &a, const Node &b)
{
return a.zl>b.zl;
}
bool Bound()//计算下界(即每个城市最小出边权值之和)
{
for(int i=1