Pyomo 中用于解决 MILP 的非固定边界错误
Non-fixed bound Error in Pyomo to solve MILP
我是 Pyomo 的新手。我正在尝试解决以下 MILP 问题:
我尝试使用以下脚本:
import numpy as np
from pyomo.environ import *
from pyomo.gdp import *
import pyomo.environ as aml
OMEGA = ['Bus 01','Bus 06','Bus 32']
K = ['G 03','Line 15-16']
MARGINS = {
'G 03' : 0.28,
'Line 15-16': 0.30,
}
BMAX = {
'Bus 01':3,
'Bus 06':3,
'Bus 32':3,
}
BMIN = {
'Bus 01':0.001,
'Bus 06':0.001,
'Bus 32':0.001,
}
SENSITIVITIES = {
('Bus 01','G 03') : {'S': 0.001},
('Bus 06','G 03') : {'S': 0.016},
('Bus 32','G 03') : {'S': 0.008},
('Bus 01','Line 15-16') : {'S': 0.004},
('Bus 06','Line 15-16') : {'S': 0.010},
('Bus 32','Line 15-16') : {'S': 0.015},
}
Cv = 0.41
Cf = 1.3
Mr = 0.35
model = ConcreteModel()
model.Omega = Set(initialize = (i for i in OMEGA))
model.K = Set(initialize = (i for i in K))
model.M = Param(model.K,initialize = MARGINS)
model.b = Var(model.Omega, within = NonNegativeReals)
model.q = Var(model.Omega, within = Binary)
model.b_k = Var(model.Omega,model.K, within = NonNegativeReals)
model.Bmax = Param(model.Omega, initialize=BMAX)
model.Bmin = Param(model.Omega, initialize=BMIN)
def obj_rule(model):
return sum(Cv*model.b[i] + Cf*model.q[i] for i in model.Omega)
model.obj = Objective(rule = obj_rule, sense = minimize)
def margin_rule(model,k):
value = sum(SENSITIVITIES[(i,k)]['S']*model.b_k[i,k] for i in model.Omega) + model.M[k]
return value >= Mr
model.margin = Constraint(model.K,rule=margin_rule)
def minmargin_rule(model,i,k):
return aml.inequality(model.Bmin[i],model.b_k[i,k],model.b[i])
model.minmargin = Constraint(model.Omega,model.K, rule=minmargin_rule)
def powerlimits_rule(model,i):
return aml.inequality(model.Bmin[i]*model.q[i],model.b[i],model.Bmax[i]*model.q[i])
model.powerlimits = Constraint(model.Omega,rule=powerlimits_rule)
results = SolverFactory('glpk').solve(model)
results.write()
但是 returns "ValueError: non-fixed bound or weight: b[Bus 01]" 用于 "minmargin" 约束,"ValueError: No value for uninitialized NumericValue object q[Bus 01]" 用于 "powerlimits" 约束。如果能提供一些帮助或建议来解决这些问题,我将不胜感激。
出于某种原因,pyomo 似乎不喜欢具有多个变量引用的链式不等式约束。我只是做了一些修补。
这将在解决时失败,就像您的模型一样:
from pyomo.environ import *
m = ConcreteModel()
m.A = Set(initialize = [1,2,3])
m.X = Var(m.A, domain=NonNegativeReals)
m.Y = Var(m.A, domain=NonNegativeReals)
def x_sandwich(m, a):
return inequality(5, m.X[a], m.Y[a])
m.c2 = Constraint(m.A, rule=x_sandwich)
然而,这工作得很好:
def x_sandwich(m, a):
return inequality(5, m.X[a], 10)
m.c2 = Constraint(m.A, rule=x_sandwich)
也许了解链式不等式函数的内幕的人可以发表评论。我在快速搜索中没有找到任何会说这些都是酸的东西。
我能够通过将链式不等式分解成独立的约束来让你的模型达到 process/solve(你可能需要对你的 powerlimits
约束做同样的事情,我已经注释掉了):
def minmargin_rule_lower(model, i, k):
return model.Bmin[i] <= model.b_k[i, k]
model.mm_l = Constraint(model.Omega, model.K, rule=minmargin_rule_lower)
def minmargin_rule_upper(model, i, k):
return model.b_k[i, k] <= model.b[i]
model.mm_u = Constraint(model.Omega, model.K, rule=minmargin_rule_upper)
我是 Pyomo 的新手。我正在尝试解决以下 MILP 问题:
我尝试使用以下脚本:
import numpy as np
from pyomo.environ import *
from pyomo.gdp import *
import pyomo.environ as aml
OMEGA = ['Bus 01','Bus 06','Bus 32']
K = ['G 03','Line 15-16']
MARGINS = {
'G 03' : 0.28,
'Line 15-16': 0.30,
}
BMAX = {
'Bus 01':3,
'Bus 06':3,
'Bus 32':3,
}
BMIN = {
'Bus 01':0.001,
'Bus 06':0.001,
'Bus 32':0.001,
}
SENSITIVITIES = {
('Bus 01','G 03') : {'S': 0.001},
('Bus 06','G 03') : {'S': 0.016},
('Bus 32','G 03') : {'S': 0.008},
('Bus 01','Line 15-16') : {'S': 0.004},
('Bus 06','Line 15-16') : {'S': 0.010},
('Bus 32','Line 15-16') : {'S': 0.015},
}
Cv = 0.41
Cf = 1.3
Mr = 0.35
model = ConcreteModel()
model.Omega = Set(initialize = (i for i in OMEGA))
model.K = Set(initialize = (i for i in K))
model.M = Param(model.K,initialize = MARGINS)
model.b = Var(model.Omega, within = NonNegativeReals)
model.q = Var(model.Omega, within = Binary)
model.b_k = Var(model.Omega,model.K, within = NonNegativeReals)
model.Bmax = Param(model.Omega, initialize=BMAX)
model.Bmin = Param(model.Omega, initialize=BMIN)
def obj_rule(model):
return sum(Cv*model.b[i] + Cf*model.q[i] for i in model.Omega)
model.obj = Objective(rule = obj_rule, sense = minimize)
def margin_rule(model,k):
value = sum(SENSITIVITIES[(i,k)]['S']*model.b_k[i,k] for i in model.Omega) + model.M[k]
return value >= Mr
model.margin = Constraint(model.K,rule=margin_rule)
def minmargin_rule(model,i,k):
return aml.inequality(model.Bmin[i],model.b_k[i,k],model.b[i])
model.minmargin = Constraint(model.Omega,model.K, rule=minmargin_rule)
def powerlimits_rule(model,i):
return aml.inequality(model.Bmin[i]*model.q[i],model.b[i],model.Bmax[i]*model.q[i])
model.powerlimits = Constraint(model.Omega,rule=powerlimits_rule)
results = SolverFactory('glpk').solve(model)
results.write()
但是 returns "ValueError: non-fixed bound or weight: b[Bus 01]" 用于 "minmargin" 约束,"ValueError: No value for uninitialized NumericValue object q[Bus 01]" 用于 "powerlimits" 约束。如果能提供一些帮助或建议来解决这些问题,我将不胜感激。
出于某种原因,pyomo 似乎不喜欢具有多个变量引用的链式不等式约束。我只是做了一些修补。
这将在解决时失败,就像您的模型一样:
from pyomo.environ import *
m = ConcreteModel()
m.A = Set(initialize = [1,2,3])
m.X = Var(m.A, domain=NonNegativeReals)
m.Y = Var(m.A, domain=NonNegativeReals)
def x_sandwich(m, a):
return inequality(5, m.X[a], m.Y[a])
m.c2 = Constraint(m.A, rule=x_sandwich)
然而,这工作得很好:
def x_sandwich(m, a):
return inequality(5, m.X[a], 10)
m.c2 = Constraint(m.A, rule=x_sandwich)
也许了解链式不等式函数的内幕的人可以发表评论。我在快速搜索中没有找到任何会说这些都是酸的东西。
我能够通过将链式不等式分解成独立的约束来让你的模型达到 process/solve(你可能需要对你的 powerlimits
约束做同样的事情,我已经注释掉了):
def minmargin_rule_lower(model, i, k):
return model.Bmin[i] <= model.b_k[i, k]
model.mm_l = Constraint(model.Omega, model.K, rule=minmargin_rule_lower)
def minmargin_rule_upper(model, i, k):
return model.b_k[i, k] <= model.b[i]
model.mm_u = Constraint(model.Omega, model.K, rule=minmargin_rule_upper)