[英]How to add and remove constraints in CPLEX-python?
我在 python 中使用了 Cplex。 我已經知道如何正確編寫數學優化問題並創建 function 以顯示解決方案友好 (F1)。 目前,我想修改 model 的一些功能,而不創建新的 model。 我的想法是解決 model P,然后是 model P1(更改決策變量域),P2(放寬一些約束),等等。 我想使用我的 function F1 獲得這些模型的解決方案。
我的代碼如下:
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')
數據文件如下:
所以我想知道如何在以這種方式編寫的 model 中進行這些更改。 提前致謝。
這里有一些提示可以幫助您朝着正確的方向前進:
add
方法(例如, Cplex.variables.add 、 Cplex.linear_constraints.add )返回一個迭代器,其中包含添加到 model 的索引。 您可以使用它來記住要修改的變量或約束類別的索引。 例如:
varind = list(Model.variables.add(obj = x_varobj, lb = x_varlb, ub = x_varub, types = x_vartypes, names = x_varnames))
或者,如果您為變量/約束命名,您可以按名稱查詢或修改它們。 但是,這可能會導致性能下降,因此請閱讀用戶手冊中的這一部分。
您可以使用Cplex.variables.set_lower_bounds和Cplex.variables.set_upper_bounds更改變量的下限和上限。
您可以使用Cplex.linear_constraints.delete刪除線性約束。
最后,您可以通過將現有 model 傳遞給Cplex構造函數來創建 model 的副本(也稱為克隆)。 例如:
Model1 = cplex.Cplex(Model)
您可以使用 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)
這使
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
我使用了動物園和公共汽車的例子
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.