在 pyomo中重新定义可变域

我有点困惑如何使用实例来更改 pyomo 中的模型。例如,我有一个模型,然后我创建一个变量

我有点困惑如何使用实例来更改 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]))
1

错误是因为您没有修改当前组件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, ...)再次求解模型

只是几个注释:

由于SSConcreteModel(),您不能调用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()

我从来没有使用过ComplementarityListpyomo.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求解器使用某种重新表述,在解析时再次调用。这可能不是问题,但仅供参考。

本站系公益性非盈利分享网址,本文来自用户投稿,不代表码文网立场,如若转载,请注明出处

(920)
pyvenv无法正常工作 因为ensurepip不可用
上一篇
log4j日志记录层次结构顺序
下一篇

相关推荐

发表评论

登录 后才能评论

评论列表(26条)