Solution d'essai par simulation

Analytique de la chaîne d'approvisionnement avec Python

Aaren Stubberfield

Supply Chain Analytics Mgr.

Attention

  • Évitez d'utiliser la PL ou la PI pour des problèmes très longs à résoudre

image d'avertissement, personne qui glisse

Analytique de la chaîne d'approvisionnement avec Python

Concept global

Concept général :

  • Ajouter du bruit aléatoire aux entrées clés choisies
  • Résoudre le modèle à répétition
  • Observer la distribution
Analytique de la chaîne d'approvisionnement avec Python

Pourquoi essayer

Pourquoi :

  • Les entrées sont souvent des estimations, donc possiblement inexactes.
  • L'analyse de sensibilité précédente ne modifiait qu'une entrée à la fois.
Analytique de la chaîne d'approvisionnement avec Python

Contexte

Contexte – Entreprise de verre – Planification des ressources :

Ressource Prod. A Prod. B Prod. C
Profit $US 500 $ 450 $ 600 $

Contraintes :

  • Contraintes de demande, de capacité de production et d'entrepôt

Risques :

  • Les estimations de profit peuvent être inexactes
Analytique de la chaîne d'approvisionnement avec Python
# Initialize Class, & Define Variables
model = LpProblem("Max Glass Co. Profits", LpMaximize)
A = LpVariable('A', lowBound=0)
B = LpVariable('B', lowBound=0)
C = LpVariable('C', lowBound=0)

# Define Objective Function
model += 500 * A + 450 * B + 600 * C

# Define Constraints & Solve
model += 6 * A + 5 * B + 8 * C <= 60
model += 10.5 * A + 20 * B + 10 * C <= 150
model += A  <= 8
model.solve()
Analytique de la chaîne d'approvisionnement avec Python

Exemple de code – étape 2

a, b, c = normalvariate(0,25), 
          normalvariate(0,25),
          normalvariate(0,25)
# Define Objective Function
model += (500+a)*A + (450+b)*B + (600+c)*C
# Initialize Class, & Define Variables
model = LpProblem("Max Glass Co. Profits", 
                   LpMaximize)

A = LpVariable('A', lowBound=0)
B = LpVariable('B', lowBound=0)
C = LpVariable('C', lowBound=0)
a, b, c = normalvariate(0,25), 
          normalvariate(0,25), 
          normalvariate(0,25)
# Define Objective Function
model += (500+a)*A + (450+b)*B + (600+c)*C

# Define Constraints & Solve
model += 6 * A + 5 * B + 8 * C <= 60
model += 10.5 * A + 20 * B + 10 * C <= 150
model += A  <= 8
model.solve()
Analytique de la chaîne d'approvisionnement avec Python
def run_pulp_model():
    # Initialize Class
    model = LpProblem("Max Glass Co. Profits", LpMaximize)
    A = LpVariable('A', lowBound=0)
    B = LpVariable('B', lowBound=0)
    C = LpVariable('C', lowBound=0)
    a, b, c = normalvariate(0,25), normalvariate(0,25), normalvariate(0,25)

    # Define Objective Function
    model += (500+a)*A + (450+b)*B + (600+c)*C

    # Define Constraints & Solve
    model += 6 * A + 5 * B + 8 * C <= 60
    model += 10.5 * A + 20 * B + 10 * C <= 150
    model += A  <= 8
    model.solve()
    o = {'A':A.varValue, 'B':B.varValue, 'C':C.varValue, 'Obj':value(model.objective)}
    return(o)
Analytique de la chaîne d'approvisionnement avec Python

Exemple de code – étape 4

def run_pulp_model():
    # Initialize Class
    model = LpProblem("Max Glass Co. Profits",
                       LpMaximize)
    A = LpVariable('A', lowBound=0)
    B = LpVariable('B', lowBound=0)
    C = LpVariable('C', lowBound=0)
    a, b, c = normalvariate(0,25), 
              normalvariate(0,25),
              normalvariate(0,25)

    # Define Objective Function
    model += (500+a)*A + (450+b)*B + 
             (600+c)*C
    # Define Constraints & Solve
    model += 6 * A + 5 * B + 8 * C <= 60
    model += 10.5 * A + 20 * B + 10 * C <= 150
    model += A  <= 8
    model.solve()
    o = {'A':A.varValue, 'B':B.varValue, 
         'C':C.varValue, 
         'Obj':value(model.objective)}
    return(o)
for i in range(100):
    output.append(run_pulp_model())
df = pd.DataFrame(output)
Analytique de la chaîne d'approvisionnement avec Python

Exemple de code – étape 5

print(df['A'].value_counts())
print(df['B'].value_counts())
print(df['C'].value_counts())

Sortie : (les résultats peuvent varier)

6.666667    73
0.000000    14
8.000000    13
Name: A, dtype: int64
4.000000    73
5.454546    14
2.400000    13
Name: B, dtype: int64
0.000000    86
4.090909    14
Name: C, dtype: int64
Analytique de la chaîne d'approvisionnement avec Python

Visualiser par histogramme

Produit A : histogramme des produits a, b, c et de l'objectif

Produit B : histogramme du produit b

Produit C : histogramme du produit c

Valeurs de l'objectif : histogramme des valeurs de l'objectif

Analytique de la chaîne d'approvisionnement avec Python

Résumé

  • À éviter pour les problèmes très longs à résoudre
  • Avantages

    • Voir comment l'optimum évolue quand les entrées du modèle changent
  • Étapes

    1. Partir du code PuLP standard
    2. Ajouter du bruit aux entrées clés avec normalvariate de Python
    3. Encapsuler le code PuLP dans une fonction qui retourne la sortie du modèle
    4. Créer une boucle qui appelle la nouvelle fonction et stocke les résultats dans un DataFrame
    5. Visualiser le DataFrame de résultats
Analytique de la chaîne d'approvisionnement avec Python

Essayez-le !

Analytique de la chaîne d'approvisionnement avec Python

Preparing Video For Download...