Notes on TSP Solvers

旅行商问题求解器.

Data Format

首先要了解Concorde及LKH等求解器支持的实例格式.

Concorde iOS App Help: Example 2: explicit distances给出了一个矩阵输入的例子

.tsp

The TSPLIB format is used in a library of TSP instances maintained at the University of Heidelberg. Concorde interpretes only those TSPLIB files that define sets of nodes in two dimensional space.

– File Formats](https://www.math.uwaterloo.ca/tsp/concorde/gui/hlp/file_formats.htm)

下面举几个例子.

berlinn52.tsp:

1
2
3
4
5
6
7
8
9
10
NAME: berlin52
TYPE: TSP
COMMENT: 52 locations in Berlin (Groetschel)
DIMENSION: 52
EDGE_WEIGHT_TYPE: EUC_2D
NODE_COORD_SECTION
1 565.0 575.0
...
52 1740.0 245.0
EOF

matrix10.tsp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
NAME: matrix10
TYPE: TSP
COMMENT: 10-city explicit problem
DIMENSION: 10
EDGE_WEIGHT_TYPE: EXPLICIT
EDGE_WEIGHT_FORMAT: LOWER_DIAG_ROW
EDGE_WEIGHT_SECTION
0
63 0
25 39 0
19 66 22 0
41 22 16 38 0
15 48 11 12 26 0
80 57 19 77 35 63 0
13 53 15 10 30 34 29 0
25 55 37 17 33 26 23 24 0
50 28 26 47 19 36 44 40 49 0
EOF

.qs

官网没有给出说明, 网上也找不到任何相关的信息, 仅在此回答有提及: How to solve a TSP using Concorde?.

Gurobi

Traveling Salesman Problem - Gurobi: 一个colab示例

tsp.py - Gurobi: 官方求解代码

attention-learn-to-route/problems/tsp/tsp_gurobi.py: Kool对官方代码的修改版

Concorde TSP Solver

jvkersch/pyconcorde

Installation

Windows

1
2
3
git clone https://github.com/jvkersch/pyconcorde
cd pycvoncorde
pip install -e .

ERROR: No matching distribution found for setuptools

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Obtaining file:///D:/mine/Github/pyconcorde
Installing build dependencies ... error
ERROR: Command errored out with exit status 1:
command: 'D:\anaconda3\python.exe' 'D:\anaconda3\lib\site-packages\pip' install --ignore-installed --no-user --prefix 'C:\Users\Carlos\AppData\Local\Temp\pip-build-env-qv02xdei\overlay' --no-warn-script-location --no-binary :none: --only-binary :none: -i https://pypi.org/simple -- setuptools numpy Cython
cwd: None
Complete output (7 lines):
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ProtocolError('Connection aborted.', OSError(0, 'Error'))': /simple/setuptools/
WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ProtocolError('Connection aborted.', OSError(0, 'Error'))': /simple/setuptools/
WARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ProtocolError('Connection aborted.', OSError(0, 'Error'))': /simple/setuptools/
WARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ProtocolError('Connection aborted.', OSError(0, 'Error'))': /simple/setuptools/
WARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ProtocolError('Connection aborted.', OSError(0, 'Error'))': /simple/setuptools/
ERROR: Could not find a version that satisfies the requirement setuptools
ERROR: No matching distribution found for setuptools
----------------------------------------
WARNING: Discarding file:///D:/mine/Github/pyconcorde. Command errored out with exit status 1: 'D:\anaconda3\python.exe' 'D:\anaconda3\lib\site-packages\pip' install --ignore-installed --no-user --prefix 'C:\Users\Carlos\AppData\Local\Temp\pip-build-env-qv02xdei\overlay' --no-warn-script-location --no-binary :none: --only-binary :none: -i https://pypi.org/simple -- setuptools numpy Cython Check the logs for full command output.
ERROR: Command errored out with exit status 1: 'D:\anaconda3\python.exe' 'D:\anaconda3\lib\site-packages\pip' install --ignore-installed --no-user --prefix g'm'C:\Users\Carlos\AppData\Local\Temp\pip-build-env-qv02xdei\overlay' --no-warn-script-location --no-binary :none: --only-binary :none: -i https://pypi.org/simple -- setuptools numpy Cython Check the logs for full command output.

更新setuptools, cython, numpy后报错:

qsopt is missing,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
Obtaining file:///D:/mine/Github/pyconcorde
Installing build dependencies ... done
WARNING: Missing build requirements in pyproject.toml for file:///D:/mine/Github/pyconcorde.
WARNING: The project does not specify a build backend, and pip cannot fall back to setuptools without 'wheel'.
Getting requirements to build wheel ... done
Installing backend dependencies ... done
Preparing wheel metadata ... done
Requirement already satisfied: numpy>=1.10.0 in d:\anaconda3\lib\site-packages (from pyconcorde==0.1.0) (1.22.2)
Requirement already satisfied: cython>=0.22.0 in d:\anaconda3\lib\site-packages (from pyconcorde==0.1.0) (0.29.27)
Installing collected packages: pyconcorde
Running setup.py develop for pyconcorde
ERROR: Command errored out with exit status 1:
command: 'D:\anaconda3\python.exe' -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'D:\\mine\\Github\\pyconcorde\\setup.py'"'"'; __file__='"'"'D:\\mine\\Github\\pyconcorde\\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' develop --no-deps
cwd: D:\mine\Github\pyconcorde\
Complete output (44 lines):
running develop
running egg_info
writing pyconcorde.egg-info\PKG-INFO
writing dependency_links to pyconcorde.egg-info\dependency_links.txt
writing requirements to pyconcorde.egg-info\requires.txt
writing top-level names to pyconcorde.egg-info\top_level.txt
reading manifest file 'pyconcorde.egg-info\SOURCES.txt'
reading manifest template 'MANIFEST.in'
adding license file 'COPYING'
running build_ext
C:\Users\Carlos\AppData\Local\Temp\pip-build-env-84ozjlf8\overlay\Lib\site-packages\setuptools\command\easy_install.py:158: EasyInstallDeprecationWarning: easy_install command is deprecated. Use build and pip and other standards-based tools.
warnings.warn(
C:\Users\Carlos\AppData\Local\Temp\pip-build-env-84ozjlf8\overlay\Lib\site-packages\setuptools\command\install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.
warnings.warn(
C:\Users\Carlos\AppData\Local\Temp\pip-build-env-84ozjlf8\overlay\Lib\site-packages\pkg_resources\__init__.py:122: PkgResourcesDeprecationWarning: 4.0.0-unsupported is an invalid version and will not be supported in a future release
warnings.warn(
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "D:\mine\Github\pyconcorde\setup.py", line 143, in <module>
setup(
File "C:\Users\Carlos\AppData\Local\Temp\pip-build-env-84ozjlf8\overlay\Lib\site-packages\setuptools\__init__.py", line 155, in setup
return distutils.core.setup(**attrs)
File "C:\Users\Carlos\AppData\Local\Temp\pip-build-env-84ozjlf8\overlay\Lib\site-packages\setuptools\_distutils\core.py", line 148, in setup
return run_commands(dist)
File "C:\Users\Carlos\AppData\Local\Temp\pip-build-env-84ozjlf8\overlay\Lib\site-packages\setuptools\_distutils\core.py", line 163, in run_commands
dist.run_commands()
File "C:\Users\Carlos\AppData\Local\Temp\pip-build-env-84ozjlf8\overlay\Lib\site-packages\setuptools\_distutils\dist.py", line 967, in run_commands
self.run_command(cmd)
File "C:\Users\Carlos\AppData\Local\Temp\pip-build-env-84ozjlf8\overlay\Lib\site-packages\setuptools\_distutils\dist.py", line 986, in run_command
cmd_obj.run()
File "C:\Users\Carlos\AppData\Local\Temp\pip-build-env-84ozjlf8\overlay\Lib\site-packages\setuptools\command\develop.py", line 34, in run
self.install_for_development()
File "C:\Users\Carlos\AppData\Local\Temp\pip-build-env-84ozjlf8\overlay\Lib\site-packages\setuptools\command\develop.py", line 114, in install_for_development
self.run_command('build_ext')
File "C:\Users\Carlos\AppData\Local\Temp\pip-build-env-84ozjlf8\overlay\Lib\site-packages\setuptools\_distutils\cmd.py", line 313, in run_command
self.distribution.run_command(command)
File "C:\Users\Carlos\AppData\Local\Temp\pip-build-env-84ozjlf8\overlay\Lib\site-packages\setuptools\_distutils\dist.py", line 986, in run_command
cmd_obj.run()
File "D:\mine\Github\pyconcorde\setup.py", line 114, in run
download_concorde_qsopt()
File "D:\mine\Github\pyconcorde\setup.py", line 66, in download_concorde_qsopt
qsopt_a_url, qsopt_h_url = QSOPT_LOCATION[platform.system()]
KeyError: 'Windows'
qsopt is missing, downloading
----------------------------------------
ERROR: Command errored out with exit status 1: 'D:\anaconda3\python.exe' -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'D:\\mine\\Github\\pyconcorde\\setup.py'"'"'; __file__='"'"'D:\\mine\\Github\\pyconcorde\\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' develop --no-deps Check the logs for full command output.

疑似线性规划求解器自动安装失败, Concorde Download Information手动下载并安装, 发生报错: 缺少cygwin1.dll.

安装Cygwin, 并在环境变量中添加C:\cygwin64\bin, 见HOWTO install Cygwin, 发生报错: 应用程序无法正常启动(0xc000007b).

注意到Concorde Download Information

The Windows/Cygwin codes will run under Windows 98/ME/NT/2000/XP if at least the minimal version of the Cygwin environment is installed.

以及The application was unable to start correctly (0xc000007b)

Which is a good indication that the 32-bit app tried to load a 64-bit DLL. – Remy Lebeau

意识到应该装32位版本的Cygwin, 下载安装后环境变量修改为C:\cygwin\bin, 之后运行.exe后跳了个命令行就结束了.

换个思路, 参考pytspWiki文档按照Instructions for installing Concorde安装Concorde, 无法configuremake, 于是按照SETUP / INSTALL安装Chocolatey, 之后choco install make, 仍然无法make, 这个文档应该不适用于Windows.

Ubuntu on Windows

官方安装一步解决~

1
2
3
git clone https://github.com/jvkersch/pyconcorde
cd pycvoncorde
pip install -e .
  • 目前不支持输入距离矩阵求解, 需要官方安装求解器后重新安装包, 具体见Can I solve a TSP problem with this solver using a distance matrix instead of inputing the latitude and longitude nodes? #28.
  • 对坐标点是有要求的, 见Issues with coordinates < 1, Issue with big coordinates.

Concorde TSP Solver

Concorde README and Installation guide: 安装时函数如configure的参数说明

Download Information : 不同平台和版本的下载地址

concorde: strange warning #42: 一个老哥非常详细的安装过程, 他在macOS失败了, 在Linux成功了

Installation

Ubuntu on Windows

参照How to install Concorde in Ubuntu 14.04 LTS?, 运行如下命令:

1
2
3
4
5
wget http://www.math.uwaterloo.ca/tsp/concorde/downloads/codes/src/co031219.tgz
tar xf co031219.tgz
cd concorde
./configure
make

之后运行~/src/concorde/TSP/concorde -s 99 -k 100测试, 发现如评论所述报错, 且参考How to install Concorde in Ubuntu 14.04 LTS?安装qsopt后依然报错:

1
2
3
4
5
6
7
8
9
10
11
/home/carlos/concorde/TSP/concorde -s99 -k 100
Host: DESKTOP-R4H3HQA Current process id: 8201
Using random seed 99
Random 100 point set
XSet initial upperbound to 780 (from tour)
need to link an lp solver to use this function
CClp_create_info failed
need to link an lp solver to use this function
CCtsp_read_probfile or first_lp failed
need to link an lp solver to use this function
CCtsp_init_lp failed</pre>

按照concorde: strange warning #42在Linux的装法重新安装:

1
2
3
4
5
6
gunzip co031219.tgz
tar xvf co031219.tar
mkdir concorde_build
cd concorde_build
../concorde/configure --with-qsopt=<FULL (non-recursive) PATH TO QSOPT>
make

试了三个qsopt版本, 安装后没有./TSP/concorde, 猜测可能是版本不对应的问题.

额外试了--with-cplex, 然而出现了libcplex.acplex.h不在同一个目录的情况, 不知道怎么搞.

GUI for Windows

下载并安装concorde1.1.exe, 然而似乎只能求解欧氏空间的问题, 输入一个如下的.qs文件后程序自动关闭了.

1
2
3
4
5
6
7
4 6
1 2 5
1 3 5
2 3 5
1 4 0
2 4 0
3 4 0

事实证明该版本不能求解非欧氏空间的问题, 输入EDGE_WEIGHT_FORMATLOWER_DIAG_ROW.tsp示例后报错: File Format Error: Can't read Explicit Lengths norm.

🌟 alberto-santini/concorde-easy-build

Ubuntu下安装成功! 😁

1
2
3
4
5
git clone git@github.com:alberto-santini/concorde-easy-build.git
cd concorde-easy-build/
cmake -DCMAKE_BUILD_TYPE=Release -DCPLEX_ROOT_DIR=/opt/ibm/ILOG/CPLEX_Studio221/
make -j5
./concorde-bin -s 99 -k 100 -o test.txt

输出如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Host: DESKTOP-R4H3HQA  Current process id: 3375
Using random seed 99
Random 100 point set
XSet initial upperbound to 780 (from tour)
LP Value 1: 738.500000 (0.00 seconds)
LP Value 2: 768.642857 (0.01 seconds)
LP Value 3: 774.000000 (0.03 seconds)
LP Value 4: 775.097826 (0.03 seconds)
LP Value 5: 777.718750 (0.06 seconds)
LP Value 6: 779.000000 (0.08 seconds)
LP Value 7: 780.000000 (0.11 seconds)
New lower bound: 780.000000
Final lower bound 780.000000, upper bound 780.000000
Exact lower bound: 780.000000
DIFF: 0.000000
Final LP has 187 rows, 313 columns, 2352 nonzeros
Optimal Solution: 780.00
Number of bbnodes: 1
Total Running Time: 0.15 (seconds)

Troubleshooting

解一个大小为1001的问题时报错:"CPXdualopt" failed, return code 1016, 随后wsl.exe --shutdown会死机: 这是因为CPLEX社区版有1000的变量和约束限制

Lin–Kernighan heuristic

LKH (Keld Helsgaun) - Parent Directory: 官方网站, 包含论文若干

LKH User Guide

Windows

下载LKH-2.exe后打开, 默认PARAMETER_FILE为空, 然后在PROBLEM_FILE输入实例的绝对路径, 支持格式如.tsp等, 可以求解EDGE_WEIGHT_FORMATLOWER_DIAG_ROW的实例.