如何在 pyomo 中制定分段阶跃函数 [英] How to Formulate a Piecewise Step Function in pyomo
问题描述
我有一个关于 pyomo 中分段阶跃函数的正确公式的问题.我想在我的模型中包含以下形式的单个分段函数:
I have a question regarding the correct formulation of a piecewise step function in pyomo. I want to include in my model a single piecewise function of the form:
/ 1 , 0 <= X(t) <= 1
Z(X) = \ 0 , 1 <= X(t) <= 2
其中 X 适合在时域上接管的数据,而 Z 的作用类似于二进制变量.pyomo 文档中最相似的例子是 step.py 使用 INC 的示例.但是,在使用此公式求解时,我观察到域变量 x粘在"x=1 处的断点的问题.我认为这是因为(如文档中所述)Z 可以求解整个垂直线,如果是连续的,或者如果是二进制的,则在 0 和 1 处都是双重可行的.通过分段函数提供的其他公式(即 dlog、dcc、log 等)也遇到了类似的问题(事实上,根据到 GAMS 的输出,我很确定它们根本不支持二进制/整数变量).
Where X is being fit to data over taken over a time domain and Z acts like a binary variable. The most similar example in pyomo documentation is the step.py example using INC. However, when solving with this formulation I observe the problem of the domain variable x ‘sticking’ to the breakpoint at x=1. I assume this is because (as noted in the documentation) Z can solve to the entire vertical line if continuous or is doubly feasible at both 0 and 1 if binary. Other formulations offered via the piecewise function (i.e. dlog, dcc, log, etc.) experience similar issues (in fact, based on the output to GAMS I’m pretty sure they don’t support binary/integer variables at all).
是否有一种正确"的方法可以在 pyomo 中制定分段函数,避免断点处的多重可行性问题,从而避免域变量收敛到断点?我将 BARON 与求解器 cplex 和 ipopt 一起使用,但是我的直觉告诉我这个公式问题不能通过简单地改变求解器来解决.
Is there a ‘correct’ way to formulate a piecewise function in pyomo that avoids the multiple-feasibility issue at the breakpoint, thus avoiding the domain variable converging to the breakpoint? I am using BARON with solvers cplex and ipopt, however my gut tells me this formulation issue can’t be solved by simply changing solvers.
如果有帮助,我还可以发送一份文件,说明我对为什么当前 pyomo 分段公式不支持二进制变量的观察.
I can also send a document illustrating my observations on why the current pyomo piecewise formulations don’t support binary variables, if it would help.
推荐答案
下面是一些示例代码,我们尝试最小化阶跃函数 Z 的总和.
Here's some sample code where we try to minimise the sum of the step function Z.
model = ConcreteModel()
model.A = Set(initialize=[1,2,3])
model.B = Set(initialize=['J', 'K'])
model.x = Var(model.A, model.B, bounds=(0, 2))
model.z = Var(model.A, model.B, domain = Binary)
DOMAIN_PTS = [0,1,1,2]
RANGE_PTS = [1,1,0,0]
model.z_constraint = Piecewise(
model.A, model.B,
model.z, model.x,
pw_pts=DOMAIN_PTS,
pw_repn='INC',
pw_constr_type = 'EQ',
f_rule = RANGE_PTS,
unbounded_domain_var = True)
def objective_rule(model):
return sum(model.z[a,b] for a in model.A for b in model.B)
model.objective = Objective(rule = objective_rule, sense=minimize)
如果您在上面设置sense = minimum
,程序将求解并为每个索引值给出x = 1
.如果您设置sense = maximum
,程序将求解并为每个索引值给出x = 0
.我不太确定你所说的粘性是什么意思,但我不认为这个程序能做到.并且它实现了阶跃函数.
If you set sense = minimize
above, the program will solve and give x = 1
for each index value. If you set sense = maximize
, the program will solve and give x = 0
for each index value. I'm not too sure what you mean by stickiness, but I don't think this program does it. and it implements the step function.
这篇关于如何在 pyomo 中制定分段阶跃函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!