我正在努力做一些逻辑上应该可以做的事情。但是,我不确定如何在线性编程领域内做到这一点。我使用的是ZMPL / SCIP,但这对大多数人来说应该是可读的。
set I := {1,2,3,4,5};
param u[I] := <1> 10, <2> 20, <3> 30, <4> 40, <5> 50;
var a;
var b;
subto bval:
b == 2;
subto works:
a == u[2];
#subto does_not_work:
# a == u[b];
我正在尝试确保变量a
等于b
中索引u
的值。例如,我确保b == 2
,然后我尝试设置a == u[b]
的约束,但这不起作用。它抱怨我试图用变量索引。我只能a == u[2]
,这使得a
等于20
。
有没有办法在变量指定的索引处轻松访问u
?感谢您提供任何帮助/指导。
编辑:我认为这是不可能的,因为它不再成为LP。在这种情况下,任何人都可以想到另一种方式来写这个,这样,根据b
的值,我可以从集u
获得一个关联的值吗?这必须避免直接索引它。
解决方案:根据Ram的反应,我能够尝试一下,发现它绝对是一个可行且线性的解决方案。谢谢,拉姆!以下是ZMPL中的示例解决方案代码:
set I := {1,2,3,4,5};
param u[I] := <1> 10, <2> 20, <3> 30, <4> 40, <5> 50;
var a;
var b;
var y[I] binary;
subto bval:
b == 4;
subto only_one:
sum <i> in I : y[i] == 1;
subto trick:
b == (sum <i> in I : y[i] * i);
subto aval:
(sum <i> in I : u[i]*y[i]) == a;
答案 0 :(得分:3)
是的,您可以通过引入一些额外的0/1变量(指标变量)来重写和线性化您的约束。这些技巧在整数编程中并不少见。
英语限制
b
可以采用1到5之间的值.b = {1..5}
并且根据b的值,变量a
应该变为u[b]
指标变量
让我们介绍5个Y
变量 - Y1..Y5(每个可能的b值一个)
在任何特定时间,其中只有一个是真的。
Y1 + Y2 + Y3 + Y4 + Y5 = 1
All Y's are binary {0,1}
这就是诀窍。我们引入一个线性约束来确保相应的Y变量将取值1,仅当b是该值时。
b - 1xY1 - 2xY2 - 3xY3 - 4xY4 - 5xY5 = 0
(例如,如果b为3,则上述约束将强制Y3为1.)
现在,我们希望a
采用值u [b]。
a = u[1]xY1 + u[2]xY2 + u[3]xY3 + u[4]xY4 + u[5]xY5
由于u [1] ... u [5]是事先已知的常数,因此上述约束也是线性的。
这里有关于整数规划中这些IF-THEN条件的one reference。其中许多技巧涉及Big-M,但在这种情况下我们并不需要它。
希望能帮助你前进。