首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在PuLP中编写条件约束

如何在PuLP中编写条件约束
EN

Stack Overflow用户
提问于 2020-01-21 23:33:17
回答 1查看 2.2K关注 0票数 1

背景

我正在建立一个使用PuLP的太阳能+电池+电解质/燃料电池系统的优化调度模型。这样做的目的是在价格较低的情况下,通过给电池充电和利用太阳能发电生产氢气,然后在价格高的时候排放电池和燃烧氢气,从而实现收入最大化。

研究与故障排除

我是PuLP新手,我花了一段时间在这方面工作,使用在线指南等帮助,但我的代码仍在返回垃圾答案。我花了一段时间浏览搜索答案(这里这里这里这里)。我想我知道问题可能是什么。

潜在问题识别

我认为我的主要问题是,我有许多逻辑约束,需要用不同的形式编写才能在PuLP中工作。我目前没有指标变量或大M约束,我认为这是写条件约束的有用方法。我试着自己写,但没有运气,因为我不知道如何用PuLP (我认为它不允许您使用IF或np.where等等)

至于大M约束,我试着用我认为合适的方式编写它们,但它返回了“非常数表达式不能乘以”的错误。

问题示例

下面是我试图通过PuLP中的条件约束实现的代码示例。

在我的系统中,电解设备的操作能力最低(10%)。因此,它在时间t处的势能图需要类似于;

代码语言:javascript
复制
if (SE[t] + BE[t]) < E_MinCons_kwh:
   (SE[t] + BE[t]) == 0
elif (HZ_Size_nm3 - HSC[t]) < E_MinProd_nm3:
   (SE[t] + BE[t]) == 0
else:
   (SE[t] + BE[t]) <= e_kwh
   (SE[t] + BE[t]) <= (HZ_Size_nm3 - HSC[t]) * nm3_to_kwh)
   (SE[t] + BE[t]) >= E_MinCons_kwh  

,其中

SE[t] = electricity input from Solar powering the Electrolyser at time t

BE[t] = electricity input from Battery powering the Electrolyser at time t

E_MinCons_kwh = The minimal power draw of the Electrolyser (~18 kWh)

e_kwh = the maximum power draw of the Electrolyser (~180 KWh)

HZ_Size_nm3 = The size of the hydrogen Storage tank (~5,000 nm3)

代码语言:javascript
复制
HSC[t] = the current storage level of the hydrogen tank at time t (in nm3)

HSC[t+1] = HSC[t] + SH[t] + BH[t] - HF[t] - HM[t]

SH[t] = volume of Hydrogen produced from solar electricity at time t (in nm3)

BH[t] = volume of Hydrogen produced from Battery Discharge at time t (in nm3)

HF[t] = volume of Hydrogen consumed by the Fuel-Cell at time t (in nm3)

HM[t] = volume of Hydrogen sold to market at time t (in nm3)

E_MinProd_nm3 = Hydrogen produced when Electroylser operating at min capacity (~3.6 nm3)

nm3_to_kwh = Conversion factor, kwh required to produce 1 nm3 of hydrogen (~5.4 kwh)

请求协助

有人知道我如何在PuLP约束中使用的方法来编写上述逻辑参数吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-01-22 12:05:27

让我在总线实例中添加一个逻辑约束,向您展示如何使用带纸浆的大M。

代码语言:javascript
复制
import pulp
import cplex

bus_problem = pulp.LpProblem("bus", pulp.LpMinimize)

nbBus40 = pulp.LpVariable('nbBus40', lowBound=0, cat='Integer')
nbBus30 = pulp.LpVariable('nbBus30', lowBound=0, cat='Integer')

# Objective function
bus_problem += 600 * nbBus40 + 480 * nbBus30, "cost"

# Constraints
bus_problem += 40 * nbBus40 + 30 * nbBus30 >= 300

bus_problem.solve(pulp.CPLEX())
print(pulp.LpStatus[bus_problem.status])

for variable in bus_problem.variables():
    print ("{} = {}".format(variable.name, variable.varValue))

print()
print("with if nb buses 40 more than 3  then nbBuses30 more than 7")

M=100

#if then constraint

A = pulp.LpVariable('A', lowBound=0, cat='Binary')
B = pulp.LpVariable('B', lowBound=0, cat='Binary')

bus_problem += A<=B


bus_problem += nbBus40-2<=M*(A)
bus_problem +=nbBus40-3>=-M*(1-A)
bus_problem +=nbBus30-6<=M*(B)
bus_problem +=nbBus30-7>=-M*(1-B)

这给

代码语言:javascript
复制
Optimal
A = 0.0
B = 1.0
nbBus30 = 10.0
nbBus40 = 0.0

使用双工 API,您可以编写相同的

代码语言:javascript
复制
from docplex.mp.model import Model

mdl = Model(name='buses')
nbbus40 = mdl.integer_var(name='nbBus40')
nbbus30 = mdl.integer_var(name='nbBus30')

A = mdl.binary_var(name='A')
B = mdl.binary_var(name='B')


mdl.add_constraint(nbbus40*40 + nbbus30*30 >= 300, 'kids')
mdl.minimize(nbbus40*500 + nbbus30*400)

mdl.solve()

for v in mdl.iter_integer_vars():
   print(v," = ",v.solution_value)

print()
print("with if nb buses 40 more than 3  then nbBuses30 more than 7")

M=100

#if then constraint



mdl.add_constraint(A<=B)


mdl.add_constraint(nbbus40-2<=M*(A))
mdl.add_constraint(nbbus40-3>=-M*(1-A))
mdl.add_constraint(nbbus30-6<=M*(B))
mdl.add_constraint(nbbus30-7>=-M*(1-B))

mdl.minimize(nbbus40*500 + nbbus30*400)

mdl.solve()

for v in mdl.iter_binary_vars():
    print(v," = ",v.solution_value)

for v in mdl.iter_integer_vars():
    print(v," = ",v.solution_value)

但是,您也可以编写简单的逻辑约束:

代码语言:javascript
复制
from docplex.mp.model import Model

mdl = Model(name='buses')
nbbus40 = mdl.integer_var(name='nbBus40')
nbbus30 = mdl.integer_var(name='nbBus30')
mdl.add_constraint(nbbus40*40 + nbbus30*30 >= 300, 'kids')
mdl.minimize(nbbus40*500 + nbbus30*400)

mdl.solve()

for v in mdl.iter_integer_vars():
   print(v," = ",v.solution_value)

print()
print("with if nb buses 40 more than 3  then nbBuses30 more than 7")

#if then constraint
mdl.add_constraint(mdl.if_then(nbbus40>=3,nbbus30>=7))

mdl.minimize(nbbus40*500 + nbbus30*400)

mdl.solve()



for v in mdl.iter_integer_vars():
    print(v," = ",v.solution_value)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59850692

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档