今天老板安排了一个任务,让自己建立一个最经典的CVRP模型,然后用LINGO把建立的模型给求解出来;LINGO只是听说过,从来没有真正使用过,运筹学课程也是混着过来的,怎么办?硬着头皮上呗。
两种编程方法:使用集合语言编程和不使用集合语言编程(笨办法编程)
1 Lingo编程基础
1.1基本思路
- 确保模型是对的,每个变量均进行了严格的定义;
- 明确已知数据、模型的类型(线性模型、非线性模型)
- 确定指标集(即每个变量的变化范围)
- 确定变量依赖的指标集
- 正确写出代码式子
1.2 建模思路
1.3 注意事项
目标函数:min或max
基本语法:
普通代码行,以分号为一行代码的结束;代码注释行,以叹号开始分号结束
空格和回车字符会被忽略掉
变量名以字母开头,不区分大小写;
没有严格大于或严格等于的约束
2 整数规划模型求解示例(不使用集合语言)
2.1 问题模型
2.2 lingo源代码:
max = 4*x1 + 3*x2; 2 * x1 + x2 <= 10; x1 + x2 <= 8; x2 <= 7; @gin(x1); @gin(x2);
2.3 结果展示
得到全局最优解,目标函数值为26
解报告中显示:x1 = 2; x2 = 6
2.4 小结
- 每行源代码都是以 【;】 结束的;
- 可以通过空格增强代码的易读性;
- 乘号不能省略
- lingo不区分大小写
- 默认变量为非负变量
- 注释代码以【!】开头,以【;】结尾
- @开头的表示函数,常用的几个指令如下表所示
要求x取值范围为[-5,5]的实数的编码方式为:
1. @free(x); !规定x为任意实数 2. @bnd(-5,x,5); !规定x的范围 3. @gin(x); !限定为整数
3 一个稍大规模的问题求解
3.1 问题描述
3.2 模型建立
3.3 模型分析
(1)确定模型的已知变量和未知变量:模型中除了剩余的变量都是已知变量
(2)确定指标集:;对应的lingo代码为:
3.3.1 定义集合段:使用【sets:】开始,【endsets】结束
!使用集合表示; sets: S/1..6/: a, b, d; !变量a_{i}, b_{i}, d_{i}; T/1,2/: e, x; !变量e_{j}, x_{j}; U(S,T): ; !双下标的集合c_{ij}; endsets
3.3.2 定义数据段:使用【data:】开始,【enddata】结束
!定义数据段; DATA: a = 1.25 8.75 0.5 5.75 3 7.25; B = 1.25 0.75 4.75 5 6.5; D = 3 5 4 7 6 11; ENDDATA
3.3.3 目标函数的代码
编码该公式的Latex代码:min \sum_{j=1}^{2}\sum_{i=1}^{6}c_{ij}\sqrt { (x_j - a_j)^2 +(y_{i} - b_{i} )^2}
编码该公式的Lingo代码:
min = @sum(T(j) : @sum(S(i) : c(i,j) * @sqrt((x(j)- a(j))^2 + (x(i) - y(i))^2) ) ); !代码注释: j \in T i \in S 调用函数:@sqrt求平方根,@sum求和;
3.3.4 约束条件代码实现
编码该公式的Latex代码:\sum_{j=1}^2 c_{ij} = d_i; i = 1,2,..,6
编码该公式的Lingo代码:
@for (S(i) : @sum(T(j) : c(i,j) = d(i)); !代码注释: i \in S j \in T;
编码该公示的Latex代码:\sum_{i=1}^{6} c_{ij} \leq e_{j}; j = 1,2
编码该约束的Lingo代码:
@for (T(j) : \sum(S(i) : c(i,j) <= e(j) ));
3.3.5 完整代码
!使用集合表示; sets: S/1..6/: a, b, d; !变量a_{i}, b_{i}, d_{i}; T/1,2/: e, x, y; !变量e_{j}, x_{j}, y_{j}; U(S,T): c ; !双下标的集合c_{ij}; endsets !定义数据段; DATA: a = 1.25 8.75 0.5 5.75 3 7.25; B = 1.25 0.75 4.75 5 6.5 7.75; D = 3 5 4 7 6 11; x = 5 2; y = 1 7; ENDDATA min = @sum(T(j) : @sum(S(i) : c(i,j) * @sqrt((x(j) - a(i))^2 + (y(j) - b(i))^2))); @for(S(i) : @sum(T(j): c(i,j)) = d(i)); @for(T(j) : @sum(S(i) : c(i,j)) <= e(j));
3.3.6 结果演示
Global optimal solution found. Objective value: 134.4157 Infeasibilities: 0.000000 Total solver iterations: 0 Variable Value Reduced Cost A( 1) 1.250000 0.000000 A( 2) 8.750000 0.000000 A( 3) 0.5000000 0.000000 A( 4) 5.750000 0.000000 A( 5) 3.000000 0.000000 A( 6) 7.250000 0.000000 B( 1) 1.250000 0.000000 B( 2) 0.7500000 0.000000 B( 3) 4.750000 0.000000 B( 4) 5.000000 0.000000 B( 5) 6.500000 0.000000 B( 6) 7.750000 0.000000 D( 1) 3.000000 0.000000 D( 2) 5.000000 0.000000 D( 3) 4.000000 0.000000 D( 4) 7.000000 0.000000 D( 5) 6.000000 0.000000 D( 6) 11.00000 0.000000 E( 1) 15.00000 0.000000 E( 2) 21.00000 0.000000 X( 1) 5.000000 0.000000 X( 2) 2.000000 0.000000 Y( 1) 1.000000 0.000000 Y( 2) 7.000000 0.000000 C( 1, 1) 3.000000 0.000000 C( 1, 2) 0.000000 2.040383 C( 2, 1) 5.000000 0.000000 C( 2, 2) 0.000000 5.440861 C( 3, 1) 0.000000 3.153524 C( 3, 2) 4.000000 0.000000 C( 4, 1) 7.000000 0.000000 C( 4, 2) 0.000000 0.1802949 C( 5, 1) 0.000000 4.734316 C( 5, 2) 6.000000 0.000000 C( 6, 1) 0.000000 1.811824 C( 6, 2) 11.00000 0.000000 Row Slack or Surplus Dual Price 1 134.4157 -1.000000 2 0.000000 -3.758324 3 0.000000 -3.758324 4 0.000000 -2.704163 5 0.000000 -4.069705 6 0.000000 -1.118034 7 0.000000 -5.303301 8 0.000000 0.000000 9 0.000000 0.000000