简体   繁体   English

如何在 CPLEX-python 中添加和删除约束?

[英]How to add and remove constraints in CPLEX-python?

I new using Cplex in python.我在 python 中使用了 Cplex。 I already know how to code a mathematical optimization problem correctly and create a function to show the solution friendly (F1).我已经知道如何正确编写数学优化问题并创建 function 以显示解决方案友好 (F1)。 Currently, I want to modify some features of the model without creating a new model.目前,我想修改 model 的一些功能,而不创建新的 model。 My idea is solving a model P, then a model P1 (changing the decision variables domain), P2 (relaxing some set o constraints), and so on.我的想法是解决 model P,然后是 model P1(更改决策变量域),P2(放宽一些约束),等等。 I would like to have the solution of those models using my function F1.我想使用我的 function F1 获得这些模型的解决方案。

My code is the following:我的代码如下:

import time
import numpy as np
import cplex
from cplex import Cplex
from cplex.exceptions import CplexError
import sys
from openpyxl import Workbook
import xlrd

def GAP_RL(I,J,data):
    #TIEMPO INICIAL
    inicio=time.process_time() #------------------------------- INICIO DEL CONTEO DE TIEMPO
    #CONJUNTOS
    maquinas=range(I)  #CONJUNTO DE TRABAJOS
    trabajos=range(J)  #CONJUNTO DE MÁQUINAS
    #print("MÁQUINAS={} | TRABAJOS= {} |\n".format(list(maquinas),list(trabajos)))
    print("\n")
    #PARÁMETROS
    wb = Workbook()
    ws = wb.active
    book = xlrd.open_workbook(data+'.xlsx')           
    sheet = book.sheet_by_name("c")
    c_a=[[int(sheet.cell_value(r,c)) for c in range(sheet.ncols)] for r in range(sheet.nrows)]
    c_a=np.matrix(c_a)  
    print("COSTO DE ASIGNACIÓN")      
    print("")         
    print(c_a) # ------------------------------------------------ COSTO DE ASIGNACIÓN
    print("\n")
    sheet = book.sheet_by_name("a")
    a=[[int(sheet.cell_value(r,c)) for c in range(sheet.ncols)] for r in range(sheet.nrows)]
    a=np.matrix(a)  
    print("UTILIZACIÓN")      
    print("")         
    print(a) #---------------------------------------------------- REQUERIMIENTOS   
    print("\n")
    sheet = book.sheet_by_name("b")
    b=[[int(sheet.cell_value(r,c)) for c in range(sheet.ncols)] for r in range(sheet.nrows)]
    b=np.matrix(b)  
    print("DISPONIBILIDAD")      
    print("")         
    print(b) #---------------------------------------------------- CAPACIDAD MÁXIMA DE PROCESO
    print("\n")

    Model=cplex.Cplex()                                                  #CREACIÓN DEL MODELO.

    Model.parameters.mip.tolerances.integrality.set(0)                   #ESPECIFICA LA CANTIDAD POR LA CUAL UNA 
                                                                         #VARIABLE ENTERA PUEDE SER DIFERENTE DE UN 
                                                                         #ENTERO Y AÚN ASÍ CONSIDERASE FACTIBLE
    Model.objective.set_sense(Model.objective.sense.minimize)            #SENTIDO DE OPTIMIZACIÓN.

    #Model.parameters.timelimit.set(float(7200))                         #TIEMPO MÁXIMO DE EJECUCIÓN [SEGUNDOS].

    #Model.parameters.mip.tolerances.mipgap.set(float(0.1))              #GAP DE TÉRMINO.

    #VARIABLES DE DECISIÓN
    x_vars=np.array([["x("+str(i)+","+str(j)+")" for j in trabajos] for i in maquinas])
    x_varnames = x_vars.flatten()
    x_vartypes='B'*I*J
    x_varlb = [0.0]*len(x_varnames)
    x_varub = [1.0]*len(x_varnames)
    x_varobj = []
    for i in maquinas:
        for j in trabajos:
            x_varobj.append(float(c_a[i,j]))
    Model.variables.add(obj = x_varobj, lb = x_varlb, ub = x_varub, types = x_vartypes, names = x_varnames)
    #RESTRICCIONES

    #PRIMER CONJUNTO DE RESTRICCIONES: CADA TRABAJO ES ASIGNADO A UNA ÚNICA MÁQUINA.
    for j in trabajos:
        row1=[]
        val1=[]
        for i in maquinas:
            row1.append(x_vars[i,j])
            val1.append(float(1.0))
        Model.linear_constraints.add(lin_expr = [cplex.SparsePair(ind = row1, val= val1)], senses = 'E', rhs = [float(1.0)])

    #SEGUNDO CONJUNTO DE RESTRICCIONES: LAS ASIGNACIONES DE TRABAJOS CONSIDERAN LA CAPACIDAD MÁXIMA DE PROCESAMIENTO DE LAS MÁQUINAS
    for i in maquinas:
        row2=[]
        val2=[]
        for j in trabajos:
            row2.append(x_vars[i,j])
            val2.append(float(a[i,j]))
        Model.linear_constraints.add(lin_expr = [cplex.SparsePair(ind = row2, val= val2)], senses = 'L', rhs = [float(b[i])])
    #RESOLVER MODELO Y EXPANDIR
    solution=Model.solve() 
    Model.write('modelo_GAP.lp') 
    #MOSTRAR SOLUCION
    def show_solution():
        print("--------------------------------------------------------------------------------------------------------------")
        print("\nVALOR FUNCIÓN OBJETIVO - COSTO TOTAL DE ASIGNACIÓN = {}".format(Model.solution.get_objective_value()))
        print("--------------------------------------------------------------------------------------------------------------")

        for i in maquinas:
            for j in trabajos:
                if(Model.solution.get_values("x("+str(i)+","+str(j)+")")!=0.0):
                    print("x("+str(i+1)+","+str(j+1)+")"+" = "+str(Model.solution.get_values("x("+str(i)+","+str(j)+")")))
        fin=time.process_time()
        tiempo=float(fin)-float(inicio)
        print("")
        print("TIEMPO DE CÓMPUTO [s]= ", float(tiempo))
    show_solution()
GAP_RL(I=2,J=7,data='data')

The data file is the following:数据文件如下:

The matrix c_a is the following:矩阵 c_a 如下: 在此处输入图像描述

The matrix a is the following:矩阵 a 如下: 在此处输入图像描述

The matrix b is the following:矩阵 b 如下: 在此处输入图像描述

So I would like to know how to make those changes in my model which is written in that way.所以我想知道如何在以这种方式编写的 model 中进行这些更改。 Thanks in advance.提前致谢。

Here are a few tips to get you headed in the right direction:这里有一些提示可以帮助您朝着正确的方向前进:

  1. The add methods (eg, Cplex.variables.add , Cplex.linear_constraints.add ) return an iterator containing the indices that were added to the model. add方法(例如, Cplex.variables.addCplex.linear_constraints.add )返回一个迭代器,其中包含添加到 model 的索引。 You can use this to remember the indices for classes of variables or constraints that you want to modify.您可以使用它来记住要修改的变量或约束类别的索引。 For example:例如:

     varind = list(Model.variables.add(obj = x_varobj, lb = x_varlb, ub = x_varub, types = x_vartypes, names = x_varnames))
  2. Alternately, if you give names to the variables/constraints, you can query or modify them by name.或者,如果您为变量/约束命名,您可以按名称查询或修改它们。 This can result in a performance hit, though, so read this section in the User's Manual.但是,这可能会导致性能下降,因此请阅读用户手册中的这一部分。

  3. You can change the lower and upper bounds of variables using Cplex.variables.set_lower_bounds and Cplex.variables.set_upper_bounds .您可以使用Cplex.variables.set_lower_boundsCplex.variables.set_upper_bounds更改变量的下限和上限。

  4. You can remove linear constraints with Cplex.linear_constraints.delete .您可以使用Cplex.linear_constraints.delete删除线性约束。

  5. Finally, you can create a copy (aka clone) of your model by passing an existing model to the Cplex constructor.最后,您可以通过将现有 model 传递给Cplex构造函数来创建 model 的副本(也称为克隆)。 For example:例如:

     Model1 = cplex.Cplex(Model)

you can do that very easily with the docplex python API.您可以使用 docplex python API 轻松做到这一点。

from docplex.mp.model import Model

# original model

mdl = Model(name='buses')
nbbus40 = mdl.integer_var(name='nbBus40')
nbbus30 = mdl.integer_var(name='nbBus30')
mdl.add_constraint(nbbus40*40 + nbbus30*30 >= 300, 'kids')
mdl.minimize(nbbus40*500 + nbbus30*400)

mdl.solve()



for v in mdl.iter_integer_vars():
    print(v," = ",v.solution_value)

#now remove the constraint

print()
print("now 0 kids instead of 300")    

mdl.get_constraint_by_name("kids").rhs=0;
mdl.solve()

for v in mdl.iter_integer_vars():
    print(v," = ",v.solution_value)

# and now let 's adapt to Covid19 1 seat out of 2

print("now 40 seats buses take 20 children and same ratio for 30 seats buses") 

mdl.add_constraint(nbbus40*20 + nbbus30*15 >= 300, 'kidsCov19')

mdl.solve()

for v in mdl.iter_integer_vars():
    print(v," = ",v.solution_value)

which gives这使

nbBus40  =  6.0
nbBus30  =  2.0

now 0 kids instead of 300
nbBus40  =  0
nbBus30  =  0
now 40 seats buses take 20 children and same ratio for 30 seats buses
nbBus40  =  15.0
nbBus30  =  0

I have used the zoo and bus example我使用了动物园和公共汽车的例子

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM