Pyomo分段函数赋值异常排查:疑似Couenne求解器问题
我现在需要在Pyomo模型里实现一个固定值的分段映射:
2 → 1-3 → 05 → 0.50 → 0
模型里的变量model.test对应model.h_change的取值集合是[-3,0,2,5],当前model.h_change的具体取值如下:
h_change : Size=11, Index=vehicules
Key : Lower : Value : Upper : Fixed : Stale : Domain
0 : -3 : 0.0 : 5 : False : False : Integers
1 : -3 : 2.0 : 5 : False : False : Integers
2 : -3 : 2.0 : 5 : False : False : Integers
3 : -3 : 2.0 : 5 : False : False : Integers
4 : -3 : 0.0 : 5 : False : False : Integers
5 : -3 : -3.0 : 5 : False : False : Integers
6 : -3 : 0.0 : 5 : False : False : Integers
7 : -3 : 0.0 : 5 : False : False : Integers
8 : -3 : 0.0 : 5 : False : False : Integers
9 : -3 : 0.0 : 5 : False : False : Integers
10 : -3 : 5.0 : 5 : False : False : Integers
我写了下面的分段约束代码:
model.test = Var(model.vehicules, initialize=0, bounds=(0,1)) DOMAIN_PTS = [-3.,0.,2.,5.] RANGE_PTS = [0.,0.,1.,0.5] model.con = Piecewise(model.vehicules, #Indexation model.test, # Var res model.h_change, #Var observées pw_pts=DOMAIN_PTS, pw_constr_type='EQ', f_rule=RANGE_PTS)
但运行后model.test的结果完全不符合预期:
test : Size=11, Index=vehicules
Key : Lower : Value : Upper : Fixed : Stale : Domain
0 : 0 : 0.0 : 1 : False : False : Reals
1 : 0 : 0.20000000000000004 : 1 : False : False : Reals
2 : 0 : 0.20000000000000004 : 1 : False : False : Reals
3 : 0 : 0.20000000000000004 : 1 : False : False : Reals
4 : 0 : 0.0 : 1 : False : False : Reals
5 : 0 : 0.0 : 1 : False : False : Reals
6 : 0 : 0.0 : 1 : False : False : Reals
7 : 0 : 0.0 : 1 : False : False : Reals
8 : 0 : 0.0 : 1 : False : False : Reals
9 : 0 : 0.0 : 1 : False : False : Reals
10 : 0 : 0.5000000000000001 : 1 : False : False : Reals
比如索引1、2、3的h_change取值是2,对应的test应该是1,但实际结果却是0.2,我实在搞不懂代码哪里出问题了。
后来我做了一个测试,用了一段参考代码(调整后):
# 预期X=5时Y=6 xdata = [1., 3., 6., 10.] ydata = [6.,2.,8.,7.] from pyomo.core import * model = ConcreteModel() model.X = Var(bounds=(1,10)) model.Y = Var(bounds=(0,100)) model.con = Piecewise(model.Y,model.X, pw_pts=xdata, pw_constr_type='EQ', f_rule=ydata, pw_repn='SOS2') # 强制X=5 def con2_rule(model): return model.X==5 model.con2 = Constraint(rule=con2_rule) model.obj = Objective(expr=model.Y, sense=maximize)
用Couenne求解器得到的Y值是7.600000072980164,和预期的6完全不符。这让我怀疑问题可能出在求解器上,而不是Piecewise的代码逻辑。有没有人能帮我确认一下问题根源,并且给出解决办法?
内容的提问来源于stack exchange,提问作者LCMa

