-
-
Notifications
You must be signed in to change notification settings - Fork 423
Description
What is your question
I have to solve an optimization problem with pulp but it only returns 0. Do you know what I can change to make it work ?
Input:
Import PuLP modeler functions
from pulp import *
import pandas as pd
import numpy as np
from itertools import combinations
import math as mt
InputData = '/Users/neliafedele/Documents/Documents/PRONTO CODE/InputDataEnergyEquity.xlsx'
Source nœuds
v0 = pd.read_excel(InputData, "SourceNum", header=None)
v0 = v0[0][0]
Nombre de nœuds
nb_nodes = pd.read_excel(InputData, "Nodes", header=None)
Nœuds coordonnées en 2D
coord_nodes = pd.read_excel(InputData, "NodesCord", header=None)
Pertes fixes aux arrêtes
vfix = pd.read_excel(InputData, "vfix(thetaijfix)", header=None)
Pertes variables aux arrêtes
vvar = pd.read_excel(InputData, "vvar(thetaijvar)", header=None)
Coût unitaire fixe
unit_cost = pd.read_excel(InputData, "FixedUnitCost", header=None)
Coût variable d'investissement aux sommets
cvar = pd.read_excel(InputData, "cvar(cijvar)", header=None)
Coût de génération de chaleur à la source
cheat = pd.read_excel(InputData, "cheat(ciheat)", header=None)
Coût d'opération et d'entretien aux sommets
com = pd.read_excel(InputData, "com(cijom)", header=None)
Revenue pour la chaleur délivrée aux sommets
crev = pd.read_excel(InputData, "crev(cijrev)", header=None)
Effet de la concurrence
Betta = pd.read_excel(InputData, "Betta", header=None)
Quota de connexion
Lambda = pd.read_excel(InputData, "Lambda", header=None)
Facteur d'annuité pour les coûts d'investissement
alpha = pd.read_excel(InputData, "Alpha", header=None)
Dictionnary with the edges demand peak dij
cdem_peak = pd.read_excel(InputData, "EdgesDemandPeak(i)", header=None)
Dictionnary with the surface of the edges
s = pd.read_excel(InputData, "Surface(i)", header=None)
Dictionnary with the surface conception of the edges
Scon = pd.read_excel(InputData, "SurfaceConsumption(i)", header=None)
Dictionnary with the Cmax
Cmax = pd.read_excel(InputData, "Cmax(cijmax)", header=None)
Dictionnary with the sources maximun capacity
Qv0max = pd.read_excel(InputData, "SourceMaxCap(Qimax)", header=None)
Dictionnary with the consumer type of the edges
ctype = pd.read_excel(InputData, "ConsumerType(i)", header=None)
Dictionnary with the equity threshold of the edges
equity = pd.read_excel(InputData, "EquityThreshold", header=None)
Dictionnary with the consumer type number of the edges
nbtype = pd.read_excel(InputData, "ConsumerTypeNumber", header=None)
Créer la contrainte d'optimisation
problem = LpProblem("Optimisation_reseau_de_chaleur", LpMaximize)
V = range(20) # Ensemble des nœuds
Variables de décision
f = LpVariable.dicts("f", (V, V), lowBound=0, cat="Continuous") # Flux de chaleur
x = LpVariable.dicts("x",(V, V), lowBound=0, cat="Binary") # Décision d'investissement, 1 si le réseau est construit, 0 sinon
q = LpVariable.dicts("q", (V, V), lowBound=0, cat="Continuous") # Chaleur produite par la source
Pin = LpVariable.dicts("Pin", (V, V), lowBound=0, cat="Continuous") # Puissance injectée
Pout = LpVariable.dicts("Pout", (V, V),lowBound=0, cat="Continuous") # Puissance sortante
Longueur des connexions
def lenght(i, j):
return ((coord_nodes[0][i] - coord_nodes[0][j]) ** 2 + (coord_nodes[1][i] - coord_nodes[1][j]) ** 2) ** 0.5
Déclaration des fonctions intermédiaires
Revenue totale
for i in V:
for j in V:
if i != j:
total_revenue = lpSum(crev * s[0][j] * Lambda * Scon[0][j] * x[i][j])
Côut total de chaleur
for i in V:
for j in V:
if j != v0:
total_heat_generation_cost = lpSum((cheat / Betta * Qv0max) * s[0][j] * Scon[0][j] * lpSum(Pin[v0][j]))
for i in V:
for j in V:
if i != j:
Total fixed investment cost
total_fixed_investment_cost = lpSum(alpha * unit_cost * x[i][j] * lenght(i,j))
Variable investment cost
total_variable_investment_cost =lpSum( alpha * cvar[i][j] * lenght(i,j) * Pin[i][j])
Coût d'opération et d'entretien
total_maintenance_cost = lpSum(com[i][j] * x[i][j] * lenght(i,j))
Fonction objectif : Maximisation du gain
problem += ( total_revenue
- ( total_heat_generation_cost
+ total_fixed_investment_cost
+ total_variable_investment_cost
+ total_maintenance_cost)), "Maximisation du gain"
Contraintes
Uniderictionalité des arêtes
for j in V:
for i in V:
problem += x[i][j] + x[j][i] <= 1, f"Unidirectionnalite_{i}_{j}"
Satisfaction de la demande et pertes thermiques
for i in V:
for j in V:
if i != j and j != v0:
problem += Pin[i][j] - Pout[i][j] == Pin[i][j] * lenght(i,j) * vvar[i][j] + Lambda * x[i][j] * s[0][j] * Scon[0][j] * Betta + x[i][j] * vfix[i][j] * lenght(i,j), f"Satisfaction_demande_{i}_{j}"
Equilibre du flux thermique dans les nœuds (hors source)
for i in V:
for j in V :
if i != j and j != v0:
problem += lpSum(Pout[i][j]) - lpSum(Pin[j][i]) == 0, f"Equilibre_flux_{i}_{j}"
Capacité maximale des tuyaux
for i in V:
for j in V:
if i != j and i != v0 and j != v0:
problem += Pin[i][j] <= Cmax[i][j] * x[i][j], f"Capacite_maximale_{i}_{j}"
Structure de la source
for j in V :
if j != v0:
problem += x[j][v0] == 0, f"Structure_source_y_{j}"
Capacité maximale de production de la source
for j in V :
if j != v0:
problem += lpSum(Pin[v0][j]) <= Qv0max, f"Capacite_maximale_source_{j}"
Elimination des cycles
for i in V:
for j in V :
if j != i:
problem += lpSum(x[i][j]) <= 1, f"Elimination_cycle_{i}_{j}"
Domaine des variables
for i in V:
for j in V:
if i != j:
problem += x[i][j] ==0 or x[i][j] == 1, f"Domaine_variables_{i}{j}"
problem += Pin[i][j] >= 0, f"Non_negativity_in{i}{j}"
problem += Pout[i][j] >= 0, f"Non_negativity_out{i+1}_{j}"
Résolution du problème
problem.solve()
Affichage des résultats
print(" Résultats de l'optimisation :")
for v in problem.variables():
print(f"{v.name} = {v.varValue}")
print(f" Statut de la solution : {LpStatus[problem.status]}")
print(f" Valeur optimale du profit : {value(problem.objective)}")
Output:
Welcome to the CBC MILP Solver
Version: 2.10.12
Build Date: Aug 20 2024
command line - cbc /var/folders/8q/hqcvy4zn4xsb9yfqgglm1fkc0000gn/T/8489a39ef25a41aab122a98c49c59713-pulp.mps -max -timeMode elapsed -branch -printingOptions all -solution /var/folders/8q/hqcvy4zn4xsb9yfqgglm1fkc0000gn/T/8489a39ef25a41aab122a98c49c59713-pulp.sol (default strategy 1)
At line 2 NAME MODEL
At line 3 ROWS
At line 3027 COLUMNS
At line 8656 RHS
At line 11679 BOUNDS
At line 12080 ENDATA
Problem MODEL has 3022 rows, 1160 columns and 4827 elements
Coin0008I MODEL read with 0 errors
Option for timeMode changed from cpu to elapsed
Continuous objective value is 0 - 0.00 seconds
Cgl0002I 380 variables fixed
Cgl0004I processed model has 0 rows, 0 columns (0 integer (0 of which binary)) and 0 elements
Cbc3007W No integer variables - nothing to do
Cuts at root node changed objective from -0 to 1.79769e+308
Probing was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
Gomory was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
Knapsack was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
Clique was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
MixedIntegerRounding2 was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
FlowCover was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
TwoMirCuts was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
ZeroHalf was tried 0 times and created 0 cuts of which 0 were active after adding rounds of cuts (0.000 seconds)
Result - Optimal solution found
Objective value: 0.00000000
Enumerated nodes: 0
Total iterations: 0
Time (CPU seconds): 0.01
Time (Wallclock seconds): 0.01
Option for printingOptions changed from normal to all
Total time (CPU seconds): 0.01 (Wallclock seconds): 0.02
Statut de la solution : Optimal
Valeur optimale du profit : 0.0
neliafedele@device-125 PRONTO CODE %