簡體   English   中英

pyomo 的終止條件不可行(求解器 glpk)

[英]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 的功率流。

我在這個問題上的主要限制是:

  1. 0<g[i]<G[i]max 對於每個 i
  2. -Pmax[j]<p[j,k]<Pmax[j](每條邊的Pmax對於所有場景都是一樣的)
  3. sum(over j) a[i,j]*p[j,k]-(-g[i]+d[i])=0 for every i, for every k (這是每個節點的功率平衡,假設線路或節點上沒有功率損耗) 4 p[1,1]=p[2,2]=p[3,3]=p[4,4]=.....p[118,18] =0(這是為了滿足每條邊上的流量為零的 18 種不同場景。

我可以運行代碼並使用求解器 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')

其中,當使用這種類型的構造時,將JK每個值傳遞給該約束的構造。 因此,如果您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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM