Skip to content

Pulp returns 0 on an optimization problem #838

@neliafedele

Description

@neliafedele

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 %

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions