0
Tags: mdcvrp, cplex, opl, solver
Published: 2024-04-17 22:14:11

i hope you are all doing good, i have a problem in modelisation of the MDCVRP ( Multi Depot Capacitated Vehicle Routing Problem ) in the CPLEX Studio IDE 22.1.0, can anyone help me on that please ?

here is my mod and dat, when i click run the results appears, but the problem is that the used vehicule does not go back to their warehouses of origin.


Mod :

` // Déclarations des ensembles et indices
int n = ...;
int m = ...;
int v = ...;
// Définition des ensembles et des plages
range Clients = 1..n;  // Inclut les entrepôts et les clients
range Entrepots = 1..m;  // Les premiers indices sont les entrepôts
range Vehicules = 1..v;

// Paramètres
int PO[Clients] = ...;  // Poids des commandes pour chaque client
int VO[Clients] = ...;  // Volume des commandes pour chaque client
int M[Clients] = ...;  // Montant des commandes pour chaque client (0 pour ceux sans commande)
int CPO[Vehicules] = ...;  // Capacité de poids des véhicules
int CVO[Vehicules] = ...;  // Capacité de volume des véhicules
int MO[Vehicules] = ...;  // Montant minimal des commandes pour le démarrage des véhicules
float D[Clients][Clients] = ...;  // Distances entre les points


// Variables de décision
dvar boolean X[Clients][Clients][Vehicules];  // Si le véhicule k emprunte l'arc de i à j
dvar boolean U[Vehicules];  // Si le véhicule k est utilisé
dvar float+ W[Clients];  // Pour l'élimination des sous-tours

// Objectifs: Minimiser la distance totale parcourue et le nombre de véhicules utilisés
minimize
    sum(i in Clients, j in Clients, k in Vehicules) D[i][j] * X[i][j][k];

// Contraintes
subject to {
    // Capacité de poids et volume pour chaque véhicule
    forall(k in Vehicules)
        sum(i in Clients, j in Clients) PO[j] * X[i][j][k] <= CPO[k];
    forall(k in Vehicules)
        sum(i in Clients, j in Clients) VO[j] * X[i][j][k] <= CVO[k];

    // Chaque client est servi exactement une fois, si il a une commande
    forall(j in Clients : M[j] > 0)
        sum(i in Clients, k in Vehicules) X[i][j][k] == 1;

    // Coordination entre X[ijk] et U[k]
    forall(i in Clients, j in Clients, k in Vehicules)
        X[i][j][k] <= U[k];

    // Élimination des sous-tours
    forall(i in Clients, j in Clients : i != j, k in Vehicules)
        W[i] - W[j] + n * X[i][j][k] <= n - 1;

    // Chaque véhicule retourne à son entrepôt d'origine après les livraisons
    forall(k in Vehicules)
        sum(e in Entrepots) sum(i in Clients) X[i][e][k] == U[k];
        
    // Empêcher les véhicules de se "servir eux-mêmes"
    forall(i in Clients, k in Vehicules)
        X[i][i][k] == 0;
        
    // Contraintes de Flux
    forall(j in Clients : j > m, k in Vehicules) // Pour tous les clients (sauf les entrepôts)
    	sum(i in Clients) X[i][j][k] == sum(i in Clients) X[j][i][k];


    // s'assurer que chaque véhicule utilisé atteint le montant minimal des commandes avant de démarrer.
    forall(k in Vehicules)
      sum(i in Clients, j in Clients : M[j] > 0) M[j] * X[i][j][k] >= MO[k] * U[k];
        
}

// Affichage des résultats

execute {
    for(var k in Vehicules) {
        if (U[k].solutionValue > 0.5) {
            writeln("Parcours pour le véhicule ", k, " :");
            var distanceTotale = 0;
            for(var i in Clients) {
                for(var j in Clients) {
                    if (X[i][j][k].solutionValue > 0.5) {
                        writeln(" De ", i, " à ", j, ", distance : ", D[i][j]);
                        distanceTotale += D[i][j];
                    }
                }
            }
            writeln("Distance totale parcourue par le véhicule ", k, " : ", distanceTotale, " unités.");
        }
    }
}

`

Dat 

`n = 9; // Total de clients + entrepôts
m = 3; // Nombre d'entrepôts
v = 4; // Nombre de véhicules disponibles

// Poids des commandes pour chaque client (inclut les entrepôts, avec ou sans commande)
PO = [0, 0, 0, 20, 30, 25, 15, 35, 40 ];

// Volume des commandes pour chaque client
VO = [0, 0, 0, 40, 50, 45, 35, 55, 60 ];

// Montant des commandes pour chaque client (0 indique pas de commande ou un entrepôt)
M = [0, 0, 0, 100, 150, 120, 130, 160, 180 ];

// Capacité de poids des véhicules
CPO = [100, 100, 80, 120 ];

// Capacité de volume des véhicules
CVO = [200, 220, 180, 240 ];

// Montant minimal des commandes pour démarrer les véhicules
MO = [300, 250, 200, 350 ];

// Distances entre les points (clients + entrepôts)
D = [
    [0, 5, 8, 10, 15, 20, 25, 30, 35 ],
    [5, 0, 7, 10, 15, 20, 25, 30, 35 ],
    [8, 7, 0, 3, 8, 13, 18, 23, 28 ],
    [10, 10, 3, 0, 5, 10, 15, 20, 25 ],
    [15, 15, 8, 5, 0, 5, 10, 15, 20 ],
    [20, 20, 13, 10, 5, 0, 5, 10, 15],
    [25, 25, 18, 15, 10, 5, 0, 5, 10 ],
    [30, 30, 23, 20, 15, 10, 5, 0, 5 ],
    [35, 35, 28, 25, 20, 15, 10, 5, 0 ],
 
];



`