from pulp import *

# Crear el problema de maximización
prob = LpProblem("Problema de selección de proveedores", LpMaximize)

# Variables de decisión
proveedores = ["Proveedor1", "Proveedor2", "Proveedor3"]  # Ejemplo de proveedores
Xi = LpVariable.dicts("X", proveedores, 0, 1, LpBinary)
Yi = LpVariable.dicts("Y", proveedores, lowBound=0, cat='Integer')

# Parámetros
parametros = {
    "Proveedor1": {"costo": 10, "precio_venta": 20, "capacidad": 100},
    "Proveedor2": {"costo": 15, "precio_venta": 25, "capacidad": 150},
    "Proveedor3": {"costo": 12, "precio_venta": 18, "capacidad": 120}
}  # Ejemplo de parámetros combinados

demanda = 150  # Ejemplo de demanda
presupuesto_total = 2000  # Ejemplo de presupuesto total
num_max_proveedores = 2  # Ejemplo de número máximo de proveedores

# Función objetivo
prob += lpSum([(parametros[i]["precio_venta"] - parametros[i]["costo"]) * Yi[i] for i in proveedores]), "Utilidad_Total"

# Restricción de presupuesto
prob += lpSum([parametros[i]["costo"] * Yi[i] for i in proveedores]) <= presupuesto_total, "Restriccion_Presupuesto"

# Restricciones de capacidad
for i in proveedores:
    prob += Yi[i] <= parametros[i]["capacidad"] * Xi[i], f"Restriccion_Capacidad_{i}"

# Restricciones de selección de proveedores
prob += lpSum([Xi[i] for i in proveedores]) <= num_max_proveedores, "Restriccion_Seleccion_Proveedores"

# Restricción de demanda
prob += lpSum([Yi[i] for i in proveedores]) >= demanda, "Restriccion_Demanda"

# Restricción de vínculo entre X e Y
for i in proveedores:
    prob += Yi[i] <= parametros[i]["capacidad"] * Xi[i], f"Restriccion_Vinculo_X_Y_{i}"

# Restricción de no negatividad
for i in proveedores:
    prob += Yi[i] >= 0, f"Restriccion_No_Negatividad_{i}"

# Resolver el problema
prob.solve()

# Imprimir el estado de la solución
print("Estado de la solución:", LpStatus[prob.status])

# Imprimir las variables de decisión
for v in prob.variables():
    print(v.name, "=", v.varValue)

# Calcular la utilidad total
utilidad_total = sum([(parametros[i]["precio_venta"] - parametros[i]["costo"]) * value(Yi[i]) for i in proveedores])

# Imprimir el valor óptimo de la función objetivo (utilidad total)
print("Utilidad Total =", utilidad_total)