转载自:分枝定界算法求解TSP

整个程序如下所示:

其中各个模块说明如下:

- Timer:计时用。

- TSPInstanceReader:TSPLIB标准算例读取用。

- PriorityQueue:优先队列。

- Node:搜索树的节点。

- City:保存城市的坐标,名字等。

- BranchBound_TSP:BB算法主程序。

branch and bound 过程

搜索树的节点定义,节点定义了原问题的solution子问题的solutionNode节点定义如下:

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旅行商问题相关推荐

  1. tsp 分支界限 java_干货 | 10分钟教你用branch and bound(分支定界)算法求解TSP旅行商问题...

    在此之前,先给大家讲讲最重要的一个点,搜索树的节点定义,节点定义了原问题的solution和子问题的solution.Node节点定义如下: public class Node {private Ar ...

  2. 分支定界算法理解(摘抄)

    解释一 分支定界算法(Branch and bound,简称为 BB.B&B, or BnB)始终围绕着一颗搜索树进行的. 我们将原问题看作搜索树的根节点.从这里出发,分支的含义就是将大的问题 ...

  3. 分支定界算法在中学排课问题中的应用

    分支定界算法在中学排课问题中的应用 摘要:在本文中我们主要研究了带约束有教案的中学排课程表问题.首先我们得到了有关该问题的中学课程表必须满足的几个条件,因为该排课程表问题是一个NP难解的问题,因此该问 ...

  4. 5.1 基于分支定界算法的单机调度

    原创文章,禁止转载.抄袭或用于报告.交流等学术或商业用途 全文(其它章节内容) https://blog.csdn.net/qq_38757869/article/details/106885769 ...

  5. 人工蜂群算法求解TSP旅行商问题C++(2020.11.13)

    ABC算法求解TSP问题的C++实现 1.输入数据文件:bayg29.tsp 2.头文件 3.所需的类 3.1 城市类City 3.2 包含城市的地图类Graph 3.3 蜜蜂类Bee 3.4 人工蜂 ...

  6. 贪心算法求解 TSP 旅行商问题及其实现

    文章目录 一.TSP 概述 1. TSP 2. 数学模型 3. TSP分类 二.贪心算法 1. 算法思路 2. 算法框架 3. 问题 三.贪心算法求解 TSP 一.TSP 概述 1. TSP 旅行商问 ...

  7. 分支定界算法 matlab,分支定界法----整数规划matlab

    分支定界法的思想是:首先确定目标值的上下界 发布人:chengxu0921 发布时间:2008-7-21 18:16:27 新闻类别:分支-界限法 例1:设有A,B,C,D,E 5人从事j1,j2,j ...

  8. branch and bound(分支定界)算法-基础概念

    网址1:干货 | 10分钟带你全面掌握branch and bound(分支定界)算法-概念篇 网址2:运筹优化学习10:分支定界算法求解整数规划问题及其Matlab实现

  9. branch and bound(分支定界)算法

    最近在看cartographer算法,其中的闭环优化使用到了branch and bound(分支定界)算法,这里简单记录一下: 分支定界算法是一种求解离散最优化问题的计算分析方法.它是由R.J.达金 ...

最新文章

  1. zTree的拖拽排序
  2. SpringMVC 学习-异常处理 SimpleMappingExceptionResolver 类
  3. Scala变量介绍及入门示例
  4. 美国WH在明尼苏达州最大光伏阵列完工
  5. 如何学习HTML语言
  6. VMWare虚拟机下为Windows Server 2012配置静态IP(NAT方式)
  7. SQLServer------存储过程的使用
  8. 4.C++深入理解 面向对象部分3
  9. mysql函数大全之数字函数
  10. Matlab中break语句
  11. linux区别sata和sas,企业级硬盘sata与sas接口区别,该怎么选择
  12. 魔兽各服务器位置,魔兽世界怀旧服矿点分布在哪 全地图采矿位置一览(多图)
  13. 上山的路上,总得给自己一点阳光。
  14. C语言 转义符\t占用几个空格
  15. Pitest内存泄露分析 (工具使用IDEA、Jprofiler)
  16. 计算机技术对艺术的影响,数字化技术对当代艺术发展的影响--理论
  17. 阮一峰:炫耀从来不是我的动机,好奇才是(图灵访谈)
  18. 第十届蓝桥杯省赛原题及参考答案
  19. 30天自制操作系统——第0天
  20. 磁共振t1t2信号记忆顺口溜_学习MRI时,老师都说 T1 看解剖,T2 看病变,T1、T2 是什么意思?大家怎样理解这句话的?...

热门文章

  1. 苹果4s怎么显示无服务器,苹果4s连接电脑没有反应怎么办 苹果4s怎么连接电脑...
  2. Office PIA:关于Office PIA应用程序的部署
  3. 以太坊合并后,矿工们要失业了吗?
  4. c语言班级管理系统需求分析报告,班级管理系统 C语言报告.doc
  5. Linux-查询登入用户信息
  6. 安卓手机阅读器_这可能就是你要找的全功能电子书阅读器
  7. android和java 通过UDP搜索同一局域网内指定网络设备
  8. 猿学~Google I/O 最全记录,看完我们睡不着了!
  9. 复制文件或文件夹时出错---未指定的错误
  10. S7-200 SMART PLC自由口协议与固定式扫码枪通信