我试图在Pyomo上运行以下代码。使用具体模型是一个简单的传输扩展问题。
谢谢jsiirola。我其实只是在学习Pyomo,这就是为什么我可能犯了愚蠢的错误。我实施了你所建议的所有内容,如下所示:
from pyutilib.misc import import_file
from pyomo.environ import *
import networkx as nx
model = ConcreteModel()
model.name = "DTEPM_trial_concrete"
#Sets
#Epoch
model.E = Set(initialize = [0, 1, 2, 3])
model.E_n = Set(model.E, initialize = {0:[1,2,3,4,5], 1:[6,7,8,9,10], 2:[11,12,13,14,15], 3:[16,17,18,19,20]})
#System nodes
model.N = ['N1', 'N2', 'N3']
model.n_name= Param(model.N, within = Integers)
#T = Set()
model.G = ['G1', 'G2', 'G3']
model.LI = ['L1', 'L2', 'L3']
#Scalar Parameters
model.int_rate = 0.05
model.vll = 3000
model.tau_period = 8760
def R_discount_inv_init(model, i):
return sum(1 / (1 + model.int_rate)**(i - 1) for i in model.E)
model.cum_disc_inv_cost = Param(model.E, initialize = R_discount_inv_init)
def R_discount_op_init(model, i):
for index in model.E_n:
return sum(1 / (1 + model.int_rate)**(i - 1) for i in model.E_n[index])
model.cum_disc_op_cost = Param(model.E, initialize = R_discount_op_init)
#Demand Periods
model.t_demand = {'N1': 1.05, 'N2': 2.10, 'N3': 7.35}
model.demand_curtailed = Var(model.E, model.N, within = NonNegativeReals)
#Generation Units
model.ge_max = {'G1': 2.00, 'G2': 2.00, 'G3': 7.35}
model.ge_marginal_cost = {'G1': 30, 'G2': 35, 'G3': 40}
model.B = {('N1','G1'): 1, ('N1','G2'): 0, ('N1','G3'): 0, ('N2','G1'): 0, ('N2','G2'): 1, ('N2','G3'): 0, ('N3','G1'): 0, ('N3','G2'): 0, ('N3','G3'): 1,}
#Transmission lines
model.li_x = {'L1': 0.2, 'L2': 0.2, 'L3': 0.2}
model.li_max_f = 1.50
model.li_f = {'L1': 1.00, 'L2': 1.00, 'L3': 1.00}
model.li_sending_bus = {'L1': 'N1', 'L2': 'N1', 'L3': 'N2'}
model.li_receiving_bus = {'L1': 'N2', 'L2': 'N3', 'L3': 'N3'}
model.li_length = {'L1': 100, 'L2': 100, 'L3': 100}
#Expansion Options
model.inv_cost_var = 4000000
nodes = ['N1', 'N2', 'N3']
edges = [['N1', 'N2'], ['N1', 'N3'], ['N2', 'N3']]
I = nx.DiGraph()
I.add_nodes_from(nodes)
I.add_edges_from(edges)
model.I = -nx.incidence_matrix(I, oriented=True) # this returns a scipy sparse matrix
#Variables
#Transmission line power flow limits
def fl_inv(model, i, l):
return (0, model.li_max_f)
model.li_f_inv = Var(model.E, model.LI, bounds = fl_inv)
#Transmission line investment and operation contraints
model.f = Var(model.LI, model.E, initialize=0)
def fl_rule(model, l, j, i):
if i:
return model.f[l,j] >= -(model.li_f_inv[j,l] + model.li_f[l])
else:
return model.f[l,j] <= (model.li_f_inv[j,l] + model.li_f[l])
model.bound_f = Constraint(model.LI, model.E, [0,1], rule=fl_rule)
#generation limit
def fg(model, i, g):
return (0, model.ge_max[g])
model.ge_output = Var(model.G, model.E, initialize = 0, bounds = fg)
#phase angles for the nodes
model.theta = Var(model.E, model.N, within = NonNegativeReals)
def line_equation(model, e, l):
return model.bound_f[l] == (1/model.li_x(l) for l in model.LI) *(sum(model.theta[n] for n in model.N if model.n_name[n] == model.li_sending_bus[l]) - sum(model.theta[n] for n in model.N if model.n_name[n] == model.li_receiving_bus[l]))
model.line_equation = Constraint(model.LI, model.E, rule = line_equation)
def system_balance(model, e, n):
return sum(model.b[n, g] * model.ge_output[g] for g in model.G) \
+ sum(model.I[n, l] * model.f[l] for l in model.LI) \
- sum(model.t_demand[n] - model.demand_curtailed[n]) == 0
model.SystemBalance = Constraint(model.E, model.N, rule=system_balance)
#OBJECTIVE FUNCTION
def objective_mincost(model):
return sum( model.cum_disc_inv_cost[e] for e in model.E * sum (model.li_f_inv[l] * model.inv_cost_var[l] * model.li_length[l]) + model.cum_disc_op_cost[e] * (model.tau_period * (sum(model.ge_max[g] * (model.ge_marginal_cost[g])) + sum(model.demand_curtailed[n] * model.vll))))
model.objective = Objective(rule = objective_mincost, sense = minimize)
opt = SolverFactory('gurobi')
results = opt.solve(model) # solves and updates instance
model.display()
但收到以下新错误消息:
错误:为索引(&#39; L3&#39;,0)生成约束line_equation的表达式时规则失败: KeyError:&#34;访问索引组件时出错:索引&#39; L3&#39;对于数组组件&#39; bound_f&#39;&#34;无效 错误:构建组件&line -equation&#39;来自data =无失败: KeyError:&#34;访问索引组件时出错:索引&#39; L3&#39;对于数组组件&#39; bound_f&#39;&#34;
无效请问您认为可能出错了什么?
谢谢
答案 0 :(得分:1)
如错误所示,您没有将有效索引传递给model.li_f_inv
规则中的model.f
。您的Var model.li_f_inv
声明为:
model.li_f_inv = Var(model.E, model.LI, bounds = fl_inv)
model.f
的当前规则只是将一个索引传递给model.li_f_inv
,这是无效的。这意味着您需要更新model.f
的规则以传递正确的索引:
#Transmission line investment and operation contraints
model.f = Var(model.LI, model.E, initialize=0)
def fl_rule(model, l, j, i):
if i:
return model.f[l,j] >= -(model.li_f_inv[j,l] + model.li_f[l])
else:
return model.f[l,j] <= (model.li_f_inv[j,l] + model.li_f[l])
model.bound_f = Constraint(model.LI, model.E, [0,1], rule=fl_rule)
另请注意,您要在model.f
的定义和fl_rule
函数隐含的集合之间转置索引集。
编辑:我没注意到在你的原始帖子中,你试图在另一个变量(li_f_inv
)的边界中使用变量(f
)。这不是一个有效的数学程序(更不用说,不是有效的Pyomo)。您需要将变量边界表示为约束。此外,虽然Pyomo允许您表达范围约束(lb <= body <= ub
),但lb
和ub
都不可能是可变的。由于这不是这种情况,因此必须单独表达两个边界约束。