我有点困惑如何使用实例来更改 pyomo 中的模型。例如,我有一个模型,然后我创建一个变量
#non negative variable
SS.lambda_DA_E=pe.Var(SS.T, domain=pe.PositiveReals)
然后我创建一个实例并解决模型
instance=SS.create_instance()
solver = po.SolverFactory('mpec_nlp')
results = solver.solve(instance, load_solutions=True, tee=True)
现在我想将变量重新定义为自由变量,将它分配给我从以前的解决方案中获得的初始值,然后再次解决它,我尝试使用
def _init_rule_L_E2(m, t):
return (pe.value(instance.lambda_DA_E[t]))
instance.lambda_DA_E=pe.Var(SS.T, domain=pe.Reals, initialize=_init_rule_L_E2)
然后我得到一个错误 ValueError:未初始化的 NumericValue 对象 lambda_DA_E [t1] 没有值
我重新定义变量正确吗?因为我也得到了一个警告
WARNING: Implicitly replacing the Component attribute lambda_DA_E (type=<cl
'pyomo.core.base.var.IndexedVar'>) on block unknown with a new Component
(type=<cl 'pyomo.core.base.var.IndexedVar'>). This is usually
indicative of a modelling error. To avoid this warning, use
block.del_component() and block.add_component().
这是完整的代码 '' '
import pandas as pd
import pyomo.environ as pe
import pyomo.opt as po
import pyomo.mpec as mpc
#DATA
T=2;
G=2;
time = ['t{0}'.format(t+1) for t in range(T)]
gen=['G{0}'.format(g+1) for g in range(G)]
#Technical characteristic
elec_maxprod= {'G1': 200, 'G2': 200,} #Only for Generators
D_E={'t1':350, 't2': 150} #El demand
C_fuel = {'G1': 15.0, 'G2': 50.0}
#MODEL
SS=pe.ConcreteModel()
#Duals are desired
SS.dual = pe.Suffix(direction=pe.Suffix.IMPORT)
### SETS
SS.T = pe.Set(initialize = time)
SS.G = pe.Set(initialize = gen )
### PARAMETERS
SS.P_max = pe.Param(SS.G, initialize = elec_maxprod) #Only for Generators
SS.D_E = pe.Param(SS.T, initialize = D_E) #El demand
SS.C_fuel = pe.Param(SS.G, initialize = C_fuel)
### VARIABLES
SS.p_DA=pe.Var(SS.G, SS.T, domain=pe.PositiveReals)
##Dual variables
#positive variables
SS.mu_min_G=pe.Var(SS.G, SS.T, domain=pe.PositiveReals)
SS.mu_max_G=pe.Var(SS.G, SS.T, domain=pe.PositiveReals)
#free variables
SS.lambda_DA_E=pe.Var(SS.T, domain=pe.PositiveReals) # day-ahead electricity price in period t [$ per MWh]
##CONSTRAINTS
##Maximum and Minimum Generation
SS.comp1 = mpc.ComplementarityList()
for t in SS.T:
for g in SS.G:
SS.comp1.add(expr=mpc.complements( SS.p_DA[g,t] >= 0, SS.mu_min_G[g,t] >= 0))
SS.comp2 = mpc.ComplementarityList()
for t in SS.T:
for g in SS.G:
SS.comp2.add(expr=mpc.complements( SS.P_max[g] - SS.p_DA[g,t] >= 0, SS.mu_max_G[g,t] >= 0))
##Stationarity
SS.L1_p_DA = pe.ConstraintList()
for t in SS.T:
for g in SS.G:
SS.L1_p_DA.add( SS.C_fuel[g] - SS.mu_min_G[g,t] + SS.mu_max_G[g,t] - SS.lambda_DA_E[t]== 0)
#El Balance
SS.El_DA_bal=pe.ConstraintList()
for t in SS.T:
SS.El_DA_bal.add( sum(SS.p_DA[g,t] for g in SS.G) - SS.D_E[t] == 0 )
instance=SS.create_instance()
solver = po.SolverFactory('mpec_nlp')
results = solver.solve(instance, load_solutions=True, tee=True)
print("\nDisplaying Solution\n" + '-'*60)
##Printing the variables results
for t in SS.T:
print('price_DA[',t,']', pe.value(instance.lambda_DA_E[t]))
##Redefine variable with a new feasible region and new initial value
def _init_rule_L_E2(m, t):
return (pe.value(instance.lambda_DA_E[t]))
instance.lambda_DA_E=pe.Var(SS.T, domain=pe.Reals, initialize=_init_rule_L_E2) # day-ahead electricity price in period t [$ per MWh]
##Solve it again
results = solver.solve(instance, load_solutions=True, tee=True)
##Printing the variables results
for t in SS.T:
print('price_DA[',t,']', pe.value(instance.lambda_DA_E[t]))

错误是因为您没有修改当前组件lambda_DA_E
,而是用一个新的组件重新引用它。
如果你想改变组件的任何属性,你可以使用这样的赋值:
#After solving the whole model.
>>>instance.lambda_DA_E[t].display()
lambda_DA_E : Size=2, Index=T
Key : Lower : Value : Upper : Fixed : Stale : Domain
t1 : 0 : None : None : False : True : PositiveReals
t2 : 0 : None : None : False : True : PositiveReals
#After solving the first time
>>>print('changing Domain:')
>>>instance.lambda_DA_E[t].domain=pe.Reals
>>>results = solver.solve(instance, load_solutions=True, tee=True)
>>>instance.lambda_DA_E[t].display()
lambda_DA_E : Size=2, Index=T
Key : Lower : Value : Upper : Fixed : Stale : Domain
t1 : None : 50.00000000097778 : None : False : False : Reals
t2 : None : 15.000000000977778 : None : False : False : Reals
然后你可以用solver.solve(instance, ...)
再次求解模型
只是几个注释:
由于SS
是ConcreteModel()
,您不能调用instance=SS.create_instance()
。根据pyomo
版本,这可能会引发WARNING
:
WARNING: DEPRECATED: Cannot call Model.create_instance() on a constructed model; returning a clone of the current model instance.
如果要创建 SSConcreteModel
的副本,可以使用clone()
:
instance = SS.clone()
我从来没有使用过ComplementarityList
从pyomo.environ.mpc
,但试图解决这个问题会返回一个警告:
WARNING: Implicitly replacing the Component attribute v (type=<cl 'pyomo.core.base.var.SimpleVar'>) on block comp2[2] with a new Component (type=<cl 'pyomo.core.base.var.SimpleVar'>). This is usually indicative of a modelling error. To avoid this warning, use block.del_component() and block.add_component().
我认为mpec_nlp
求解器使用某种重新表述,在解析时再次调用。这可能不是问题,但仅供参考。
本站系公益性非盈利分享网址,本文来自用户投稿,不代表码文网立场,如若转载,请注明出处
评论列表(26条)