【分支限界法】求解TSP问题

问题描述

TSP问题是指旅行家要旅行n个城市,要求各个城市经历且仅经历一次然后回到出发城市,并要求所走的路程最短。
在这里插入图片描述

求解思路

  采用贪心法求得近似解为1→3→5→4→2→1,其路径长度为1+2+3+7+3=16,这可以作为TSP问题的上界。
  把矩阵中每一行最小的元素相加,可以得到一个简单的下界,其路径长度为1+3+1+3+2=10,但是还有一个信息量更大的下界:考虑一个TSP问题的完整解,在每条路径上,每个城市都有两条邻接边,一条是进入这个城市的,另一条是离开这个城市的,那么,如果把矩阵中每一行最小的两个元素相加再除以2,如果图中所有的代价都是整数,再对这个结果向上取整,就得到了一个合理的下界。
  lb=((1+3)+(3+6)+(1+2)+(3+4)+(2+3))/2=14
  于是,得到了目标函数的界[14, 16]。
  需要强调的是,这个解并不是一个合法的选择(可能没有构成哈密顿回路),它仅仅给出了一个参考下界。
部分解的目标函数值的计算方法
  例如图所示无向图,如果部分解包含边(1, 3,5),则该部分解的下界是lb=(2*(1+2)+3+3+(3+6)+(3+4))/2=14。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
  应用分支限界法求解图9.4所示无向图的TSP问题,其搜索空间如图9.5所示,具体的搜索过程如下(加黑表示该路径上已经确定的边):
(1)在根结点1,根据限界函数计算目标函数的值为lb=((1+3)+(3+6)+(1+2)+(3+4)+(2+3))/2=14;
(2)在结点2,从城市1到城市2,路径长度为3,目标函数的值为(23)+1+6+(1+2)+(3+4)+(2+3))/2=14,将结点2加入待处理结点表PT中;在结点3,从城市1到城市3,路径长度为1,目标函数的值为(21+1+1+(3+6)+(3+4)+(2+3))/2=14,将结点3加入表PT中;在结点4,从城市1到城市4,路径长度为5,目标函数的值为((2*5)+1+3+(3+6)+(1+2)+(2+3))/2=16,将结点4加入表PT中;在结点5,从城市1到城市5,路径长度为8,目标函数的值为((1+8)+(3+6)+(1+2)+(3+5)+(2+8))/2=19,超出目标函数的界,将结点5丢弃;
(3)在表PT中选取目标函数值极小的结点2优先进行搜索;
(4)在结点6,从城市2到城市3,目标函数值为((1+3)+(3+6)+(1+6)+(3+4)+(2+3))/2=16,将结点6加入表PT中;在结点7,从城市2到城市4,目标函数值为((1+3)+(3+7)+(1+2)+(3+7)+(2+3))/2=16,将结点7加入表PT中;在结点8,从城市2到城市5,目标函数值为
((1+3)+(3+9)+(1+2)+(3+4)+(2+9))/2=19,超出目标函数的界,将结点8丢弃;
(5)在表PT中选取目标函数值极小的结点3优先进行搜索;
(6)在结点9,从城市3到城市2,目标函数值为((1+3)+(3+6)+(1+6)+(3+4)+(2+3))/2=16,将结点9加入表PT中;在结点10,从城市3到城市4,目标函数值为((1+3)+(3+6)+(1+4)+(3+4)+(2+3))/2=15,将结点10加入表PT中;在结点11,从城市3到城市5,目标函数值为((1+3)+(3+6)+(1+2)+(3+4)+(2+3))/2=14,将结点11加入表PT中;
(7)在表PT中选取目标函数值极小的结点11优先进行搜索;
(8)在结点12,从城市5到城市2,目标函数值为((1+3)+(3+9)+(1+2)+(3+4)+(2+9))/2=19,超出目标函数的界,将结点12丢弃;在结点13,从城市5到城市4,目标函数值为((1+3)+(3+6)+(1+2)+(3+4)+(2+3))/2=14,将结点13
加入表PT中;
(9)在表PT中选取目标函数值极小的结点13优先进行搜索;
(10)在结点14,从城市4到城市2,目标函数值为((1+3)+(3+7)+(1+2)+(3+7)+(2+3))/2=16,最后从城市2回到城市1,目标函数值为((1+3)+(3+7)+(1+2)+(3+7)+(2+3))/2=16,由于结点14为叶子结点,得到一个可行解,其路径长度为16;
(11)在表PT中选取目标函数值极小的结点10优先进行搜索;
(12)在结点15,从城市4到城市2,目标函数的值为((1+3)+(3+7)+(1+4)+(7+4)+(2+3))/2=18,超出目标函数的界,将结点15丢弃;在结点16,从城市4到城市5,目标函数值为((1+3)+(3+6)+(1+4)+(3+4)+(2+3))/2=15,将结点16加入表PT中;
(13)在表PT中选取目标函数值极小的结点16优先进行搜索;
(14)在结点17,从城市5到城市2,目标函数的值为((1+3)+(3+9)+(1+4)+(3+4)+(9+3))/2=20,超出目标函数的界,将结点17丢弃;
(15)表PT中目标函数值均为16,且有一个是叶子结点14,所以,结点14对应的解1→3→5→4→2→1 即是TSP问题的最优解,搜索过程结束。
在这里插入图片描述在这里插入图片描述

代码实现

/*分支限界法求解TSP问题
*/
#include<iostream>
#include<algorithm>
#include<queue>
#define MAXLENGTH 10
using namespace std;

//城市个数
int n;
//城市距离代价矩阵
int value[MAXLENGTH][MAXLENGTH];
//定义访问标识符
bool dfs_visited[MAXLENGTH];
//定义函数上界
int up;
//定义下界
int down;
//距离修正函数声明
void Modify();
//分支限界法求解TSP问题
int solve();
//贪心法计算上界
void get_up();
//计算下界
void get_down();
//贪心算法
int dfs(int, int, int);
//待处理节点表
struct  Node
{
   
	//节点访问标记
	bool visited[MAXLENGTH];
	//访问次序
	int cixu[MAXLENGTH];
	//第一个点
	int start;
	//第一个节点的邻接节点
	int start_p;
	//最后一个节点
	int end;
	//最后一个节点的邻接节点
	int end_p;
	//走过的点数
	int k;
	//经过路径的距离
	int sumv;
	//目标函数值
	int lb;
	//运算符重载
	//目标函数值小的先出队列
	bool operator <(const Node &p) 
  • 53
    点赞
  • 316
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值