I new using Cplex in python. I already know how to code a mathematical optimization problem correctly and create a function to show the solution friendly (F1). Currently, I want to modify some features of the model without creating a new 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. I would like to have the solution of those models using my 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:
The matrix a is the following:
The matrix b is the following:
So I would like to know how to make those changes in my model which is written in that way. Thanks in advance.
Here are a few tips to get you headed in the right direction:
The add methods (e.g., Cplex.variables.add, Cplex.linear_constraints.add) return an iterator containing the indices that were added to the 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))
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.
You can change the lower and upper bounds of variables using Cplex.variables.set_lower_bounds and Cplex.variables.set_upper_bounds.
You can remove linear constraints with Cplex.linear_constraints.delete.
Finally, you can create a copy (aka clone) of your model by passing an existing model to the Cplex constructor. For example:
Model1 = cplex.Cplex(Model)
you can do that very easily with the 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
Related
While creating a tkinter GUI application, I created a window with a button to close the program and terminate the script, but when I used it, the program did close but the script was still running in the background and I was unable to start the program again.
I have tried several different functions to close the program, but nothing has worked. Here are some of my attempts:
def Cerrar():
summary.destroy()
No = customtkinter.CTkButton(summary, text="Cerrar", command=Cerrar,width=10)
or
No = customtkinter.CTkButton(summary, text="Cerrar", command=lambda:Cerrar(),width=10)
or
No = customtkinter.CTkButton(summary, text="Cerrar", command=lambda:summary.destroy(),width=10)
here is the window im having a problem with:
def Analisis():
global resumen,cuantia,summary,refuerzo
Denom_Malla = "{}-{}".format(Malla.get(),Separacion.get())
denominacion_mallas = ["4-25","4-20","4-15","4.5-15","5-15","5.5-15",
"6-15","6.5-15","7-15","7.5-15","8-15","8.5-15",
"4-12.5","4-10","4-7.5","4.5-7.5","5-7.5","5.5-7.5",
"6-7.5","6.5-7.5","7-7.5","7.5-7.5","8-7.5","8.5-7.5"]
if Denom_Malla in denominacion_mallas:
fc = int(Fc.get())
fy_malla = int(Fy_Malla.get())
fy_barra = int(Fy_Barra.get())
mu = float(Mu.get())
H = float(h.get())
Rec = float(rec.get())
malla = Malla.get()
separacion = Separacion.get()
denom_barra = int(Denom_Barra.get())
resumen, cuantia_calculada, d, Rn, cuantia_min, cuantia_diseño, As,Sep_Barra = Calculo_Losa(fc, fy_malla, fy_barra, mu, H, Rec, malla, separacion, denom_barra)
root.destroy()
if resumen == None:
root_losas(lista_fc.index(str(fc)),lista_fy.index(str(fy_malla)),lista_fy.index(str(fy_barra)),lista_mallas.index(malla),lista_denombarra.index(str(denom_barra)),mu,H,Rec,lista_separacion.index(str(separacion)))
else:
summary = customtkinter.CTk()
summary.title("Resumen")
summary.minsize(width=300,height=150)
customtkinter.CTkLabel(summary, text="Momento Último calculado es de: {} KN-m".format(mu)).grid(row=0,column=0,columnspan=2)
customtkinter.CTkLabel(summary, text="La cuantía calculada es de: {}".format(round(cuantia_diseño,4))).grid(row=1,column=0,columnspan=2)
customtkinter.CTkLabel(summary, text="Para la losa se necesita una malla {}".format(resumen)).grid(row=2,column=0,columnspan=2)
customtkinter.CTkLabel(summary, text="Desea realizar otro análisis?").grid(row=3,column=0,columnspan=2)
customtkinter.CTkLabel(summary, text="En que tipo de refuerzo desea guardar: ").grid(row=2,column=3)
refuerzo = customtkinter.StringVar(value=lista_refuerzo[0])
refuerzo_Box = customtkinter.CTkOptionMenu(summary, variable=refuerzo, values=lista_refuerzo, width=100)
refuerzo_Box.grid(row=3,column=3,padx=15)
refuerzo_Box.configure(cursor="hand2")
Yes = customtkinter.CTkButton(summary, text="Analizar", command=lambda:Siguiente(fc,fy_malla,fy_barra,malla,denom_barra,mu,H,Rec,separacion),width=10)
Yes.grid(row=4,column=0)
Yes.configure(cursor="hand2")
Guardar = customtkinter.CTkButton(summary, text="Guardar", command=lambda:Save(fc,fy_malla,mu,1,H,Rec,d,Rn,cuantia_calculada,cuantia_min,cuantia_diseño,As,malla,separacion,denom_barra,Sep_Barra,resumen))
Guardar.grid(row=4,column=3,pady=15)
Guardar.configure(cursor="hand2")
No = customtkinter.CTkButton(summary, text="Cerrar", command=Cerrar,width=10)
No.grid(row=4,column=1)
No.configure(cursor="hand2")
summary.mainloop()
else:
tk.messagebox.showerror(title="Error Malla", message="La denominacion de la malla elegida no está registrada.")
`
everything's fine? I hope so.
I'm dealing with this issue: List index out of range. -
Error message:
c:\Users.....\Documents\t.py:41: FutureWarning: As the xlwt package is no longer maintained, the xlwt engine will be removed in a future version of pandas. This is the only engine in pandas that supports writing in the xls format. Install openpyxl and write to an xlsx file instead. You can set the option io.excel.xls.writer to 'xlwt' to silence this warning. While this option is deprecated and will also raise a warning, it can be globally set and the warning suppressed.
read_file.to_excel(planilhaxls, index = None, header=True)
The goal: I need to create a loop that store a specific line of a worksheet such as sheet_1.csv, this correspondent line in sheet_2.csv and a third sheet also, stored in 3 columns in a sheet_output.csv
Issue: It's getting an index error out of range that I don't know what to do
Doubt: There is any other way that I can do it?
The code is below:
(Please, ignore portuguese comments)
import xlrd as ex
import pyautogui as pag
import os
import pyperclip as pc
import pandas as pd
import pygetwindow as pgw
import openpyxl
#Inputs
numerolam = int(input('Escolha o número da lamina: '))
amostra = input('Escoha a amostra: (X, Y, W ou Z): ')
milimetro_inicial = int(input("Escolha o milimetro inicial: "))
milimetro_final = int(input("Escolha o milimetro final: "))
tipo = input("Escolha o tipo - B para Branco & E para Espelho: ")
linha = int(input("Escolha a linha da planilha: "))
# Conversão de código
if tipo == 'B':
tipo2 = 'BRA'
else:
tipo2 = 'ESP'
#Arquivo xlsx
#planilhaxlsx = f'A{numerolam}{amostra}{milimetro_inicial}{tipo2}.xlsx'
#planilhaxls = f'A{numerolam}{amostra}{milimetro_inicial}{tipo2}.xls'
#planilhacsv = f'A{numerolam}{amostra}{milimetro_inicial}{tipo2}.csv'
#planilhacsv_ = f'A{numerolam}{amostra}{milimetro_final}{tipo2}.csv'
#arquivoorigin = f'A{numerolam}{amostra}{milimetro_inicial}{tipo2}.opj'
#Pasta
pasta = f'L{numerolam}{amostra}'
while milimetro_inicial < milimetro_final:
planilhaxlsx = f'A{numerolam}{amostra}{milimetro_inicial}{tipo2}.xlsx'
planilhaxls = f'A{numerolam}{amostra}{milimetro_inicial}{tipo2}.xls'
planilhacsv = f'A{numerolam}{amostra}{milimetro_inicial}{tipo2}.csv'
planilhacsv_ = f'A{numerolam}{amostra}{milimetro_final}{tipo2}.csv'
arquivoorigin = f'A{numerolam}{amostra}{milimetro_inicial}{tipo2}.opj'
# Converte o arquivo .csv para .xls e .xlsx
read_file = pd.read_csv(planilhacsv)
read_file.to_excel(planilhaxls, index = None, header=True)
#read_file.to_excel(planilhaxlsx, index = None, header=True)
# Abre o arquivo .xls com o xlrd - arquivo excel.
book = ex.open_workbook(planilhaxls)
sh = book.sheet_by_index(0)
# Declaração de variáveis.
coluna_inicial = 16 # Q - inicia em 0
valor = []
index = 0
# Loop que armazena o valor da linha pela coluna Q-Z na variável valor 0-(len-1)
while coluna_inicial < 25:
**#ERRO NA LINHA ABAIXO**
**temp = sh.cell_value(linha, coluna_inicial)**
valor.append(temp) # Adiciona o valor
print(index)
print(valor[index])
index +=1
coluna_inicial += 1
# Abre planilha de saída
wb = openpyxl.Workbook()
ws = wb.active
#Inicia loop de escrita
colunas = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']
idx_colunas = 0
contador_loop = colunas[idx_colunas]
linha_loop = 1
index_out = 0
s = f'{contador_loop}{linha_loop}'
print(s)
while linha_loop < len(valor):
valor[index_out] = "{}".format(valor[index_out])
ws[s].value = valor[index_out]
print(valor[index_out] + ' feito')
linha_loop += 1
idx_colunas += 1
index_out += 1
# Salva planilha de saída
wb.save("teste.xlsx")
milimetro_inicial += 1
Your problem is on this line
temp = sh.cell_value(linha, coluna_inicial)
There are two index params used linha and coluna_inicial, 'linha' appears to be a static value so the problem would seem to be with 'coluna_inicial' which gets increased by 1 each iteration
coluna_inicial += 1
The loop continues while 'coluna_inicial' value is less than 25. I suggest you check number of columns in the sheet 'sh' using
sh.ncols
either for debugging or as the preferred upper value of your loop. If this is less than 25 you will get the index error once 'coluna_inicial' value exceeds the 'sh.ncols' value.
<---------------Additional Information---------------->
Since this is an xls file there would be no need for delimiter settings, your code as is should open it correctly. However since the xls workbook to be opened is determined by params entered by the user at the start presumably meaning there are a number in the directory to choose from, are you sure you are checking the xls file your code run is opening? Also if there is more than one sheet in the workbook(s) are you opening the correct sheet?
You can print the workbook name to be sure which one is being opened. Also by adding verbosity to the open_workbook command (level 2 should be high enough), it will upon opening the book, print in console details of the sheets available including number of rows and columns in each.
print(planilhaxls)
book = ex.open_workbook(planilhaxls, verbosity=2)
sh = book.sheet_by_index(0)
print(sh.name)
E.g.
BOF: op=0x0809 vers=0x0600 stream=0x0010 buildid=14420 buildyr=1997 -> BIFF80
sheet 0('Sheet1') DIMENSIONS: ncols=21 nrows=21614
BOF: op=0x0809 vers=0x0600 stream=0x0010 buildid=14420 buildyr=1997 ->
BIFF80
sheet 1('Sheet2') DIMENSIONS: ncols=13 nrows=13
the print(sh.name) as shown checks the name of the sheet that 'sh' is assigned to.
this issue appear when I put promedios[x] = float(punteos / 3), if suppose to x is in for outside have a int value like possition. I modified the code with the new changes
def alumno(nombre, apellido):
print('Nombre: ', nombre, 'Apellido: ', apellido)
def promedio(a,b,c):
promedio1 = int(a+b+c)/3
#return promedio1
print(promedio1)
nombre = input('ingrese nombre: ')
apellido = input('ingrese apellido: ')
alumno(nombre,apellido)
print()
#promedio(1,2,3)
print('Ingrese los punteos de las Materias:')
punteo = 0
materias = 5
for x in range(0, materias):
punteos = 0
notas = 3
promedio1 = 0
promedios = []
xx = 1
for y in range(0, notas):
punteo = int(input("Ingrese punteo de la Materia "+str(x+1)+" punteo "+str(y+1)+": "))
punteos = int(punteos + punteo)
promedio1 = float(punteos/3)
promedios.append(promedio1)
print('El promedio de la materia ',x+1,' es ',promedio1)
print(promedios[x])
As long as you have done promedios = 0 and no longer modify the variable promedios before the line of code promedios[x] = float(punteos / 3), promedios is an int at that line.
However, doing promedios[x] = ... calls the __setitem__ method of variable promedios, which is of type int and of course does not support such item assignment.
Types like list, dict support item assignment, by the way.
You need to start with an empty list:
promedios = []
And then append to it:
promedios.append(float(punteos / 3))
I want an activity to scrapy a web page. The part of data web is route_data.
route_data = ["javascript:mostrarFotografiaHemiciclo( '/wc/htdocs/web/img/diputados/peq/215_14.jpg', '/wc/htdocs/web', 'Batet Lamaña, Meritxell (Presidenta del Congreso de los Diputados)', 'Diputada por Barcelona', 'G.P. Socialista' ,'','');",
"javascript:mostrarFotografiaHemiciclo( '/wc/htdocs/web/img/diputados/peq/168_14.jpg', '/wc/htdocs/web', 'Rodríguez Gómez de Celis, Alfonso (Vicepresidente Primero)', 'Diputado por Sevilla', 'G.P. Socialista' ,'','');",]
I create a dictionary with empty values.
dictionary_data = {"Nombre":None, "Territorio":None, "Partido":None, "url":None}
I have to save in dictionary_data each one line:
url = /wc/htdocs/web/img/diputados/peq/215_14.jpg
Nombre = Batet Lamaña, Meritxell
Territorio = Diputada por Barcelona
Partido = G.P. Socialista
For thus, and I loop over route_data.
for i in route_data:
text = i.split(",")
nombre = text[2:4]
territorio = text[4]
partido = text[5]
But the output is:
[" 'Batet Lamaña", " Meritxell (Presidenta del Congreso de los Diputados)'"] 'Diputada por Barcelona' 'G.P. Socialista'
[" 'Rodríguez Gómez de Celis", " Alfonso (Vicepresidente Primero)'"] 'Diputado por Sevilla' 'G.P. Socialista'
How can it get put correct in dictionary?
A simple solution would be:
all_routes = []
for i in route_data:
text = re.findall("'.+?'", i)
all_routes.append(
{"Nombre": re.sub('\(.*?\)', '', text[2]).strip(),
"Territorio": text[3],
"Partido": text[-2],
"Url": text[0]})
I am trying to develop an application to calculate the surplus value on the IRPJ. It consists of, if the value of the IRPJ is greater than 60k, calculate 10% over the excess of 60k, but I am not able to put the second value as a variable, it gives the following error:
l_calcirpj = Label(calc, text='O valor a ser pago de IRPJ é de: {:.2f}'.format(irpj2))
UnboundLocalError: local variable 'irpj2' referenced before assignment
Follow the code below:
from tkinter import *
# ---
calc = Tk()
calc.title('mikaelson')
calc.geometry('350x350')
# ---
l_receita = Label(text='Receita')
l_receita.place(x=15, y=15)
e_receita = Entry(calc)
e_receita.place(x=100, y=15)
# ---
def calcular():
receita = float(e_receita.get())
# ---
irpj = receita * 32 / 100
if irpj > 60000:
irpj2 = (irpj - 60000) * 10 / 100
else:
print('menor que 60k')
l_calcirpj = Label(calc, text='O valor a ser pago de IRPJ é de: {:.2f}'.format(irpj2))
l_calcirpj.place(x=15, y=60)
# ---
e_receita.delete(0, END)
bt = Button(calc, text='Calcular', command=calcular)
bt.place(x=15, y=95)
calc.mainloop()
The variable irpj2 is only created if irpj>60000. Try creating the variable and initialising it to a sensible default (e.g. 0) outside of the if statement.