某油田在10个有油气构造处要选择若干个钻探采油,设第j 个构造开采时需花费aj元,投产后预计年收益为cj元,若尤其投资总额为b元,问题应选择哪几个构造开采最为有利。
1 基本问题求解
1.1 示例数据:
B = 7200;
1.2 模型构建:
1.3 代码实现
1.3.1 Latex代码:
max = \sum_{i=1}^{10}x_i * c_i \sum_{i=1}^{10}x_i * a_i \leq b x_i \in \{0,1\} a_i , c_i > 0
1.3.2 Lingo代码:
model: sets: CONSTRUCT/1..10/: C, A, X; endsets data: a = 1000 1300 1260 1500 1420 1670 1340 1190 1720 1640; c = 800 940 920 880 960 1000 870 840 1020 980; b = 7200; enddata max = @sum(CONSTRUCT : x * c); @sum(CONSTRUCT : x * a) <= b; @for(CONSTRUCT : @bin(X)); end
1.3.4 解决方案
Global optimal solution found. Objective value: 4720.000 Objective bound: 4720.000 Infeasibilities: 0.000000 Extended solver steps: 0 Total solver iterations: 0 Variable Value Reduced Cost B 7200.000 0.000000 C( 1) 800.0000 0.000000 C( 2) 940.0000 0.000000 C( 3) 920.0000 0.000000 C( 4) 880.0000 0.000000 C( 5) 960.0000 0.000000 C( 6) 1000.000 0.000000 C( 7) 870.0000 0.000000 C( 8) 840.0000 0.000000 C( 9) 1020.000 0.000000 C( 10) 980.0000 0.000000 A( 1) 1000.000 0.000000 A( 2) 1300.000 0.000000 A( 3) 1260.000 0.000000 A( 4) 1500.000 0.000000 A( 5) 1420.000 0.000000 A( 6) 1670.000 0.000000 A( 7) 1340.000 0.000000 A( 8) 1190.000 0.000000 A( 9) 1720.000 0.000000 A( 10) 1640.000 0.000000 X( 1) 0.000000 -800.0000 X( 2) 1.000000 -940.0000 X( 3) 1.000000 -920.0000 X( 4) 1.000000 -880.0000 X( 5) 1.000000 -960.0000 X( 6) 0.000000 -1000.000 X( 7) 0.000000 -870.0000 X( 8) 0.000000 -840.0000 X( 9) 1.000000 -1020.000 X( 10) 0.000000 -980.0000 Row Slack or Surplus Dual Price 1 4720.000 1.000000 2 0.000000 0.000000
2 拓展问题求解--柴油发电或电网供电
2.1 约束表达:
定义变量yj标识开采电力来源,若为柴油机发电取值为1;若为电网供电,取值为0
2.2 Latex代码:
\sum_{i=1}^{10} x_i * y_i * d_i \leq f \sum_{i=1}^{10} 0.3 * x_i * (1 - y_i) * d_i \leq p
3 拓展问题--增加新约束
3.1 约束表达:
3.2 Latex代码:
0 \leqslant x_6 - x_8 \leq 1 0 \leqslant x_5 + x_8 \leq 1 1 \leq x_2 + x_4 \leq 2 x_7 = x_8 x_1 + x_4 + x_6 + x_9 \leq 2
Lingo源码
model: sets: CONSTRUCT/1..10/: C, A, X; endsets data: a = 1000 1300 1260 1500 1420 1670 1340 1190 1720 1640; c = 800 940 920 880 960 1000 870 840 1020 980; b = 7200; enddata max = @sum(CONSTRUCT : x * c); @sum(CONSTRUCT : x * a) <= b; @for(CONSTRUCT : @bin(X)); x6 - x8 <= 1; x6 - x8 >= 0; x5 + x3 <= 1; (x4 + x2) >= 1; x8 = x7; x1 + x4 + x6 + x9 <= 2; end
3.3 结果展示
Local optimal solution found. Objective value: 4720.000 Objective bound: 4720.000 Infeasibilities: 0.000000 Extended solver steps: 3 Total solver iterations: 375 Variable Value Reduced Cost B 7200.000 0.000000 X6 0.000000 0.000000 X8 0.000000 0.000000 X5 0.000000 0.000000 X3 2.000000 0.000000 X4 0.000000 0.000000 X2 0.5000000E-03 0.000000 X7 0.000000 0.000000 X1 0.000000 0.000000 X9 0.000000 0.000000 C( 1) 800.0000 0.000000 C( 2) 940.0000 0.000000 C( 3) 920.0000 0.000000 C( 4) 880.0000 0.000000 C( 5) 960.0000 0.000000 C( 6) 1000.000 0.000000 C( 7) 870.0000 0.000000 C( 8) 840.0000 0.000000 C( 9) 1020.000 0.000000 C( 10) 980.0000 0.000000 A( 1) 1000.000 0.000000 A( 2) 1300.000 0.000000 A( 3) 1260.000 0.000000 A( 4) 1500.000 0.000000 A( 5) 1420.000 0.000000 A( 6) 1670.000 0.000000 A( 7) 1340.000 0.000000 A( 8) 1190.000 0.000000 A( 9) 1720.000 0.000000 A( 10) 1640.000 0.000000 X( 1) 1.000000 -800.0000 X( 2) 1.000000 -940.0000 X( 3) 0.000000 -920.0000 X( 4) 0.000000 -880.0000 X( 5) 1.000000 -960.0000 X( 6) 1.000000 -1000.000 X( 7) 0.000000 -870.0000 X( 8) 0.000000 -840.0000 X( 9) 1.000000 -1020.000 X( 10) 0.000000 -980.0000 Row Slack or Surplus Dual Price 1 4720.000 1.000000 2 90.00000 0.000000 3 1.000000 0.000000 4 0.000000 0.000000 5 0.000000 0.000000 6 0.000000 0.000000 7 0.000000 0.000000 8 2.000000 0.000000
4 总结梳理
(1)当两个二进制变量存在依赖关系,先决变量取值应不大于后继变量
(2)第一部分和第三部分得到两个相同最优解值,但解的表达形式不一样。应进一步探索,Lingo内部的实现机制,以获取更多形式的最优解。
更多精彩欢迎关注个人公众账号