Plutôt que de calculer un risque avec une formule, on rejoue des milliers de fois le futur au hasard, à partir de ce que l'on sait des incertitudes. La part des scénarios qui tournent mal donne directement la probabilité du risque. Simple, transparent, et utilisable sur presque tous les problèmes de stock, de budget ou de planning.
Pour savoir si un budget de projet tient, on le rejoue 10 000 fois en tirant au hasard les retards et les surcoûts plausibles. Si 800 versions dépassent le budget, le risque de dépassement est de 8 %.
Demande, délai, prix, taux de panne : pour chacun, une loi de probabilité ou simplement l'historique observé, qu'on retire au sort (rééchantillonnage).
À chaque tirage, on choisit une valeur au hasard pour chaque incertitude et on calcule le résultat : stock final, coût total, date de fin.
La distribution des résultats donne tout : moyenne, pire cas à 95 %, probabilité de dépasser un seuil. Plus on tire de scénarios, plus ces chiffres sont stables.
Une référence de pièce détachée à la demande très irrégulière : sur le jeu d'exemple, 87 % des semaines sans aucune commande, puis des pics de 3 à 11 pièces. Le fournisseur livre en 4 semaines.
10 000 scénarios de 4 semaines donnent la probabilité de rupture pour chaque stock possible : 41 % avec 4 pièces, 6 % avec 12, 1,4 % avec 16. Le stock minimal pour 95 % de cycles sans rupture est de 13 pièces.
On retient le plus petit stock qui atteint le taux de service visé. La formule classique « moyenne + 1,65 écart-type » suppose une demande en cloche : ici elle donne 11,3 pièces et sous-estime le besoin.
L'algorithme est trivial. Toute la qualité du résultat tient aux hypothèses d'entrée.
L'erreur de simulation baisse comme 1 divisé par la racine du nombre de tirages. 10 000 suffit pour un risque de quelques pourcents ; relancer avec une autre graine vérifie la stabilité.
Historique rééchantillonné (bootstrap) quand on a assez de données, loi paramétrique (Poisson, log-normale, triangulaire) sinon. Une loi mal choisie fausse tout le reste.
Ici, les semaines sont tirées indépendamment. Si une forte semaine annonce souvent une autre forte semaine, il faut tirer des blocs de semaines consécutives, sinon le risque est sous-estimé.
Fixer la graine rend les résultats reproductibles, indispensable pour un chiffre présenté en comité.
# Risque de rupture de stock : simulation Monte Carlo en R
pieces <- read.csv("pieces_detachees.csv")
demande <- pieces$quantite[pieces$reference == "REF-B07"]
cat("Semaines sans aucune demande :", round(100 * mean(demande == 0)), "%\n")
# 10 000 scénarios de demande sur les 4 semaines de délai fournisseur :
# chaque semaine est tirée au hasard parmi les 156 semaines observées
set.seed(42)
scenarios <- replicate(10000, sum(sample(demande, 4, replace = TRUE)))
cat("Demande moyenne sur 4 semaines :", round(mean(scenarios), 1), "pièces\n")
# Risque de rupture selon le stock disponible au moment de la commande
for (stock in c(4, 8, 12, 16, 20)) {
cat("Stock de", stock, "pièces : rupture dans", round(100 * mean(scenarios > stock), 1), "% des scénarios\n")
}
# Plus petit stock qui couvre au moins 95 % des scénarios
risque <- sapply(0:100, function(s) mean(scenarios > s))
cat("Stock pour 95 % de cycles sans rupture :", min(which(risque <= 0.05)) - 1, "pièces\n")
# Comparaison : la règle « moyenne + 1,65 écart-type » (loi normale)
cat("Règle normale :", round(mean(scenarios) + 1.65 * sd(scenarios), 1), "pièces\n")
# Risque de rupture de stock : simulation Monte Carlo en Python
import numpy as np
import pandas as pd
pieces = pd.read_csv("pieces_detachees.csv")
demande = pieces.loc[pieces["reference"] == "REF-B07", "quantite"].values
print("Semaines sans aucune demande :", f"{np.mean(demande == 0):.0%}")
# 10 000 scénarios de demande sur les 4 semaines de délai fournisseur :
# chaque semaine est tirée au hasard parmi les 156 semaines observées
rng = np.random.default_rng(42)
scenarios = rng.choice(demande, size=(10000, 4), replace=True).sum(axis=1)
print("Demande moyenne sur 4 semaines :", round(scenarios.mean(), 1), "pièces")
# Risque de rupture selon le stock disponible au moment de la commande
for stock in [4, 8, 12, 16, 20]:
print(f"Stock de {stock:2d} pièces : rupture dans {np.mean(scenarios > stock):.1%} des scénarios")
# Plus petit stock qui couvre au moins 95 % des scénarios
stock_95 = next(s for s in range(100) if np.mean(scenarios > s) <= 0.05)
print("Stock pour 95 % de cycles sans rupture :", stock_95, "pièces")
# Comparaison : la règle « moyenne + 1,65 écart-type » (loi normale) sous-estime ici le besoin
print("Règle normale :", round(scenarios.mean() + 1.65 * scenarios.std(), 1), "pièces")
C'est une méthode qui estime un résultat incertain en le recalculant des milliers de fois avec des valeurs d'entrée tirées au hasard. La distribution des résultats obtenus donne la moyenne, les extrêmes et la probabilité de chaque issue. Le nom vient du casino de Monte-Carlo.
Cela dépend de la précision voulue. Pour une probabilité autour de 5 %, 10 000 tirages donnent une précision d'environ plus ou moins 0,4 point. Pour estimer un événement rare, il en faut beaucoup plus. Le bon test : relancer avec une autre graine et vérifier que le résultat bouge peu.
Oui, avec la fonction ALEA() et une table de données, ou avec des compléments dédiés. Au-delà de quelques milliers de scénarios ou de plusieurs incertitudes liées, R ou Python sont plus rapides, plus reproductibles et plus faciles à auditer.
Donne une prévision moyenne pour ce type de demande. Monte Carlo en tire la distribution complète et le stock à tenir.
Voir la fiche → le cousin bayésienUtilise aussi le hasard, mais pour estimer les paramètres d'un modèle, pas pour rejouer des scénarios.
Voir la fiche → le hasard pour déciderSimule des parties au hasard pour choisir le meilleur coup dans un jeu ou une séquence de décisions.
Voir la fiche →Dataistudio forme les équipes au machine learning et à l'IA, sur des cas concrets.
Nous utilisons des cookies de mesure d'audience et de suivi publicitaire pour comprendre la fréquentation du site et l'efficacité de nos annonces. Rien n'est déposé sans votre accord. En savoir plus