较小的实例可以通过混合整数线性规划来解决。这是 MiniZinc 中使用问题数据的实现。可用管道已重新排列为平面阵列pipeLength。在模型x中表示每个管道的切口,并z表示是否使用管道。
int: nPipes = 6;
int: nCuts = 2;
set of int: PIPE = 1..nPipes;
set of int: CUT = 1..nCuts;
array[PIPE] of float: pipeLength = [3, 3, 3, 3, 4, 5];
array[CUT] of int: cutQuantity = [4, 1];
array[CUT] of float: cutLength = [2, 2.5];
array[PIPE, CUT] of var 0..10: x;
array[PIPE] of var 0..1: z;
% required cuts constraint
constraint forall(k in CUT)
(sum(i in PIPE)(x[i,k]) = cutQuantity[k]);
% available pipes constraint
constraint forall(i in PIPE)
(sum(k in CUT)(cutLength[k]*x[i,k]) <= pipeLength[i]);
% pipe used constraint
constraint forall(i in PIPE)
(max(cutQuantity)*z[i] >= sum(k in CUT)(x[i,k]));
var float: loss = sum(i in PIPE)(pipeLength[i]*z[i] - sum(k in CUT)(cutLength[k]*x[i,k]));
solve minimize loss;
output ["loss=\(show_float(2, 2, loss))\n"] ++
["pipeCuts="] ++ [show2d(x)] ++
["usePipe="] ++ [show(z)];
运行给出:
loss="1.50"
pipeCuts=[| 0, 0 |
0, 0 |
0, 0 |
0, 1 |
2, 0 |
2, 0 |]
usePipe=[0, 0, 0, 1, 1, 1]
相同的 MILP 模型也可以在例如 PuLP 中实现。