网上关于IBM的ILOG CPLEX Optimization Studio的使用非常少,给自己的编程带来了不少的麻烦。下面是我用OPL编程语言编写的第一个TSP程序。以TSPlib中gr17.tsp为例。TSP问题中子集的表示比较麻烦,下面nodes2相关的代码段就是用来处理这个子集的。下面的代码第一部分是.mod文件,第二部分是.dat文件。该例子中输出结果是 2085,运行完总用时35秒,具体结果在第三部分代码段。.dat文档中的代码的作用是初始化数据,.mod文档中第一部分的代码是定义相关数据,其中dvar是OPL编程语言中的关键词,表示定义变量。execute代码块的作用是对数据进行预处理,因为数据集中给定的数据是下三角,我这边需要首先把城市之间的距离补全。minimize代码块表示求解的目标函数,subject to的代码段表示约束条件。execute中语法与C语言类似。
/*********************************************
* OPL 12.6.3.0 Model
* Author: ASUS
* Creation Date: 2019-6-21 at 下午5:42:13
*********************************************/
int CityNum = ...;//the number of city
range City =0..CityNum-1;
range SNode =2..CityNum-1;
float distance[City][City]=...;//the distance between city A and city B
dvar boolean visitCity[City][City];//City A to city B or not
{int} nodes ={i|i in City};
range r=1..-2+ftoi(pow(2,card(nodes)));
{int} nodes2[k in r]={i|i in nodes :((k div(ftoi(pow(2,(ord(nodes,i)))))mod 2)==1)};
execute{
for(var c1 in City)
for(var c2 in City)
if(c1
/*********************************************
* OPL 12.6.3.0 Data
* Author: ASUS
* Creation Date: 2019-6-21 at 下午5:42:13
*********************************************/
CityNum=17;
distance=[
[0],
[633,0],
[257,390,0],
[91,661,228,0],
[412,227,169,383,0],
[150,488,112,120,267,0],
[80,572,196,77,351,63,0],
[134,530,154,105,309,34,29,0],
[259,555,372,175,338,264,232,249,0],
[505,289,262,476,196,360,444,402,495,0],
[353,282,110,324,61,208,292,250,352,154,0],
[324,638,437,240,421,329,297,314,95,578,435,0],
[70,567,191,27,346,83,47,68,189,439,287,254,0],
[211,466,74,182,243,105,150,108,326,336,184,391,145,0],
[268,420,53,239,199,123,207,165,383,240,140,448,202,57,0],
[246,745,472,237,528,364,332,349,202,685,542,157,289,426,483,0],
[121,518,142,84,297,35,29,36,236,390,238,301,55,96,153,336,0]];
// solution (optimal) with objective 2085
// Quality Incumbent solution:
// MILP objective 2.0850000000e+003
// MILP solution norm |x| (Total, Max) 1.70000e+001 1.00000e+000
// MILP solution error (Ax=b) (Total, Max) 0.00000e+000 0.00000e+000
// MILP x bound error (Total, Max) 0.00000e+000 0.00000e+000
// MILP x integrality error (Total, Max) 0.00000e+000 0.00000e+000
// MILP slack bound error (Total, Max) 0.00000e+000 0.00000e+000
//
visitCity = [[0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0]
[0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0]
[1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0]
[0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0]
[0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0]
[0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1]
[0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0]
[0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0]];