[英]Termination condition infeasible for pyomo (solver glpk)
我正在嘗試解決具有 N-1 可靠性約束的功率流優化,這意味着當 1 條線路出現故障時,來自四台發電機的電力仍可以通過剩余的 17 條電力線為 8 個負載供電。
為了解決這個問題,我引入了 3 組 I:節點集(i:1 到 4 是生成器,而 i:5 到 12 是負載) J:邊集(共 18 個) K:場景集(有共18個場景,每條邊出的時候一個場景
變量 p[j,k] 是場景 k 邊 j 的功率流。
我在這個問題上的主要限制是:
我可以運行代碼並使用求解器 glpk,但似乎我設置問題的方式有問題,因為終止條件不可行。
有人可以幫忙解釋一下我的 model 配方有什么問題嗎?
import numpy as np
from pyomo.environ import *
#Max generator output for node 1-4. Nodes 5-12 are not generators so 0.
Gmax_d = {1: 3, 2: 2, 3: 4, 4: 7, 5: 0, 6: 0, 7: 0, 8: 0, 9: 0, 10: 0, 11: 0, 12: 0}
#Cost for each generator
Cost_d = {1: 4, 2: 8, 3: 5, 4: 3, 5: 0, 6: 0, 7: 0, 8: 0, 9: 0, 10: 0, 11: 0, 12: 0}
#Max flow in each edge (total 18 edges)
Pmax_d = {1: 4.8005, 2: 1.9246, 3: 3.4274, 4: 2.9439, 5: 4.5652, 6: 4.0484, 7: 2.8259, 8: 1.074, 9: 4.2856, 10: 2.7788, 11: 3.4617, 12: 4.1677, 13: 4.6873, 14: 3.9528, 15: 1.7051, 16: 2.6228, 17: 4.7419, 18: 4.6676}
#Demand/load at nodes 5-12. Nodes 1-4 are connected to generators so 0.
Demand_d = {1: 0, 2: 0, 3: 0, 4: 0, 5: 1.6154, 6: 2.3405, 7: 1.0868, 8: 1.5293, 9: 2.2197, 10: 1.0148, 11: 1.2083, 12: 1.3041}
#12 by 18 matrix to show the direction between node i and edge j. +1 if the flow is into the node and -1 if the flow is in the direction away from the edge, 0 if the edge j is not connected to node i
A_dict = {(1, 1): -1, (1, 2): -1, (1, 3): 0, (1, 4): 0, (1, 5): 0, (1, 6): 0, (1, 7): 0, (1, 8): 0, (1, 9): 0, (1, 10): 0, (1, 11): 0, (1, 12): 0, (1, 13): 0, (1, 14): 0, (1, 15): 0, (1, 16): 0, (1, 17): 0, (1, 18): 0, (2, 1): 0, (2, 2): 0, (2, 3): -1, (2, 4): -1, (2, 5): 0, (2, 6): 0, (2, 7): 0, (2, 8): 0, (2, 9): 0, (2, 10): 0, (2, 11): 0, (2, 12): 0, (2, 13): 0, (2, 14): 0, (2, 15): 0, (2, 16): 0, (2, 17): 0, (2, 18): 0, (3, 1): 0, (3, 2): 0, (3, 3): 0, (3, 4): 0, (3, 5): 0, (3, 6): 0, (3, 7): 0, (3, 8): 0, (3, 9): 0, (3, 10): -1, (3, 11): -1, (3, 12): 0, (3, 13): 0, (3, 14): 0, (3, 15): 0, (3, 16): 0, (3, 17): 0, (3, 18): -1, (4, 1): 0, (4, 2): 0, (4, 3): 0, (4, 4): 0, (4, 5): 0, (4, 6): 0, (4, 7): -1, (4, 8): 0, (4, 9): 0, (4, 10): 0, (4, 11): 0, (4, 12): 0, (4, 13): 0, (4, 14): 0, (4, 15): -1, (4, 16): 0, (4, 17): -1, (4, 18): 0, (5, 1): 1, (5, 2): 0, (5, 3): 0, (5, 4): 0, (5, 5): 1, (5, 6): -1, (5, 7): 0, (5, 8): 0, (5, 9): 0, (5, 10): 0, (5, 11): 0, (5, 12): 0, (5, 13): 0, (5, 14): 0, (5, 15): 0, (5, 16): 0, (5, 17): 0, (5, 18): 0, (6, 1): 0, (6, 2): 1, (6, 3): 1, (6, 4): 0, (6, 5): -1, (6, 6): 0, (6, 7): 1, (6, 8): -1, (6, 9): 0, (6, 10): 0, (6, 11): 0, (6, 12): 0, (6, 13): 0, (6, 14): 0, (6, 15): 0, (6, 16): 0, (6, 17): 0, (6, 18): 0, (7, 1): 0, (7, 2): 0, (7, 3): 0, (7, 4): 1, (7, 5): 0, (7, 6): 0, (7, 7): 0, (7, 8): 0, (7, 9): -1, (7, 10): 1, (7, 11): 0, (7, 12): 0, (7, 13): 0, (7, 14): 0, (7, 15): 0, (7, 16): 0, (7, 17): 0, (7, 18): 0, (8, 1): 0, (8, 2): 0, (8, 3): 0, (8, 4): 0, (8, 5): 0, (8, 6): 0, (8, 7): 0, (8, 8): 1, (8, 9): 1, (8, 10): 0, (8, 11): 0, (8, 12): 0, (8, 13): -1, (8, 14): 0, (8, 15): 1, (8, 16): 0, (8, 17): 0, (8, 18): 1, (9, 1): 0, (9, 2): 0, (9, 3): 0, (9, 4): 0, (9, 5): 0, (9, 6): 0, (9, 7): 0, (9, 8): 0, (9, 9): 0, (9, 10): 0, (9, 11): 1, (9, 12): -1, (9, 13): 0, (9, 14): 0, (9, 15): 0, (9, 16): 0, (9, 17): 0, (9, 18): 0, (10, 1): 0, (10, 2): 0, (10, 3): 0, (10, 4): 0, (10, 5): 0, (10, 6): 0, (10, 7): 0, (10, 8): 0, (10, 9): 0, (10, 10): 0, (10, 11): 0, (10, 12): 1, (10, 13): 1, (10, 14): -1, (10, 15): 0, (10, 16): 0, (10, 17): 0, (10, 18): 0, (11, 1): 0, (11, 2): 0, (11, 3): 0, (11, 4): 0, (11, 5): 0, (11, 6): 0, (11, 7): 0, (11, 8): 0, (11, 9): 0, (11, 10): 0, (11, 11): 0, (11, 12): 0, (11, 13): 0, (11, 14): 1, (11, 15): 0, (11, 16): 1, (11, 17): 0, (11, 18): 0, (12, 1): 0, (12, 2): 0, (12, 3): 0, (12, 4): 0, (12, 5): 0, (12, 6): 1, (12, 7): 0, (12, 8): 0, (12, 9): 0, (12, 10): 0, (12, 11): 0, (12, 12): 0, (12, 13): 0, (12, 14): 0, (12, 15): 0, (12, 16): -1, (12, 17): 1, (12, 18): 0}
# Creation of a Concrete Model
model = ConcreteModel()
# Sets
model.i = Set(initialize=[1,2,3,4,5,6,7,8,9,10,11,12], doc='Nodes')
model.j = Set(initialize=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18], doc='Edges')
model.k = Set(initialize=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18], doc='Set of scenarios, where in each scenario the flow in edge j is zero so total 18 scenarios')
# Parameters
model.Gmax = Param(model.i,initialize = Gmax_d, doc = 'Maximum generator power')
model.Pmax = Param(model.j, initialize = Pmax_d, doc = 'Maximum power flow ')
model.cost = Param(model.i, initialize = Cost_d, doc = 'Cost to generate power from each generator')
model.demand = Param(model.i, initialize = Demand_d, doc = 'Demand in each electric load node')
model.A = Param(model.i,model.j, initialize = A_dict, doc = 'Incidence matrix')
#Variable
model.g = Var(model.i, bounds=(0.0,None), doc = 'generator power')
model.p = Var(model.j, model.k, bounds =(0.0, None), doc = 'power flow in each edge for each scenario')
#Constraints
def max_gen_power(model, i):
return model.g[i] <= model.Gmax[i]
model.gen_power = Constraint(model.i, rule = max_gen_power, doc = 'Maximum generation capacity')
def max_power_flow_positive(model, j, k):
return model.p[j,k] <= model.Pmax[j]
model.power_flow_positive = Constraint(model.j, model.k, rule = max_power_flow_positive, doc = 'Maximum power flow')
def max_power_flow_negative(model, j, k):
return model.p[j,k] >= -model.Pmax[j]
model.power_flow_negative = Constraint(model.j, model.k, rule = max_power_flow_negative, doc = 'Minimum power flow')
def balance(model, i, k):
return sum(model.A[i,j] * model.p[j,k] for j in model.j) - (-model.g[i] + model.demand[i]) == 0.0
model.flow_balance = Constraint(model.i, model.k, rule = balance, doc ='Balance in every node, total power generated must be equal to the total demand by the loads')
def zeroflow1(model, j, k):
return model.p[1,1] <= 0.0
model.zero_flow1 = Constraint(model.j, model.k, rule = zeroflow1, doc ='zero flow for p11')
def zeroflow1a(model, j, k):
return model.p[1,1] >= 0.0
model.zero_flow1a = Constraint(model.j, model.k, rule = zeroflow1a, doc ='zero flow for p11')
def zeroflow2(model, j, k):
return model.p[2,2] <= 0.0
model.zero_flow2 = Constraint(model.j, model.k, rule = zeroflow2, doc ='zero flow for p22')
def zeroflow2a(model, j, k):
return model.p[2,2] >= 0.0
model.zero_flow2a = Constraint(model.j, model.k, rule = zeroflow2a, doc ='zero flow for p22')
def zeroflow3(model, j, k):
return model.p[3,3] <= 0.0
model.zero_flow3 = Constraint(model.j, model.k, rule = zeroflow3, doc ='zero flow for p33')
def zeroflow3a(model, j, k):
return model.p[3,3] >= 0.0
model.zero_flow3a = Constraint(model.j, model.k, rule = zeroflow3a, doc ='zero flow for p33')
def zeroflow4(model, j, k):
return model.p[4,4] <= 0.0
model.zero_flow4 = Constraint(model.j, model.k, rule = zeroflow4, doc ='zero flow for p44')
def zeroflow4a(model, j, k):
return model.p[4,4] >= 0.0
model.zero_flow4a = Constraint(model.j, model.k, rule = zeroflow4a, doc ='zero flow for p44')
def zeroflow5(model, j, k):
return model.p[5,5] <= 0.0
model.zero_flow5 = Constraint(model.j, model.k, rule = zeroflow5, doc ='zero flow for p55')
def zeroflow5a(model, j, k):
return model.p[5,5] >= 0.0
model.zero_flow5a = Constraint(model.j, model.k, rule = zeroflow5a, doc ='zero flow for p55')
def zeroflow6(model, j, k):
return model.p[6,6] <= 0.0
model.zero_flow6 = Constraint(model.j, model.k, rule = zeroflow6, doc ='zero flow for p66')
def zeroflow6a(model, j, k):
return model.p[6,6] >= 0.0
model.zero_flow6a = Constraint(model.j, model.k, rule = zeroflow6a, doc ='zero flow for p66')
def zeroflow7a(model, j, k):
return model.p[7,7] <= 0.0
model.zero_flow7a = Constraint(model.j, model.k, rule = zeroflow7a, doc ='zero flow for p77')
def zeroflow7(model, j, k):
return model.p[7,7] >= 0.0
model.zero_flow7 = Constraint(model.j, model.k, rule = zeroflow7, doc ='zero flow for p77')
def zeroflow8(model, j, k):
return model.p[8,8] <= 0.0
model.zero_flow8 = Constraint(model.j, model.k, rule = zeroflow8, doc ='zero flow for p88')
def zeroflow8a(model, j, k):
return model.p[8,8] >= 0.0
model.zero_flow8a = Constraint(model.j, model.k, rule = zeroflow8a, doc ='zero flow for p88')
def zeroflow9(model, j, k):
return model.p[9,9] <= 0.0
model.zero_flow9 = Constraint(model.j, model.k, rule = zeroflow9, doc ='zero flow for p99')
def zeroflow9a(model, j, k):
return model.p[9,9] >= 0.0
model.zero_flow9a = Constraint(model.j, model.k, rule = zeroflow9a, doc ='zero flow for p99')
def zeroflow10(model, j, k):
return model.p[10,10] <= 0.0
model.zero_flow10 = Constraint(model.j, model.k, rule = zeroflow10, doc ='zero flow for p1010')
def zeroflow10a(model, j, k):
return model.p[10,10] >= 0.0
model.zero_flow10a = Constraint(model.j, model.k, rule = zeroflow10a, doc ='zero flow for p1010')
def zeroflow11(model, j, k):
return model.p[11,11] <= 0.0
model.zero_flow11 = Constraint(model.j, model.k, rule = zeroflow11, doc ='zero flow for p1111')
def zeroflow11a(model, j, k):
return model.p[11,11] >= 0.0
model.zero_flow11a = Constraint(model.j, model.k, rule = zeroflow11a, doc ='zero flow for p1111')
def zeroflow12(model, j, k):
return model.p[12,12] <= 0.0
model.zero_flow12 = Constraint(model.j, model.k, rule = zeroflow12, doc ='zero flow for p1212')
def zeroflow12a(model, j, k):
return model.p[12,12] >= 0.0
model.zero_flow12a = Constraint(model.j, model.k, rule = zeroflow12a, doc ='zero flow for p1212')
def zeroflow13(model, j, k):
return model.p[13,13] <= 0.0
model.zero_flow13 = Constraint(model.j, model.k, rule = zeroflow13, doc ='zero flow for p1313')
def zeroflow13a(model, j, k):
return model.p[13,13] >= 0.0
model.zero_flow13a = Constraint(model.j, model.k, rule = zeroflow13a, doc ='zero flow for p1313')
def zeroflow14(model, j, k):
return model.p[14,14] <= 0.0
model.zero_flow14 = Constraint(model.j, model.k, rule = zeroflow14, doc ='zero flow for p1414')
def zeroflow14a(model, j, k):
return model.p[14,14] >= 0.0
model.zero_flow14a = Constraint(model.j, model.k, rule = zeroflow14a, doc ='zero flow for p1414')
def zeroflow15(model, j, k):
return model.p[15,15] <= 0.0
model.zero_flow15 = Constraint(model.j, model.k, rule = zeroflow15, doc ='zero flow for p1515')
def zeroflow15a(model, j, k):
return model.p[15,15] >= 0.0
model.zero_flow15a = Constraint(model.j, model.k, rule = zeroflow15a, doc ='zero flow for p1515')
def zeroflow16(model, j, k):
return model.p[16,16] <= 0.0
model.zero_flow16 = Constraint(model.j, model.k, rule = zeroflow16, doc ='zero flow for p1616')
def zeroflow16a(model, j, k):
return model.p[16,16] >= 0.0
model.zero_flow16a = Constraint(model.j, model.k, rule = zeroflow16a, doc ='zero flow for p1616')
def zeroflow17(model, j, k):
return model.p[17,17] <= 0.0
model.zero_flow17 = Constraint(model.j, model.k, rule = zeroflow17, doc ='zero flow for p1717')
def zeroflow17a(model, j, k):
return model.p[17,17] >= 0.0
model.zero_flow17a = Constraint(model.j, model.k, rule = zeroflow17a, doc ='zero flow for p1717')
def zeroflow18(model, j, k):
return model.p[18,18] <= 0.0
model.zero_flow18 = Constraint(model.j, model.k, rule = zeroflow18, doc ='zero flow for p1818')
def zeroflow18a(model, j, k):
return model.p[18,18] >= 0.0
model.zero_flow18a = Constraint(model.j, model.k, rule = zeroflow18a, doc ='zero flow for p1818')
#Objective Function
def objective_rule(model):
return sum(model.cost[i] * model.g[i] for i in model.i)
model.objective = Objective(rule = objective_rule, sense = minimize, doc = 'Cost minimization')
#Display Output
def pyomo_postprocess(options=None, instance=None, results=None):
model.g.display()
if __name__ == '__main__':
# This emulates what the pyomo command-line tools does
from pyomo.opt import SolverFactory
import pyomo.environ
opt = SolverFactory("glpk")
results = opt.solve(model)
#sends results to stdout
results.write()
print("\nDisplaying Solution\n" + '-'*60)
pyomo_postprocess(None, model, results)
您錯誤地構建了“零流量”約束。 你這樣做:
def zeroflow1(model, j, k):
return model.p[1,1] <= 0.0
model.zero_flow1 = Constraint(model.j, model.k, rule = zeroflow1, doc ='zero flow for p11')
其中,當使用這種類型的構造時,將J
和K
的每個值傳遞給該約束的構造。 因此,如果您pprint
,您會發現您設置了太多約束 (| J
| * | K
|)。 它們是重復的,因為您在值1
中進行了硬編碼。 效率低下,但可能不會殺死 model。
你想對每個場景進行限制,所以你唯一應該傳遞給 function 的是場景,並使用它,巧合的是與節點號相同,只限制場景 - 節點組合中的功率。 刪除所有這些並執行以下操作:
def zero_flow(model, scenario):
# we know scenario == node number of interest by problem definition... so:
node = scenario # unneccessary, but adds clarity
return model.p[node, scenario] == 0
model.scenario_constraint = Constraint(model.k, rule=zero_flow)
注意,如果你這樣做,問題的狀態仍然是不可行。 為什么? 這是不可能分辨的,因為你在那里埋下了 18.network 流量問題,你不知道哪一個有問題。 老實說,我會寫一個適當的 .network 流問題並分析它(不使用優化——不是必需的),看看 .network 是否可以在每個場景中做你想做的。
如果您更改約束並只運行前 2 個場景:
model.k = Set(initialize=[1,2])
model 解決了問題,所以這 2 個可以工作,但是您將運行生成器來同時滿足所有陣容中最嚴格的要求,也許這不是您想要的?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.