我用pyomo设置了一个更大的能量最佳化问题。设置花费了不合理的时间,如其他问题中提到的,但是我设法加快了大多数有问题的线路,除了能量流限制。
与所有其他约束相反,流包括所有元素的总和。所以我决定重写流变量的创建方式,这样它们就包括了所有元素的索引,希望这能改善这种情况。我的代码现在看起来像这样:
def flows(model, et, t):
return pyo.quicksum(model.in_flow[:, et, t],
linear=True,
start=pyo.quicksum(model.out_flow[:, et, t],
linear=True)
) == 0
model.add_component("flows",
pyo.Constraint(model.energy_type,
model.t,
rule=flows)
)
然而,这仍然需要65%的模型设置时间。
我将其分解为一个嵌套的for循环,只是为了看看谁花时间:
for t in model.t:
for et in model.energy_type:
e = model.in_flow[:, et, t]
f = model.out_flow[:, et, t]
es = pyo.quicksum(e)
fs = pyo.quicksum(f)
这需要大约相同的运行时间,并且“全部”都花费在最后两行中。将quicksums链接起来并设置线性标志会带来一些小的改进,但没有实质性的改进。PyPSA的共享代码仍然使用旧的coopr3表达式生成器,因此不再工作。我也不知道如何使用它。
关于如何提高模型生成性能的任何建议?
原来问题出在切片上。
def flows(model, et, t):
vars = [model.in_flow[obj, et, t] for obj in model.objects_index]
vars.extend([model.out_flow[obj, et, t] for obj in model.objects_index])
return pyo.quicksum(vars) == 0
这种约束规则的重新模拟将我的模型创建速度提高了大约60%。我找到了另外两个地方,在那里我做了类似的重新表述。我现在从优化前的120秒下降到大约7秒。