branch and bound(分支定界)算法求解TSP旅行商问题
转载自:分枝定界算法求解TSP
整个程序如下所示:
其中各个模块说明如下:
- Timer:计时用。
- TSPInstanceReader:TSPLIB标准算例读取用。
- PriorityQueue:优先队列。
- Node:搜索树的节点。
- City:保存城市的坐标,名字等。
- BranchBound_TSP:BB算法主程序。
branch and bound 过程
搜索树的节点定义,节点定义了原问题的solution和子问题的solution。Node节点定义如下:
public class Node {
private ArrayList<Integer> path;
private double bound;
private int level;
public double computeLength(double[][] distanceMatrix) {
// TODO Auto-generated method stub
double distance = 0;
for(int i=0;i<this.getPath().size()-1;i++){
distance = distance + distanceMatrix[this.getPath().get(i)][this.getPath().get(i+1)];
}
return distance;
}
其余不重要的接口略过。如下:
- path:保存该节点目前已经走过的城市序列。
- bound:记录该节点目前所能达到的最低distance。
- level:记录节点处于搜索树的第几层。
- computeLength:记录当前城市序列的distance。
可能大家还没理解节点是如何分支的,看一张图大家就懂了。我们知道TSP问题的一个solution是能用一个序列表示城市的先后访问顺序,比如现在有4座城市(1,2,3,4):
图中每个节点的数字序列就是path保存的。大家都看到了吧,其实分支就是一个穷枚举的过程。
相对于穷举,分支定界算法的优越之处就在于其加入了定界过程,在分支的过程中就砍掉了某些不可能的支,减少了枚举的次数,大大提高了算法的效率。如下:
分支定界算法的主过程如下:
private static void solveTSP(double[][] distanceMatrix) {int totalCities = distanceMatrix.length;ArrayList<Integer> cities = new ArrayList<Integer>();for (int i = 0; i < totalCities; i++) {cities.add(i);}ArrayList<Integer> path;double initB = initbound(totalCities, distanceMatrix);Node v = new Node(new ArrayList<>(), 0, initB, 0);queue.add(v);queueCount++;while (!queue.isEmpty()) {v = queue.remove();if (v.getBound() < shortestDistance) {Node u = new Node();u.setLevel(v.getLevel() + 1);for (int i = 1; i < totalCities; i++) {path = v.getPath();if (!path.contains(i)) {u.setPath(v.getPath());path = u.getPath();path.add(i);u.setPath(path);if (u.getLevel() == totalCities - 2) {// put index of only vertex not in u.path at the end// of u.pathfor (int j = 1; j < cities.size(); j++) {if (!u.getPath().contains(j)) {ArrayList<Integer> temp = new ArrayList<>();temp = u.getPath();temp.add(j);u.setPath(temp);}}path = u.getPath();path.add(0);u.setPath(path);if (u.computeLength(distanceMatrix) < shortestDistance) {shortestDistance = u.computeLength(distanceMatrix);// implementshortestPath = u.getPath();}} else {u.setBound(computeBound(u, distanceMatrix, cities));//u.getBound()获得的是不完整的解,如果一个不完整的解bound都大于当前最优解,那么完整的解肯定会更大,那就没法玩了。//所以这里只要u.getBound() < shortestDistance的分支if (u.getBound() < shortestDistance) {queue.add(u);queueCount++;}else {System.out.println("currentBest = "+shortestDistance+" cut bound >>> "+u.getBound());}}}}}}}
1. 首先initbound利用贪心的方式获得一个bound,作为初始解。
2. 而后利用优先队列遍历搜索树,进行branch and bound算法。对于队列里面的任意一个节点,只有(v.getBound() < shortestDistance)条件成立我们才有分支的必要。不然将该支砍掉。
3. 分支以后判断该支是否到达最底层,这样意味着我们获得了一个完整的解。那么此时就可以更新当前的最优解了。
4. 如果没有到达最底层,则对该支进行定界操作。如果该支的bound也比当前最优解还要大,那么也要砍掉的
然后讲讲定界过程,TSP问题是如何定界的呢?
private static double computeBound(Node u, double[][] distanceMatrix, ArrayList<Integer> cities) {double bound = 0;ArrayList<Integer> path = u.getPath();for (int i = 0; i < path.size() - 1; i++) {bound = bound + distanceMatrix[path.get(i)][path.get(i + 1)];}int last = path.get(path.size() - 1);List<Integer> subPath1 = path.subList(1, path.size());double min;//回来的for (int i = 0; i < cities.size(); i++) {min = Integer.MAX_VALUE;if (!path.contains(cities.get(i))) {for (int j = 0; j < cities.size(); j++) {if (i != j && !subPath1.contains(cities.get(j))) {if (min > distanceMatrix[i][j]) {min = distanceMatrix[i][j];}}}}if (min != Integer.MAX_VALUE)bound = bound + min;}//出去的min = Integer.MAX_VALUE;for (int i = 0; i < cities.size(); i++) {if (/*cities.get(i) != last && */!path.contains(i) && min > distanceMatrix[last][i]) {min = distanceMatrix[last][i];}}bound = bound + min;//System.out.println("bound = "+bound);return bound;}
我们知道,每个节点保存的城市序列可能不是完整的解。bound的计算方式:bound = 当前节点path序列的路径距离 + 访问下一个城市的最短路径距离 + 从下一个城市到下下城市(有可能是起点)的最短路径距离。
比如城市节点5个{1,2,3,4,5}。当前path = {1,2},那么:
- 当前节点path序列的路径距离 = d12
- 访问下一个城市的最短路径距离 = min (d2i), i in {3,4,5} (与下一站相关)
- 从下一个城市到下下城市(有可能是起点)的最短路径距离=min (dij), i in {3,4,5} , j in {3,4,5,1}, i != j 。 (与剩余站有关)
注意这两个是可以不相等的。
3、运行说明
目前分支定界算法解不了大规模的TSP问题,10个节点以内吧差不多。input里面有算例,可以更改里面的DIMENSION值告诉算法需要读入几个节点。
更改算例在main函数下面,改名字就行,记得加上后缀。
branch and bound(分支定界)算法求解TSP旅行商问题相关推荐
- tsp 分支界限 java_干货 | 10分钟教你用branch and bound(分支定界)算法求解TSP旅行商问题...
在此之前,先给大家讲讲最重要的一个点,搜索树的节点定义,节点定义了原问题的solution和子问题的solution.Node节点定义如下: public class Node {private Ar ...
- 分支定界算法理解(摘抄)
解释一 分支定界算法(Branch and bound,简称为 BB.B&B, or BnB)始终围绕着一颗搜索树进行的. 我们将原问题看作搜索树的根节点.从这里出发,分支的含义就是将大的问题 ...
- 分支定界算法在中学排课问题中的应用
分支定界算法在中学排课问题中的应用 摘要:在本文中我们主要研究了带约束有教案的中学排课程表问题.首先我们得到了有关该问题的中学课程表必须满足的几个条件,因为该排课程表问题是一个NP难解的问题,因此该问 ...
- 5.1 基于分支定界算法的单机调度
原创文章,禁止转载.抄袭或用于报告.交流等学术或商业用途 全文(其它章节内容) https://blog.csdn.net/qq_38757869/article/details/106885769 ...
- 人工蜂群算法求解TSP旅行商问题C++(2020.11.13)
ABC算法求解TSP问题的C++实现 1.输入数据文件:bayg29.tsp 2.头文件 3.所需的类 3.1 城市类City 3.2 包含城市的地图类Graph 3.3 蜜蜂类Bee 3.4 人工蜂 ...
- 贪心算法求解 TSP 旅行商问题及其实现
文章目录 一.TSP 概述 1. TSP 2. 数学模型 3. TSP分类 二.贪心算法 1. 算法思路 2. 算法框架 3. 问题 三.贪心算法求解 TSP 一.TSP 概述 1. TSP 旅行商问 ...
- 分支定界算法 matlab,分支定界法----整数规划matlab
分支定界法的思想是:首先确定目标值的上下界 发布人:chengxu0921 发布时间:2008-7-21 18:16:27 新闻类别:分支-界限法 例1:设有A,B,C,D,E 5人从事j1,j2,j ...
- branch and bound(分支定界)算法-基础概念
网址1:干货 | 10分钟带你全面掌握branch and bound(分支定界)算法-概念篇 网址2:运筹优化学习10:分支定界算法求解整数规划问题及其Matlab实现
- branch and bound(分支定界)算法
最近在看cartographer算法,其中的闭环优化使用到了branch and bound(分支定界)算法,这里简单记录一下: 分支定界算法是一种求解离散最优化问题的计算分析方法.它是由R.J.达金 ...
最新文章
- zTree的拖拽排序
- SpringMVC 学习-异常处理 SimpleMappingExceptionResolver 类
- Scala变量介绍及入门示例
- 美国WH在明尼苏达州最大光伏阵列完工
- 如何学习HTML语言
- VMWare虚拟机下为Windows Server 2012配置静态IP(NAT方式)
- SQLServer------存储过程的使用
- 4.C++深入理解 面向对象部分3
- mysql函数大全之数字函数
- Matlab中break语句
- linux区别sata和sas,企业级硬盘sata与sas接口区别,该怎么选择
- 魔兽各服务器位置,魔兽世界怀旧服矿点分布在哪 全地图采矿位置一览(多图)
- 上山的路上,总得给自己一点阳光。
- C语言 转义符\t占用几个空格
- Pitest内存泄露分析 (工具使用IDEA、Jprofiler)
- 计算机技术对艺术的影响,数字化技术对当代艺术发展的影响--理论
- 阮一峰:炫耀从来不是我的动机,好奇才是(图灵访谈)
- 第十届蓝桥杯省赛原题及参考答案
- 30天自制操作系统——第0天
- 磁共振t1t2信号记忆顺口溜_学习MRI时,老师都说 T1 看解剖,T2 看病变,T1、T2 是什么意思?大家怎样理解这句话的?...
热门文章
- 苹果4s怎么显示无服务器,苹果4s连接电脑没有反应怎么办 苹果4s怎么连接电脑...
- Office PIA:关于Office PIA应用程序的部署
- 以太坊合并后,矿工们要失业了吗?
- c语言班级管理系统需求分析报告,班级管理系统 C语言报告.doc
- Linux-查询登入用户信息
- 安卓手机阅读器_这可能就是你要找的全功能电子书阅读器
- android和java 通过UDP搜索同一局域网内指定网络设备
- 猿学~Google I/O 最全记录,看完我们睡不着了!
- 复制文件或文件夹时出错---未指定的错误
- S7-200 SMART PLC自由口协议与固定式扫码枪通信