Au lieu de rejoindre
Lorsque les processus de collecte et de traitement des déchets sont entièrement ajustés en Russie, ce n'est pas facile à dire, mais je ne veux pas participer à la reconstitution des décharges maintenant. Par conséquent, dans de nombreuses grandes villes, d'une manière ou d'une autre, il existe des mouvements de volontaires engagés dans une collecte séparée particulière.
À Novossibirsk, une telle activité se forme autour de la campagne Green Squirrel, dans le cadre de laquelle une fois par mois, les citadins soucieux de l'environnement apportent à un certain moment des déchets ménagers recyclables accumulés vers des lieux prédéterminés. En même temps, un camion loué arrive sur place, qui emmène les matières recyclables collectées et triées sur le site, d'où il est redistribué entre les différentes entreprises de transformation. L'action existe depuis 2014, et depuis lors, le nombre de points de collecte pour les matières recyclables, ainsi que ses volumes, a considérablement augmenté. Pour le routage des camions, un simple regard ne suffisait pas et nous avons commencé à développer des modèles d'optimisation pour minimiser les coûts de transport. Le premier de ces modèles fait l'objet de cet article.
Dans la section 1, je décrirai en détail et avec des illustrations le schéma d'organisation de l'action. En outre, dans la section 2, la tâche de minimiser les coûts de transport sera formalisée comme la tâche de routage des véhicules hétérogènes problème de routage des véhicules de la flotte avec des fenêtres de temps. La section 3 est consacrée à la résolution de ce problème à l'aide d'un package librement distribué pour résoudre les problèmes de programmation mathématique linéaire à nombres entiers mixtes GLPK.
1. L'action "Ecureuil vert"
Depuis 2014, le groupe d'initiative
Living Earth mène une campagne mensuelle pour séparer la collecte d'
écureuil vert recyclé à Novossibirsk. Au moment de la rédaction du présent document, le recyclage avec un certain nombre de réserves est accepté comme déchet plastique étiqueté PET, PE, PP, PS, verre, aluminium, fer, appareils électroménagers, vieux papiers et plus encore. Plus de 50 bénévoles participent à la préparation et à la conduite de l'action. L'action n'est pas commerciale, sa participation est gratuite et n'implique pas de récompense monétaire.
Des pointsL'action se déroule à 17 points de la ville, situés les uns des autres à des distances couvertes par la voiture dans une période de 15 à 90 minutes. Un de ces points sur la photo: des sacs à gauche le long du mur pour collecter diverses fractions de plastique, à droite - un camion, dans lequel tout est chargé à l'avenir, et au centre - un volontaire avec des oreilles.

Toutes les activités au point sont organisées par des conservateurs qui ont des restrictions sur le moment où ils sont prêts à remplir leurs fonctions. Lors de la planification d'une action, les conservateurs signalent l'intervalle de temps pendant lequel l'action doit se terminer à leur point.
Il existe également des données sur les volumes moyens de matières recyclables collectées à chaque point.
ItinérairesLes points sont organisés en parcours successivement conduits par un camion. Les mouvements des camions sont surveillés par des superviseurs d'itinéraire qui surveillent l'environnement opérationnel et prennent des décisions sur la gestion des événements spéciaux.
CamionsSont loués sur une base commune dans le cadre de propositions de location horaire de véhicules de fret. Il n'est pas possible de compacter le plastique en place, donc le paramètre principal caractérisant le camion est le volume de la caisse. La capacité de charge dans notre cas n'est pas un facteur limitant.
Les principales dépenses de l'action sont liées au paiement de la location de camions, donc sa réduction est critique pour l'existence et le développement de notre part, qui acquiert une signification institutionnelle dans le sens de former des idées sur la consommation responsable. Ensuite, une approche pour résoudre ce problème sera décrite, basée sur l'application de méthodes d'optimisation discrètes, à savoir la programmation mathématique.
2. Formalisation
Dans la construction du modèle mathématique, nous resterons dans le cadre de programmes linéaires à nombres mixtes, pour lesquels la connaissance de l'algèbre de classe 7 est suffisante.
La seule difficulté peut être associée à l'utilisation de la notation abstraite et des signes de sommation dans les formules. J'espère que cela n'effraie pas les lecteurs qui ont des rencontres peu fréquentes avec des textes mathématiques.
Dans le modèle d'optimisation, quatre composants peuvent être distingués:
- la formation de groupes de points qui composent un itinéraire distinct;
- définition d'un plan de détour pour chacun des groupes;
- répondre aux exigences relatives à l'heure d'arrivée du camion à chaque point;
- détermination du type de camion nécessaire pour desservir chacun des itinéraires.
Nous considérons chacune des parties, en introduisant la notation nécessaire si nécessaire.
Regroupement de pointsSoit
V = \ {1, \ dots, n \}V = \ {1, \ dots, n \} il existe de nombreux indices de points de collecte pour les matières recyclables, et le site où les matières recyclables collectées sont ensuite transportées - nous l'appellerons un
dépôt - a un indice de 0.
\ bar {V} = V \ cup \ {0 \}\ bar {V} = V \ cup \ {0 \}Chaque groupe de points forme un itinéraire distinct. À travers
R désignent l'ensemble des numéros de route.
Laissez la quantité
zir,i inI,r inR est égal à un si le point
i inclus dans l'itinéraire avec le numéro
r et zéro sinon. Ensuite, l'exigence que le point
i inV doit entrer l'un des itinéraires peut être écrit comme
sumr inRzir=zi1+zi2+ dots+zin=1.
Le dépôt doit saisir toutes les routes:
z0r=1,r inRSubtilitésMalheureusement, un tel enregistrement crée des problèmes de calcul associés à la symétrie de la région admissible. Il peut être éliminé en ajoutant un certain nombre de restrictions garantissant le choix d'une décomposition lexicographiquement minimale. Vous pouvez en savoir plus à ce sujet en russe, par exemple,
ici .
1−zir leq sumi−1j=1 left(1− sumr−1k=1zjk right)+ sumr−1k=1zik, quadi inI,r inR,r leqi.
Définition d'un détourLes itinéraires sont une séquence alternée de points et de croisements entre eux. Formellement, ils commencent tous à l'un des points de l'ensemble
V et se terminent au dépôt, cependant, il sera plus facile de supposer que toutes les routes sont cycliques. Cette hypothèse ne change pas l'essence, mais rend tous les sommets identiques: dans ce cas, il n'y a pas de sommets d'extrémité, ils sont tous en transit.
Pour les points
i,j in barV et itinéraire
r inR configurer une variable
xijr égal à un si dans l'itinéraire avec un numéro
r camion se déplaçant du point
i au point
j et zéro sinon.
Ensuite, nous exigeons, premièrement, que le camion se déplaçant le long de l'itinéraire
r inR visité le point
i inV si elle, après avoir divisé en groupes, est tombée dans le groupe avec le nombre
r :
sumj in barVxjir=zir, quadi in barV,r inR.
Deuxièmement, le camion après son arrivée au point
i in barV doit la quitter.
sumj in barVxjir= sumj in barVxijr, quadi in barV,r inR.
Vous remarquerez peut-être que ces restrictions autorisent les quantités
xijr Définissez des routes qui sont un ensemble de boucles disjointes. Les itinéraires de ce type n'ont bien entendu aucun sens et un certain nombre de restrictions sont nécessaires pour éviter cela.
À propos de l'élimination des sous-cyclesUne façon pourrait consister à introduire des quantités auxiliaires non négatives
fijr,i,j in barV,r inR L'ensemble des relations enregistrées à l'aide de ces quantités élimine les combinaisons de valeurs
xijr définir des routes qui ne sont pas une boucle connectée.
sumi inVf0jr= sumi inVzir, quadr inR,
fijr leqnxijr, quadi in barV,j in barV,r inR,
sumj in barVfjir= sumj in barVfijr+zir, quadi inV,r inR.
Ces ratios spécifient le flux du dépôt vers le reste des points de routage. À chaque point intermédiaire, une unité de flux est absorbée, donc pour que le réseau ait un flux de puissance égal au nombre de points moins un, il est nécessaire que la route soit connectée.
Satisfaire aux exigences au moment de l'arrivée du camion à chaque pointEn d'autres termes, vous devez visiter les points uniquement à l'intérieur des fenêtres temporelles indiquées par les conservateurs. À travers
Bi et
Ei indiquent respectivement le début et la fin de l'intervalle de temps dans lequel le conservateur du point
i peut y assister.
Pour suivre la mise en œuvre de ces restrictions, nous avons besoin d'informations sur le temps passé par le camion lors des arrêts et des traversées sur l'itinéraire. À travers
Li,i inV désigne la durée du chargement au point
i , et par
Dij,i,j in barV - le temps de se déplacer d'un point
i au point
j Nous faisons une réservation
D0i=0 pour tous
i in barV , et peut généralement être effectuée
Dij neqDji pour tout
i neqjNous introduisons des variables non négatives
ai,i in barV et
wir,i in barV,r inR égal aux heures d'arrivée et aux temps d'attente au point
i lors de la conduite sur un itinéraire
r , respectivement. Pour les valeurs saisies, les relations suivantes doivent être satisfaites.
Le temps d'attente ne peut être inférieur au temps de chargement
wir geqLizir, quadi in barV,r inR,
et égal à zéro si le point n'appartient pas à l'itinéraire
rwir leqMzir, quadi in barV,r inR,
Heure d'arrivée au point
j calculé aux moments appropriés pour le point précédent
i Voici une constante assez grande
M utilisé pour éliminer les dépendances inutiles lors du déplacement entre
i et
j pas fait.
ai+ sumr inRwir+Dij leqaj+M(1− sumr inRxijr), quadi inI,j enV,
L'arrivée et le départ du camion doivent se faire dans l'intervalle indiqué par le conservateur.
ai geqBi, quadi inV,
ai+ sumr inRwir leqEi, quadi inV.
Déterminer le type de camion nécessaire pour desservir chaque itinéraireIndique les nombreux types de camions disponibles à la location par
T Type de camion
t inT caractérisé par le volume corporel
Ct et le coût d'une heure de loyer
Pt Temps minimum de location de camion
t dénoter par
U0t La quantité de matières recyclables collectées au point
i inV dénoter par
GiNous introduisons des variables
ytr,t dansT,r dansR égal à un si type de camion
t affecté à l'itinéraire de service avec un numéro
r et zéro sinon.
Variables entières
utr,t inT,r inR définir l'heure de location d'un type de camion
t desservant l'itinéraire avec un numéro
rPour chaque itinéraire,
r inR , vous devez attribuer le type de camion:
sumt inTytr=1, quadr inR
Conformément à la répartition des points entre les itinéraires, certains itinéraires peuvent se révéler triviaux, c'est-à-dire ne contenir que des dépôts. Si l'itinéraire
r non triviale, le camion qui lui est affecté est loué au moins
U0t heures.
utr geqU0t(ytr− sumi inVzir), quadt inT,r inR.
Dans le même temps, la durée du bail devrait également dépasser la durée totale de stationnement et de déplacement le long du parcours.
utr geq sumi inV sumj in barVDijxijr+ sumi in barVwir−M(1−ytr), quadr inR,t inT.
Ajouter des restrictions fournissant la propriété: si le camion est de type
t non affecté à un itinéraire
r , son temps de location est nul.
utr leqMytr.
Tous les produits recyclables collectés aux points de passage doivent tenir à l'arrière du camion.
sumi inVGizir leq sumt inTCtytr, quadr inR.
Enfin, notre objectif est de minimiser le coût de la location de camions, qui, en utilisant les désignations introduites, s'écrit
sumt inT sumr inRPtutrRechercher une solution
Il est facile de vérifier que toutes les expressions impliquées dans le modèle d'optimisation sont des fonctions linéaires de variables.Par conséquent, pour trouver des solutions exactes et approximatives, vous pouvez utiliser des packages standard pour résoudre des problèmes de programmation en nombres mixtes tels que
Gurobi ,
CPLEX ,
Xpress ,
ORtools ,
SCIP ,
BLIS , etc.
Nous écrivons un modèle pour minimiser les coûts de transport dans le langage GMPL. Cela nous permettra d'utiliser le package
GLPK gratuit à nos fins. Pour écrire du code et déboguer le modèle, il sera pratique de télécharger l'
environnement de développement
GUSEK , qui contient déjà GLPK dans sa composition.
GUSEK ressemble à ceci:

Sur la gauche, nous voyons une description du modèle, et sur la droite, il y a une fenêtre pour afficher des informations sur la progression du calcul, que le solveur fournira après le lancement.
Description complète du modèleparam numOfPoints > 0, integer; # param numOfTypes > 0, integer; # param numOfRoutes = numOfPoints;# set V := 1 .. numOfPoints; # set Vbar := V union {0}; # () set T := 1 .. numOfTypes; # set R := 1 .. numOfPoints; # ############### param WDL >= 0, default 8; # param B{i in Vbar} >= 0; # param E{i in Vbar} >= 0; # param L{i in Vbar} >= 0; # param D{i in Vbar, j in Vbar} >= 0, <= WDL; # param G{i in V}, >= 0; # , 3 ########## param C{t in T}, >= 0; # param P{t in T}, >= 0; # param U0{t in T}, >= 0; # , /********************************************** * **********************************************/ var z{Vbar, R} binary; # , , st pointToGroup 'point to group' {i in V}: sum{r in R} z[i, r] == 1; st depotToGroup 'depot to group' {r in R}: z[0, r] == 1; st lexMinGroups 'lexicographycally minimal division' {i in V, r in R: r <= i}: 1 - z[i, r] <= sum{j in V: j <= i - 1}(1 - sum{k in R: k <= r - 1} z[j, k]) + sum{k in R: k <= r - 1}z[i, k] ; /********************************************** * **********************************************/ var x{Vbar, Vbar, R} binary; # , c r i j, . st visitPoint 'visit point' {i in Vbar, r in R}: sum{j in Vbar} x[i, j, r] = z[i, r]; st keepMoving 'keep moving' {i in Vbar, r in R}: sum{j in Vbar} x[j, i, r] = sum {j in Vbar} x[i, j, r]; var f{Vbar, Vbar, R} >= 0; #, . st flowFromDepot 'flow from depot' {r in R}: sum{i in V} f[0, i, r] == sum{i in V} z[i, r]; st flowAlongActiveArcs 'flow along active arcs' {i in Vbar, j in Vbar, r in R}: f[i, j, r] <= numOfPoints * x[i, j, r]; st flowConservation 'flow conservation' {i in V, r in R}: sum{j in Vbar} f[j, i, r] == sum{j in Vbar} f[i, j, r] + z[i, r]; var a{i in V} >= 0; # var w{i in Vbar, r in R} >= 0; # st wait 'wait'{i in Vbar, r in R}: w[i, r] >= L[i] * z[i, r]; st dontWait 'dont wait'{i in Vbar, r in R}: w[i, r] <= (E[i] - B[i]) * z[i, r]; st arrivalTime 'arrival time' {i in V, j in V}: a[i] + sum{r in R}w[i, r] + D[i,j] <= a[j] + 3 * WDL * (1 - sum{r in R} x[i, j, r]); st arriveAfter 'arrive after' {i in V}: a[i] >= B[i]; st departBefore 'depart before' {i in V}: a[i] + sum{r in R}w[i, r] <= E[i]; /********************************************** * , **********************************************/ var y{t in T, r in R}, binary; # , t r, . var u{t in T, r in R}, integer, >= 0; # t, rst assignVehicle 'assign vehicle' {r in R}: sum{t in T} y[t,r] == 1; st rentTime 'rent time' {r in R, t in T}: u[t, r] >= sum{i in V, j in Vbar}D[i, j] * x[i, j, r] + sum{i in Vbar}w[i, r] - WDL * (1 - y[t, r]); st minRentTime 'minimal rent time' {r in R, t in T}: u[t, r] >= U0[t] * (y[t, r] - sum{i in V}z[i, r]); st noRent 'no rent' {t in T, r in R}: u[t, r] <= WDL * y[t, r]; st fitCapacity 'fit capacity' {r in R}: sum{i in V} G[i] * z[i, r] <= sum{t in T} C[t] * y[t, r]; minimize rentCost: sum{t in T, r in R} P[t] * u[t, r]; solve; /********************************************** * **********************************************/ printf{i in V, r in R} (if 0.1 < z[i,r] then "point %s to group %s\n" else ""), i, r, z[i,r]; printf{r in R, i in Vbar, j in Vbar} (if 0.1 < x[i, j, r] then "route %s: %s -> %s\n" else ""), r, i, j; printf{i in V} "point %s arrive between %s and %s (actual = %s)\n", i, B[i], E[i], a[i]; end;
Pour un démarrage rapide, j'ajouterai également des données provenant de ma tête préparées pour être utilisées dans le modèle:
Entrer les données data; param numOfPoints := 9; # param numOfTypes := 6; # ############### param : B E L := 0 0 8 1 1 0 8 1 2 0 8 1 3 0 8 1 4 0 8 1 5 0 8 1 6 0 8 1 7 0 8 1 8 0 8 1 9 0 8 1; param D default 0 : 0 1 2 3 4 5 6 7 8 9 := 0 . . . . . . . . . . 1 0.1 0.3 0.2 0.1 0.2 0.1 0.2 0.1 0.2 0.1 2 0.3 0.2 0.2 0.1 0.2 0.1 0.2 0.1 0.2 0.1 3 0.4 0.3 0.2 0.1 0.2 0.1 0.2 0.1 0.2 0.1 4 0.4 0.4 0.2 0.1 0.2 0.1 0.2 0.1 0.2 0.1 5 0.1 0.2 0.2 0.1 0.2 0.1 0.2 0.1 0.2 0.1 6 0.5 0.5 0.2 0.1 0.2 0.1 0.2 0.1 0.2 0.1 7 0.3 0.2 0.2 0.1 0.2 0.1 0.2 0.1 0.2 0.1 8 0.2 0.1 0.2 0.1 0.2 0.1 0.2 0.1 0.2 0.1 9 0.5 0.2 0.2 0.1 0.2 0.1 0.2 0.1 0.2 0.1; param G := 1 1 2 2 3 1 4 2 5 1 6 2 7 1 8 2 9 1; ########## param : C P := 1 8 500 2 10 500 3 14 600 4 18 650 5 25 700 6 35 800; param U0 default 2; # , end;
Après avoir copié le code du modèle dans un fichier portant le nom, par exemple, model.mod et les données d'entrée dans le fichier data.dat, tout est prêt à fonctionner. Nous fixons une limite au temps de calcul de 100 secondes (cela se fait en utilisant la clé --tmlim [temps en secondes]), transférons le chemin vers le fichier avec les données d'entrée (en utilisant la clé -d [chemin du fichier]),

et appuyez sur F5. En cas de succès, des messages apparaîtront dans la fenêtre de droite, et après une centaine de secondes, nous aurons la meilleure solution que GLPK a réussi à trouver dans le temps imparti.

Dans le texte bleu, nous nous intéressons au sens après l'inscription "mip =". Comme vous pouvez le voir, il diminue de temps en temps. Toutes les nouvelles solutions sont en cours de réalisation, dont la valeur des frais de transport au mieux est affichée dans cette colonne (il y en a 14700 à ce jour). Le nombre suivant est la borne inférieure de la meilleure solution existante, c'est-à-dire
optimale . Initialement, l'estimation est considérablement sous-estimée, mais elle s'affine avec le temps, c'est-à-dire qu'elle augmente. Les valeurs de gauche et de droite convergent et l'écart relatif entre elles au moment de la capture d'écran est de 54,1%. Dès que ce nombre devient nul, l'algorithme prouvera que la meilleure solution trouvée est la meilleure possible. Il n'est pas toujours justifié d'attendre cet événement dans la pratique, et pas seulement parce que c'est long, mais il est important de faire une réservation qui, en règle générale, une bonne solution est relativement rapide, et les principaux coûts de temps sont associés au raffinement de l'estimation nécessaire pour prouver le meilleur possible.
Au lieu d'une conclusion
Les problèmes de routage sont extrêmement complexes sur le plan informatique et avec l'augmentation du nombre de points à visiter, le temps nécessaire à un solveur pour trouver une solution et prouver que son optimalité augmente rapidement. Cependant, pour des exemples assez petits, dans un laps de temps raisonnable, le solveur est capable de créer un ensemble de routes réussi et peut être utilisé pour prendre des décisions. L'analyse des options de routage proposées par le modèle nous a permis de découvrir des opportunités importantes de réduction des coûts, ce qui est critique pour l'existence et le développement du stock.
Nos efforts se sont poursuivis pour travailler avec une incertitude sur les volumes de matières recyclables collectées aux points. Nous développons un certain nombre de modèles de programmation stochastiques pour prendre des décisions stratégiques et opérationnelles dans l'acheminement des camions. Si le sujet s'avère pertinent et suscite de l'intérêt, j'écrirai également à ce sujet, car bientôt nous devrons tous approfondir de manière beaucoup plus approfondie les questions environnementales, ce dans quoi je souhaite que nous réussissions.