单位承诺约束 pyomo
unit commitment constraint pyomo
我目前尝试使用 this unit commitment example to build my own model with pyomo. After defining switch-on and switch-off variables I struggle to implement the following equation:Equation
yalmip 示例非常简单:
for k = 2:Horizon
for unit = 1:Nunits
% indicator will be 1 only when switched on
indicator = onoff(unit,k)-onoff(unit,k-1);
range = k:min(Horizon,k+minup(unit)-1);
% Constraints will be redundant unless indicator = 1
Constraints = [Constraints, onoff(unit,range) >= indicator];
end
end
现在我只看一个单位,它给了我这个模型。
model = ConcreteModel()
p = prices
ts = timesteps
ut = min_uptime1
model.x = Var(ts, within = Binary) #onoff
model.v = Var(ts, within = Binary) #switch_on
model.w = Var(ts, within = Binary) #switch_off
def obj_rule(model):
return sum(p[t] * model.x[t] - 0.001 * (model.v[t] + model.w[t]) for t in ts)
model.revenue = Objective(rule = obj_rule, sense = maximize)
#start-up, shut-down costs will be added
def daily_uptime_rule (model):
return sum(model.x[t] for t in ts) == 12
model.daily_uptime_rule = \
Constraint(rule = daily_uptime_rule)
def switch_on(model, t):
if t == ts[0]:
return model.v[t] >= 1 - (1 - model.x[t])
else:
return model.v[t] >= 1 - model.x[t-1] - (1 - model.x[t])
model.switch_on = \
Constraint(ts, rule = switch_on)
def switch_off(model, t):
if t == ts[23]:
return model.w[t] >= model.x[t]
else:
return model.w[t] >= 1 - model.x[t+1] + (model.x[t] - 1)
model.switch_off = \
Constraint(ts, rule = switch_off)
def min_ut(model, t):
a = list(range(t, (min(ts[23], t+ut-1)+1)))
for i in a:
return model.x[i] >= model.v[t]
model.min_ut = \
Constraint(ts, rule = min_ut)
我的问题是,我无法在 pyomo 中以相同的方式访问变量 x。对于每个时间步 t,我们都需要 t+1、t+2、.. t+min_up -1 的约束,但我不能将范围与变量一起使用 (model.x)。我可以在 pyomo 中使用 yalmip 示例还是我需要一个新的公式?
好的,看来这里的根本问题是你想做的求和指数取决于不等式的 RHS。您可以通过几种方式构建总和的索引。您只需要注意您构造的值是有效的。这是一个可能对您有帮助的想法。这个玩具模型试图最大化 x[t] 的总和,但限制 x[t] <= x[t-1] + x[t-2] 只是为了咯咯笑。注意从 t
:
的传递值构造求和范围 "on the fly"
from pyomo.environ import *
m = ConcreteModel()
m.t = Set(initialize=range(5))
m.x = Var(m.t)
# constrain x_t to be less than the sum of x_(t-1), x_(t-2)
def x_limiter(m, t):
if t==0:
return m.x[t] <= 1 # limit the first value
# upperlimit on remainder is sum of previous 2
return sum(m.x[i] for i in range(t-2, t) if i in m.t) >= m.x[t]
m.c1 = Constraint(m.t, rule=x_limiter)
# try to maximize x
m.OBJ = Objective(expr=sum(m.x[t] for t in m.t), sense=maximize)
solver = SolverFactory('glpk')
m.pprint()
solver.solve(m)
m.display()
它完成了工作:
Variables:
x : Size=5, Index=t
Key : Lower : Value : Upper : Fixed : Stale : Domain
0 : None : 1.0 : None : False : False : Reals
1 : None : 1.0 : None : False : False : Reals
2 : None : 2.0 : None : False : False : Reals
3 : None : 3.0 : None : False : False : Reals
4 : None : 5.0 : None : False : False : Reals
Objectives:
OBJ : Size=1, Index=None, Active=True
Key : Active : Value
None : True : 12.0
最近这个post也有类似的想法:
我目前尝试使用 this unit commitment example to build my own model with pyomo. After defining switch-on and switch-off variables I struggle to implement the following equation:Equation
yalmip 示例非常简单:
for k = 2:Horizon
for unit = 1:Nunits
% indicator will be 1 only when switched on
indicator = onoff(unit,k)-onoff(unit,k-1);
range = k:min(Horizon,k+minup(unit)-1);
% Constraints will be redundant unless indicator = 1
Constraints = [Constraints, onoff(unit,range) >= indicator];
end
end
现在我只看一个单位,它给了我这个模型。
model = ConcreteModel()
p = prices
ts = timesteps
ut = min_uptime1
model.x = Var(ts, within = Binary) #onoff
model.v = Var(ts, within = Binary) #switch_on
model.w = Var(ts, within = Binary) #switch_off
def obj_rule(model):
return sum(p[t] * model.x[t] - 0.001 * (model.v[t] + model.w[t]) for t in ts)
model.revenue = Objective(rule = obj_rule, sense = maximize)
#start-up, shut-down costs will be added
def daily_uptime_rule (model):
return sum(model.x[t] for t in ts) == 12
model.daily_uptime_rule = \
Constraint(rule = daily_uptime_rule)
def switch_on(model, t):
if t == ts[0]:
return model.v[t] >= 1 - (1 - model.x[t])
else:
return model.v[t] >= 1 - model.x[t-1] - (1 - model.x[t])
model.switch_on = \
Constraint(ts, rule = switch_on)
def switch_off(model, t):
if t == ts[23]:
return model.w[t] >= model.x[t]
else:
return model.w[t] >= 1 - model.x[t+1] + (model.x[t] - 1)
model.switch_off = \
Constraint(ts, rule = switch_off)
def min_ut(model, t):
a = list(range(t, (min(ts[23], t+ut-1)+1)))
for i in a:
return model.x[i] >= model.v[t]
model.min_ut = \
Constraint(ts, rule = min_ut)
我的问题是,我无法在 pyomo 中以相同的方式访问变量 x。对于每个时间步 t,我们都需要 t+1、t+2、.. t+min_up -1 的约束,但我不能将范围与变量一起使用 (model.x)。我可以在 pyomo 中使用 yalmip 示例还是我需要一个新的公式?
好的,看来这里的根本问题是你想做的求和指数取决于不等式的 RHS。您可以通过几种方式构建总和的索引。您只需要注意您构造的值是有效的。这是一个可能对您有帮助的想法。这个玩具模型试图最大化 x[t] 的总和,但限制 x[t] <= x[t-1] + x[t-2] 只是为了咯咯笑。注意从 t
:
from pyomo.environ import *
m = ConcreteModel()
m.t = Set(initialize=range(5))
m.x = Var(m.t)
# constrain x_t to be less than the sum of x_(t-1), x_(t-2)
def x_limiter(m, t):
if t==0:
return m.x[t] <= 1 # limit the first value
# upperlimit on remainder is sum of previous 2
return sum(m.x[i] for i in range(t-2, t) if i in m.t) >= m.x[t]
m.c1 = Constraint(m.t, rule=x_limiter)
# try to maximize x
m.OBJ = Objective(expr=sum(m.x[t] for t in m.t), sense=maximize)
solver = SolverFactory('glpk')
m.pprint()
solver.solve(m)
m.display()
它完成了工作:
Variables:
x : Size=5, Index=t
Key : Lower : Value : Upper : Fixed : Stale : Domain
0 : None : 1.0 : None : False : False : Reals
1 : None : 1.0 : None : False : False : Reals
2 : None : 2.0 : None : False : False : Reals
3 : None : 3.0 : None : False : False : Reals
4 : None : 5.0 : None : False : False : Reals
Objectives:
OBJ : Size=1, Index=None, Active=True
Key : Active : Value
None : True : 12.0
最近这个post也有类似的想法: