首页 > 解决方案 > Python Pyomo:布尔语句中变量的简单优化问题

问题描述

我想知道是否可以使用 Pyomo 来解决这样的问题:

变量:z (bounds = (0,1), S, sq, Loc1

平方 = -z*(z-1)

如果(z <= Loc1-0.2 或 z >= Loc1+0.2):S = 0

否则,如果 z <= Loc1:S = 0.6 * (z - Loc1 + 0.2)/0.2

否则:S = 0.6 * (Loc1 + 0.2 - z)/0.2

最大化(S*sq)

根据这个定义,S 在 Loc1 - 0.2 和 Loc + 0.2 之间是非零的,从 (Loc - 0.2) 处的 0 上升到 Loc1 处的 0.6,然后在 (Loc1 + 0.2) 处回到 0。

sq 是一个二次函数,其根为 0 和 1,最大 sq (z = 0.5) = 0.25。

所以问题的解决方案是 z = 0.5,Loc1 = 0.5,sq = 0.25 和 S = 0.6(在这些位置,sq 和 S 都有最大值)。

我尝试使用分段线性约束,但问题是在布尔表达式中使用变量(例如,如果 z < m.Loc1 - 0.2)是无效的,并且 value(m.Loc1) 仅使用 m.Loc1 的初始化值。有没有办法定义分段函数或带有分离的公式,允许使用变量来定义分段函数的域?

谢谢你的帮助!

编辑:它适用于这样的事情:

from pyomo.environ import *


m = ConcreteModel()
m.z = Var(bounds=(0,1))
m.S = Var() 
m.sq = Var()
m.Loc1 = Var(initialize=0.65)

def sq_func(m):
        return m.sq == -(m.z)*(m.z-1)
m.sqcon = Constraint(rule=sq_func)

rangep = [0,0,0.6,0,0]

bpts=[0,0.3,m.Loc1,0.8,1]
m.source=Piecewise(m.S,m.z,pw_pts=bpts,pw_repn='DCC',pw_constr_type='EQ',f_rule=rangep)

def obj(m):
    return m.S*m.sq
m.obj = Objective(rule = obj,sense=maximize)


results = SolverFactory('ipopt').solve(m)
print("Loc1: ",value(m.Loc1), "\nz: ", value(m.z), "\nS: ",value(m.S), "\nsq: ",value(m.sq),"\nS*sq: ",value(m.sq)*value(m.S))

标签: pythonbooleanconstraintspyomopiecewise

解决方案


推荐阅读