Résoudre le problème des quantités minimales de commande

Résoudre le problème des quantités minimales de commande


Accueil » Documentation » Ici
Par Joannès Vermorel, Janvier 2016

Les quantités minimales de commande (MOQ) forment une contrainte omniprésente dans le domaine logistique. Une telle contrainte existe lorsqu'un fournisseur n'accepte les commandes qu'à partir d'une certaine quantité commandée, exprimée en unités ou en euros. Souvent, plusieurs contraintes de quantités minimales de commande coexistent et doivent toutes être respectées. Le problème des quantités minimales de commande consiste à calculer la commande d'achat optimisée qui respecte les contraintes de quantités tout en maximisant les résultats économiques des unités achetées.

Ce problème est un problème d'optimisation non linéaire pour lequel le calcul de la solution « optimale » est généralement impossible. Mais, même si les solutions optimales ne peuvent être déterminées, des solutions satisfaisantes peuvent être proposées par des algorithmes avancés de résolution de contraintes non linéaires. La fonction moqsolv, présentée ci-dessous, implémente un tel algorithme pour résoudre avec Lokad ce problème de quantités minimales de commande.

Les contraintes de quantités minimales de commandes habituelles

Les contraintes de quantités minimales de commande peuvent prendre plusieurs formes, parmi les plus fréquentes on trouve :
  • Les quantités minimales exprimées en unités par SKU, pour les articles trop bon marché pour être vendus à la pièce.
  • Les quantités minimales exprimées en euros par commande, souvent utilisées lorsque le fournisseur ne facture pas la livraison.
  • Les quantités minimales exprimées en unités par « catégorie » d'articles, souvent utilisées avec les articles fabriqués sur commande par lots d'une taille minimale.

En général, il est relativement simple de respecter une contrainte à la fois. Par contre, dès que plusieurs contraintes de quantités minimales de commande doivent être prises en compte en même temps, la composition des commandes devient plus complexe.

Les concepts associés aux quantités minimales de commande

Avant d'aborder le problème du point de vue de l'optimisation numérique, passons en revue les concepts essentiels des quantités minimales de commande :
  • Les articles (items) qui représentent ce qui peut être acheté. Les quantités d'articles sont souvent des nombres entiers, même si dans le cas présent aucune restriction ne l'impose.
  • Les quantités commandées (ordered quantity) de chaque article (peuvent être nulles) qui représentent une solution potentielle au problème des quantités minimales de commande.
  • Les récompenses (rewards).associées à chaque unité supplémentaire de chaque article — simplement ce que la fonction stockrwd (récompense associée au stock) fournit, bien que l'utilisation de cette fonction ne soit pas obligatoire.
  • Les coûts (costs) des unités achetées. Le but est de maximiser la récompense pour un budget de dépense donné exprimé en « coûts ». Ces derniers doivent généralement être fixes par unité, mais, dans le cas présent, cette hypothèse ne s'applique pas et les remises en fonction des quantités commandées peuvent donc être prises en compte.
  • Les cibles (targets) qui représentent une façon de spécifier un critère d'arrêt comme le coût réel. Ce concept est un peu subtil et détaillé ci-dessous.

Le critère d'arrêt idéal, lorsque l'on définit une commande à partir d'une « liste de priorité d'achat », est un « budget maximal » : les unités sont achetées, dans l'ordre décroissant du retour sur investissement qui leur est associé, jusqu'à ce que le budget soit dépensé. Toutefois, une limite budgétaire ne dit rien des performances du stock qui peuvent être obtenue. Ainsi, si l'objectif reste d'optimiser le retour sur investissement quel que soit le critère d'arrêt utilisé, il est toujours très utile d'être en mesure de prendre en compte d'autres critères comme un taux de couverture cible par exemple. Le concept de « cible » correspond à un mécanisme générique qui permet de définir des critères d'arrêt alternatifs, tout en passant des commandes par ordre de priorité. Il s'agit alors d'identifier les commandes qui donnent accès au meilleur retour sur investissement pour le plus petit investissement, tout en atteignant l'objectif « cible ». Une définition plus précise du processus d'optimisation est donnée ci-dessous.

Exemple : le responsable logistique définit un taux de couverture cible de 90 %. La résolution du problème des quantités minimales de commande consiste à calculer la commande la moins coûteuse qui « maximise les récompenses » et permet d'atteindre le taux de couverture de 90 %. La commande définie n'est pas la commande la moins coûteuse qui permet d'atteindre le taux de couverture de 90 % — ce qui correspondrait à donner uniquement la priorité au taux de couverture. Il s'agit de la commande la moins coûteuse, qui donne la priorité aux récompenses, mais qui est assez importante pour atteindre le taux de couverture de 90%. Donner uniquement la priorité au taux de couverture est une erreur car, au contraire des récompenses associées au stock, les coûts de création de stock mort ne sont alors pas pris en compte.

Définition formelle du problème des quantités minimales de commande

La présente section porte sur le problème des quantités minimales de commande en tant que problème formel d'optimisation non linéaire. Il est relativement simple de démontrer que ce problème est difficile, NP-difficile pour être précis. En réalité, ce problème des quantités minimales de commande est une extension du problème de bin packing, qui est déjà NP-difficile. Donc le problème des quantités minimales de commande est au moins aussi difficile que le problème de bin packing. En pratique, même s'il s'agit d'un problème NP-difficile, de très bonnes solutions peuvent être calculées.

$I$ représente l'ensemble des articles à considérer pour la commande. $q_i$ avec $i \in I$ représente la quantité à commander pour l'article $i$. Une série de fonctions est ensuite définie :

  • $r_i(q)$ repésente la « récompense » avec $q$ unités de l'article $i$ en stock.
  • $c_i(q)$ repésente le « coût » avec $q$ unités de l'article $i$ achetées.
  • $t_i(q)$ représente la « cible » avec $q$ unités de l'article $i$ en stock.

La fonction de récompense peut renvoyer des valeurs positives ou négatives tandis que celles du coût et de la cible sont strictement positives : $$\forall i, \forall q, c_i(q) > 0 \text{ and } t_i(q) >0$$ $M$ correspond à l'ensemble des contraintes de quantités minimales de commande. Pour chaque $m \in M$, $I_m$ est la liste des articles qui respectent la contrainte $m$ et $Q_m$ la quantité minimale qui doit être atteinte pour respecter la contrainte. $m_i(q)$ est la fonction qui définit la contribution de l'article $i$ à la contrainte $m$ lorsque $q$ unités sont achetées. La contrainte $m$ est respectée si : $$\forall i \in I_m, q_i = 0 \text{ or } \sum_{i \in I_m}m_i(q_i) \geq Q_m$$ Ainsi, toutes les contraintes de de quantités minimales de commande peuvent être respectées de deux façons : en atteignant le seuil de quantité minimale ou en mettant les quantités de tous les articles à zéro.

Ensuite, $C$ représente le coût maximal de la commande. $\textbf{q}_C=(q_i)_i$ est alors défini comme la meilleure commande avec : $$\textbf{q}_C = \underset{q}{\operatorname{argmax}} \left\{ \sum_i r_i(q_i) \text{ with $m$ satisfied } \forall m\in M \right\}$$ La commande est la « meilleure » dans le sens où elle maximise la récompense pour un budget donné. La solution $\textbf{q}_C$ n'est pas unique, cependant, il s'agit là d'une considération théorique car le problème des quantités minimales de commande est trop difficile pour être résolu de façon exacte. Pour plus de simplicité, nous considérerons dans ce qui suit que la solution est unique.

Enfin, $T$ étant une cible minimale, $\textbf{q}^T$ est défini avec $$C^T = \underset{C}{\operatorname{min}} \left\{ \left(\sum_{q_i \in \textbf{q}_C} t_i(q_i) \right) \geq T \right\}$$ et $$\mathbf{q}^T = \textbf{q}_{C^T}$$ La solution $\mathbf{q}^T$ est construite sur $\textbf{q}_C$ : la solution la moins coûteuse qui maximise le retour sur investissement et qui permet d'atteindre la cible.

La fonction moqsolv dans Envision

Envision fournit une fonction non linéaire destinée à résoudre le problème des quantités minimales de commande. Grâce à cette fonction appelée moqsolv, vous n'avez plus besoin de bidouiller des chiffres pour essayer de faire face aux contraintes de quantités minimales de commande. La fonction moqsolv est conçue pour traiter une série de vecteurs associés à une table de type Id(*). Cette dernière est généralement obtenue au moyen de l'extension d'un vecteur de distributions via extend.distrib() (voir également l'algèbre des distributions).

La fonction doit recevoir les arguments suivants :

moqsolv(Id, Min, Reward, Cost, Target, threshold, g0, oq0, moq0, g1, oq1, moq1, ...)

Où :

  • Id est la colonne de regroupement des articles.
  • Min est la colonne de commande des unités – comme dans Grid.Min
  • Reward est la récompense de la ligne – telle qu'obtenu avec stockrwd, la fonction de récompense associée au stock.
  • Cost est le coût de la ligne - généralement PurchasePrice * Grid.Q
  • Target est une quantité cible – qui peut être égale au coût pour une limitation simple du budget. Grâce à Target == Cost, il s'agira d'une optimisation « petit budget » (et, avec Target != Cost, d'une optimisation « cible »).
  • threshold est une valeur scalaire qui joue le rôle du seuil de la « cible ». Dans le cas d'une optimisation « petit budget », la valeur cible correspond à la limite supérieure du coût de la solution. Dans le cas d'une optimisation « cible », la valeur cible correspond à la limite inférieure de la cible associée à la solution. Si la valeur seuil est négative, le signe moins est interprété comme un indicateur booléen qui signale que la cible (positive) est un maximum. En effet, le signe de la valeur seuil n'est utilisé que pour déterminer le sens de l'inégalité et la valeur est toujours interprétée comme positive.
  • g0, oq0, moq0 représente un triplet de vecteurs associés à chaque contrainte de quantité minimale de commande (détaillé ci-dessous).

Voir également Commandes prioritaires avec contraintes, un tutoriel qui illustre comment la fonction moqsolv peut être utilisée pour composer une commande qui respecte les contraintes de quantités minimales de commande.

La fonction renvoie un vecteur booléen dans lequel toutes les lignes éligibles sont indiquées par la valeur true. La combinaison de toutes ces lignes respecte les contraintes de quantités minimales de commande. La solution $\textbf{q}^T$ est approximée comme dans la section précédente. Comme indiqué précédemment, les arguments Cost, Target et threshold doivent être strictement positifs.

Chaque contrainte de quantité minimale de commande est définie par trois vecteurs :

  • G le regroupement de quantités minimales de commande, qui peut être égal à Id dans le cas de contraintes par article.
  • OQ la contribution de la ligne à la « quantité commandée » de la contrainte de quantité minimale de commande.
  • MOQ le seuil à atteindre pour satisfaire la contrainte de quantité minimale de commande.

Les groupes représentés par G doivent former une partition des identifiants des articles. Le seuil de quantité minimale de commande doit être identique pour toutes les lignes qui portent la même valeur de G. Toutes les valeurs de contribution OQ doivent être strictement positives. Les valeurs MOQ doivent être positives mais peuvent être égales à zéro s'il n'y a pas de contrainte de ce type.

Il est possible de spécifier plusieurs quantités minimales de commande avec plusieurs triplets. Envision peut prendre en charge jusqu'à 4 contraintes de quantités minimales de commande simultanées.