Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/344.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 二维变量的SOS2约束_Python_Mathematical Optimization_Pyomo_Piecewise - Fatal编程技术网

Python 二维变量的SOS2约束

Python 二维变量的SOS2约束,python,mathematical-optimization,pyomo,piecewise,Python,Mathematical Optimization,Pyomo,Piecewise,我希望lambda的每一行(m.lbd[n,:])都有一个SOS2约束。lambda的每一行中有不同数量的元素。 目标变量具有从.dat文件加载的以下集合: set setNK := (1, 1) (1, 2) (1, 3) (1, 4) (1, 5) (1, 6) (2, 1) (2, 2) (2, 3) (2, 4) (2, 5) (2, 6) (2, 7) (2, 8) (3, 1)

我希望lambda的每一行(m.lbd[n,:])都有一个SOS2约束。lambda的每一行中有不同数量的元素。 目标变量具有从.dat文件加载的以下集合:

set setNK := 
   (1, 1)
   (1, 2)
   (1, 3)
   (1, 4)
   (1, 5)
   (1, 6)

   (2, 1)
   (2, 2)
   (2, 3)
   (2, 4)
   (2, 5)
   (2, 6)
   (2, 7)
   (2, 8)
   
   (3, 1)
   (3, 2)
   (3, 3)
   (3, 4)
   (3, 5)
   (3, 6)
   (3, 7)
   (3, 8)
   (3, 9)
   (4, 1)
   (4, 2)
   (4, 3)
   (4, 4)
   (4, 5)
   
   (5, 1)
   (5, 2)
   (5, 3)
   (5, 4)
   (5, 5)
   (6, 1)
   (6, 2)
   (6, 3)
   (6, 4)
   (6, 5)
   (6, 6)
   (6, 7)
   (6, 8)
   
   (7, 1)
   (7, 2)
   (7, 3)
   (7, 4)
   (7, 5)
   (7, 6)
   (7, 7)
   (7, 7)
    
   (8, 1)
   (8, 2)
   (8, 3)
   (8, 4)
   (8, 5)
   (8, 6);

set setK := 1 2 3 4 5 6 7 8 9;
set setN := 1 2 3 4 5 6 7 8; 

#---------------

table N := 1;

set setN := 1; 
set setK := 1 2 3 4 5 6;
set setNK := 
   (1, 1)
   (1, 2)
   (1, 3)
   (1, 4)
   (1, 5)
   (1, 6);
set setN_KEND :=
    (1,6);

param K := 
   1 6;

param lb_inj := 
   1 225;

   
param ub_inj := 
   1 1485;

#table Qinj_max := 50;
#table Qinj_max := 1000;
table Qinj_max := 1500;

table Qliq_max := 5500;
table Qgas_max := 6000;


param WCut := 
   1 0.4567;
 
param GOR := 
   1 1.9642;

   
table Qinj(n,k) Qoil(n,k):
  n k Qinj Qoil:=
  1 1 0.000000 0.000000
  1 2 225.000000 290.000000
  1 3 314.000000 324.000000
  1 4 672.000000 386.000000
  1 5 768.000000 391.000000
  1 6 1485.000000 433.000000

;


模型构造:

m = AbstractModel()
m.setNK = Set()
m.lbd = Var(setNK, bounds=(0,1))
...
data = DataPortal
data.load(filename='p1.dat')
m_instance = m.create_instance(data)
...

m.SOS2_c = SOS2Constraint(setN, var=m.lbd, index=setK, sos=2)
运行脚本会出现错误:

if type(sosSet) is list or sosSet is UnindexedComponent_set or len(sosSet) == 1:

TypeError: object of type 'int' has no len()
应能够根据SOS.py中给出的示例创建N个SOS约束:

    Example:

      model = AbstractModel()
      model.A = Set()
      model.B = Set(A)
      model.X = Set(B)

      model.C1 = SOSConstraint(model.A, var=model.X, set=model.B, sos=1)

    This constraint actually creates one SOS-1 constraint for each
    element of model.A (e.g., if |A| == N, there are N constraints).
    In each constraint, model.X is indexed by the elements of
    model.B[a], where 'a' is the current index of model.A.

      model = AbstractModel()
      model.A = Set()
      model.X = Var(model.A)

      model.C2 = SOSConstraint(var=model.X, sos=2)

    This produces exactly one SOS-2 constraint using all the variables
    in model.X.
我做错了什么

完整脚本:

# -*- coding: utf-8 -*-
"""
Created on Wed Sep 16 21:26:33 2020

@author: lsi
"""

from pyomo.environ import *
from pyomo.gdp import Disjunct
import matplotlib.pyplot as plt
import numpy as np
from pyomo.kernel import sos
import inspect
data = DataPortal()
data.load(filename='p1.dat')


data_list = [tup[1] for tup in list(data.items())]
N = data_list[0]
setN = data_list[1]
setK = data_list[2]
K = [data_list[5][n+1] for n in range(N)]
lb_inj = [data_list[6][n+1] for n in range(N)]
ub_inj = [data_list[7][n+1] for n in range(N)]
Qinj_max = data_list[8]
Qliq_max = data_list[9]
Qgas_max = data_list[10]
WCut = [data_list[11][n+1] for n in range(N)]
GOR = [data_list[12][n+1] for n in range(N)]
Qinj = [[data_list[13][n+1,k+1] for k in range(K[n])]for n in range(N)]
Qoil = [[data_list[14][n+1,k+1] for k in range(K[n])]for n in range(N)]




# %% create model
def general_model():
    m = AbstractModel()
    
    m.N = Param() # number of wells
    m.setN = Set()
    
    m.K = Param(m.setN) # number of breakpoint for each well "n"
    m.setK = Set() # set of breakpoints for each well
    
    m.setNK = Set()
    m.setN_KEND = Set()
    
    m.Qinj = Param(m.setN,m.setK,domain=NonNegativeReals)
    m.Qoil = Param(m.setN,m.setK,domain=NonNegativeReals)
    
    m.Qinj_max = Param(domain=NonNegativeReals)
    m.Qliq_max = Param(domain=NonNegativeReals)
    m.Qgas_max = Param(domain=NonNegativeReals)
    
    m.GOR = Param(m.setN)
    m.WCut = Param(m.setN)
    Disjunct()
    m.lb_inj = Param(m.setN)
    m.ub_inj = Param(m.setN)
    
    m.y = Var(m.setN, bounds = (0,1), within=Binary)#, initialize=0)
    m.Qinj_var = Var(m.setN, within=NonNegativeReals, initialize=225)#, initialize= max(_inj))
    m.Qoil_var = Var(m.setN, within=NonNegativeReals)#, initialize=0)
    m.Qw_var = Var(m.setN, within=NonNegativeReals)#, initialize=0)
    m.Qg_var = Var(m.setN, within=NonNegativeReals)#, initialize=0)
    m.lbd = Var(m.setNK, bounds=(0,1), within=NonNegativeReals)
    
    
    
    
    # %% Objective
    def objRule(m):
        return sum(m.Qoil_var[:])
    
    # %% Well constraints
    def inj_constraint(m):
        return sum(m.Qinj_var[k] for k in m.setN) <= m.Qinj_max
    def liq_constraint(m):
        return sum(m.Qoil_var[k] + m.Qw_var[k] for k in m.setN) <= m.Qliq_max
    def gas_constraint(m):
        return sum(m.Qinj_var) + sum(m.Qg_var) <= m.Qgas_max
    def q_g_constraint(m, i):
        return m.Qg_var[i] == m.GOR[i] * m.Qoil_var[i]
    def q_w_constraint(m,i):
        return m.Qw_var[i] == m.WCut[i]/(1-m.WCut[i]) * m.Qoil_var[i]
    def q_inj_binary_constraint_lb(m,i):
        return m.Qinj_var[i] >= m.lb_inj[i]*m.y[i]
    def q_inj_binary_constraint_ub(m,i):
        return m.Qinj_var[i] <= m.ub_inj[i]*m.y[i]
    def y_relaxed_constraint(m,i):
        return m.y[i] <= 1
    
    m.c_inj = Constraint(rule=inj_constraint)
    m.c_liq = Constraint(rule=liq_constraint)
    m.c_gas = Constraint(rule=gas_constraint)
    m.c_q_g = Constraint(m.setN, rule=q_g_constraint)
    m.c_q_w = Constraint(m.setN, rule=q_w_constraint)
    m.c_q_inj_bin_lb = Constraint(m.setN, rule=q_inj_binary_constraint_lb)
    m.c_q_inj_bin_ub = Constraint(m.setN, rule=q_inj_binary_constraint_ub)
    m.c_y_relaxed = Constraint(m.setN, rule=y_relaxed_constraint)
    m.OBJ = Objective(rule=objRule, sense=maximize)

    return m

# %% Convex Combination Constraints
def add_CC_constraints(m):
    m.z = Var(m.setNK,within=Binary, initialize=0)#, initialize=0)
    
    def CC_x_constraint(m,n):
        Qinj_n = list(m.Qinj[n,:])
        return  sum([m.lbd[n,k+1] * Qinj_n[k] for k in range(K[n-1])])== m.Qinj_var[n]
    def CC_y_constraint(m,n):
        Qoil_n = list(m.Qoil[n,:])
        return  sum([m.lbd[n,k+1] * Qoil_n[k] for k in range(K[n-1])])== m.Qoil_var[n]
    def CC_lbd_sum_constraint(m,n):
        return 1 == sum(m.lbd[n,:])
    def CC_lbd_k_constraint(m,n,k):
        return m.lbd[n,k] <= m.z[n,k]
    def CC_lbd_end_constraint(m,n,k):
        return m.lbd[n,k] <= m.z[n,k]
    def CC_z_constraint(m,n):
        return sum(m.z[n,:]) == 1
    
    m.CC_x = Constraint(m.setN, rule=CC_x_constraint)
    m.CC_y = Constraint(m.setN, rule=CC_y_constraint)
    m.CC_lbd = Constraint(m.setN,rule=CC_lbd_sum_constraint)
    m.CC_lbd_k = Constraint(m.setNK, rule=CC_lbd_k_constraint)
    m.CC_lbd_end = Constraint(m.setN_KEND, rule=CC_lbd_end_constraint)
    m.CC_z = Constraint(m.setN,rule=CC_z_constraint)
    return m

# %% SOS2
def add_SOS2_constraints(m):
    m.z = Var(m.setN,domain=PositiveIntegers)
    m.SOSset = Set(dimen=3)
    
    def SOS2_x_constraint(m,n):
        return sum([m.lbd[n,k+1]*m.Qinj[n,k+1] for k in range(m.K[n])]) == m.Qinj_var[n]
    
    def SOS2_y_constraint(m,n):
        return sum([m.lbd[n,k+1]*m.Qoil[n,k+1] for k in range(m.K[n])]) == m.Qoil_var[n]
    
    def SOS2_z_ub_constraint(m,n):
        return m.z[n] <= 1
    
    def SOS2_lbd_constraint(m,n):
        return sum(m.lbd[n,:]) == 1
    
    # def SOS2_left_branching_constraint(m,n):
    #     return m.lbd[n,slice(0,m.z[n])] == 0
    
    # def SOS2_right_branching_constraint(m,n):
    #     return m.lbd[n,slice(m.z[n]+2,m.K[n])] == 0
    
    
    m.SOS2_x = Constraint(m.setN, rule=SOS2_x_constraint)
    m.SOS2_y = Constraint(m.setN, rule=SOS2_y_constraint)
    m.SOS2_z_ub = Constraint(m.setN, rule=SOS2_z_ub_constraint)
    m.SOS2_lbd = Constraint(m.setN, rule=SOS2_lbd_constraint)
    
    m.SOS2_lbd_SOS2 = SOSConstraint(m.setN, var=m.lbd, index=m.setK, sos=2)
    return m



# %% Construct CC-model
m_general = general_model()
m_CC = add_CC_constraints(m_general.clone())
m_SOS2 = add_SOS2_constraints(m_general.clone())

m_CC_instance = m_CC.create_instance(data)
m_SOS2_instance = m_SOS2.create_instance(data)
m_SOS2_instance = add_lbd_SOS2_constraint(m_SOS2_instance)
#%% Solve

opt = SolverFactory('glpk')
results_CC = opt.solve(m_CC_instance)
results_SOS2 = opt.solve(m_SOS2_instance)

# %% Retrieve solution:
Qinj_sol_CC = list(m_CC_instance.Qinj_var.get_values().values())
Qoil_sol_CC = list(m_CC_instance.Qoil_var.get_values().values())

# %% Plot
fig1, ax1 = plt.subplots(num=1)
K = m_CC_instance.K.sparse_values()
Qoil_vals = m_CC_instance.Qoil.sparse_values()
Qinj_vals = m_CC_instance.Qinj.sparse_values()
Qoil_vec = []
Qinj_vec = []

ind = 0
for i in range(len(K)):
    ax1.plot(Qinj[i], Qoil[i], label='Well'+str(i))
    ax1.scatter(Qinj_sol_CC[i], Qoil_sol_CC[i])
    ind += K[i]
ax1.legend()
plt.show()