我正在使用Pyomo和glpk解算器为一个家用太阳能光伏板电池的运行编写优化。当没有多余的太阳能时,优化工作非常完美,但当太阳能太多时,我会得到一个未初始化的错误。 这是我的密码:
import numpy as np
import pandas as pd
from pyomo.environ import *
from pulp import *
power = pd.read_csv('Battery 2 Hourly Power flow for the month with time.csv')
solar_forecast = list(power['Solar_(W)'])
demand = list(power['Household_(W)']*(-1.0))
power['Time'] = np.arange(720)
以下是数据示例:
Hour Grid_(W) Household_(W) Solar_(W) Storage_(W) Time
00:00 392.095000 -379.960833 0.0 -12.134167 0
01:00 205.441667 -193.115833 0.0 -12.325000 1
02:00 142.570000 -130.807500 0.0 -11.763333 2
03:00 96.456667 -84.829167 0.0 -11.632500 3
04:00 100.940833 -89.330833 0.0 -11.610833 4
05:00 132.357500 -120.559167 0.0 -11.797500 5
06:00 182.733333 -171.605833 0.000000 -11.126667 6
07:00 96.900833 -127.610000 42.106667 -11.397500 7
08:00 35.052500 -228.003333 304.839167 -111.890000 8
09:00 1.385833 -308.922500 489.586667 -182.050833 9
10:00 2086.825833 -2596.776667 492.475000 17.478333 10
11:00 959.740000 -1696.840833 846.346667 -109.245833 11
12:00 2648.243333 -3006.825000 374.156667 -15.579167 12
13:00 1826.446667 -2055.055833 240.062500 -11.453333 13
14:00 1410.041667 -1551.870000 153.488333 -11.658333 14
15:00 536.535000 -572.946667 48.553333 -12.143333 15
16:00 1079.993333 -1069.868333 0.890000 -11.016667 16
17:00 2269.711667 -2260.661667 0.000000 -9.050833 17
优化
model = ConcreteModel()
# Define model parameters
model.T = Set(initialize=power.Time.tolist(), ordered=True, doc='hour of week')
model.Ein = Param(initialize=2400, doc='Max rate of power flow (W) in')
model.Eout = Param(initialize=-2400, doc='Max rate of power flow (W) out')
model.Smax = Param(initialize=4800, doc='Max storage (Wh)')
model.Smin = Param(initialize=480, doc='Min storage (Wh)')
model.price = Param(initialize = 0.000124, doc = 'Hourly Price of Electricity')
#Decision Variables
model.E = Var(model.T, domain=Reals) # Battery Power Flow
model.S = Var(model.T, domain=NonNegativeReals) # Battery State of Charge
model.excess_pv = Var(model.T, domain=Reals) # Excess PV Forecasted
## Set Constraints
def storage_state(model,t):
'Storage changes with flows in/out'
if t == model.T.first():
return model.S[t] == (model.Smax + model.Smin)/2
else:
return model.S[t] == (model.S[t-1] - model.E[t-1])
model.charge_state = Constraint(model.T, rule = storage_state)
def max_charge(model,t):
'Max hourly charge of the battery'
return model.E[t] <= model.Ein
model.pos_charge = Constraint(model.T, rule = max_charge)
def max_discharge(model,t):
'Max hourly discharge of the battery'
return model.E[t] >= model.Eout
model.discharge = Constraint(model.T, rule = max_discharge)
def max_stateofcharge(model,t):
'Max storage in the battery'
return model.S[t] <= model.Smax
model.max_soc = Constraint(model.T, rule = max_stateofcharge)
def min_stateofcharge(model, t):
'Min storage in the battery'
return model.S[t] >= model.Smin
model.min_soc = Constraint(model.T, rule = min_stateofcharge)
def stop_final_discharge(model, t):
'Prevents battery discharging in final hour'
return model.E[t] <= model.S[t]
model.final = Constraint(model.T, rule = stop_final_discharge)
def excess_solar(model, t):
'Calculating the excess solar if the battery is full'
if model.S[t] == model.Smax:
return model.excess_pv[t] == demand[t] - solar_forecast[t]
else:
return model.excess_pv[t] == 0
model.solar_constraint = Constraint(model.T, rule = excess_solar)
def demand_cons(model, t):
'Demand must be postive'
if model.excess_pv[t] <= 0:
return demand[t] - solar_forecast[t] - model.E[t] >= 0
else:
return demand[t] + model.excess_pv[t] - solar_forecast[t] - model.E[t] >= 0
model.demand_constraint = Constraint(model.T, rule = demand_cons)
# objective
cost = sum(model.price*(demand[t] - solar_forecast[t] - model.E[t]) for t in model.T)
model.cost = Objective(expr = cost, sense=minimize)
# solve
solvername='glpk'
solverpath_folder='C:\\w64'
solverpath_exe='C:\\w64\\glpsol'
opt = SolverFactory(solvername,executable=solverpath_exe)
results = opt.solve(model)
print('Cost = €', round(value(model.cost()),2))
如果我没有多余的PV,我就不需要变量model.excess_pv = Var(model.T, domain=Reals)
,需求约束如下所示:
def demand_cons(model, t):
'Demand must be postive'
return demand[t] - solar_forecast[t] - model.E[t] >= 0
model.demand_constraint = Constraint(model.T, rule = demand_cons)
这就是我在尝试使用具有多余pv的数据运行代码时遇到的错误
ERROR: evaluating object as numeric value: S[0]
(object: <class 'pyomo.core.base.var._GeneralVarData'>)
No value for uninitialized NumericValue object S[0]
ERROR: Rule failed when generating expression for constraint solar_constraint
with index 0: ValueError: No value for uninitialized NumericValue object
S[0]
ERROR: Constructing component 'solar_constraint' from data=None failed:
ValueError: No value for uninitialized NumericValue object S[0]
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-4-cd4b3e07af68> in <module>
63 return Constraint.Skip
64
---> 65 model.solar_constraint = Constraint(model.T, rule = excess_solar)
66
67 def demand_cons(model, t):
c:\users\stephen\python\lib\site-packages\pyomo\core\base\block.py in __setattr__(self, name, val)
542 # Pyomo components are added with the add_component method.
543 #
--> 544 self.add_component(name, val)
545 else:
546 #
c:\users\stephen\python\lib\site-packages\pyomo\core\base\block.py in add_component(self, name, val)
1087 _blockName, str(data))
1088 try:
-> 1089 val.construct(data)
1090 except:
1091 err = sys.exc_info()[1]
c:\users\stephen\python\lib\site-packages\pyomo\core\base\constraint.py in construct(self, data)
834 for index in self.index_set():
835 self._setitem_when_not_present(
--> 836 index, self.rule(block, index)
837 )
838 except Exception:
c:\users\stephen\python\lib\site-packages\pyomo\core\base\util.py in __call__(self, parent, idx)
302 return self._fcn(parent, *idx)
303 else:
--> 304 return self._fcn(parent, idx)
305
306
<ipython-input-4-cd4b3e07af68> in excess_solar(model, t)
58 def excess_solar(model, t):
59 'Calculating the excess solar if the battery is full'
---> 60 if model.S[t] == model.Smax:
61 return model.excess_pv[t] == demand[t] - solar_forecast[t]
62 else:
pyomo\core\expr\logical_expr.pyx in pyomo.core.expr.logical_expr.EqualityExpression.__nonzero__()
pyomo\core\expr\numeric_expr.pyx in pyomo.core.expr.numeric_expr.ExpressionBase.__call__()
c:\users\stephen\python\lib\site-packages\pyomo\core\expr\visitor.py in evaluate_expression(exp, exception, constant)
1052 visitor = _EvaluationVisitor()
1053 try:
-> 1054 return visitor.dfs_postorder_stack(exp)
1055
1056 except ( TemplateExpressionError, ValueError, TypeError,
c:\users\stephen\python\lib\site-packages\pyomo\core\expr\visitor.py in dfs_postorder_stack(self, node)
582 _sub = _argList[_idx]
583 _idx += 1
--> 584 flag, value = self.visiting_potential_leaf(_sub)
585 if flag:
586 _result.append( value )
c:\users\stephen\python\lib\site-packages\pyomo\core\expr\visitor.py in visiting_potential_leaf(self, node)
960
961 if node.is_numeric_type():
--> 962 return True, value(node)
963 elif node.is_logical_type():
964 return True, value(node)
pyomo\core\expr\numvalue.pyx in pyomo.core.expr.numvalue.value()
pyomo\core\expr\numvalue.pyx in pyomo.core.expr.numvalue.value()
ValueError: No value for uninitialized NumericValue object S[0]
有人知道我应该如何制定约束以解决此问题吗?我们将非常感谢您的帮助,并提前感谢您的帮助
正如@Erwin所提到的,您不能在
if
语句中使用pyomo变量。因为在执行if
语句时,变量的值是未知的。请参阅下面的代码注释,其中列出了有错误的行我认为,如果你使用变量来确定约束是如何形成的,那么整个逻辑可能会有问题。我还没有讨论过您的示例,但我认为
model.S
应该是excess_solar
约束的一部分,而不是用作if语句。过多的太阳能不会影响电池的最佳状态吗? 类似的情况也可能发生在demand constraint
上对于
excess solar
约束,可能是这样的:如果要确保电池电量已满时
model.excess_pv
为0,可以在变量上设置一个界限,使其大于0。这只会导致约束松弛相关问题 更多 >
编程相关推荐