La programmation mathématique est une méthode de maximisation (minimisation) d'une valeur cible appelée fonction objectif sous une certaine contrainte. Parmi eux, la programmation linéaire (LP) signifie que la fonction objectif et l'expression de contrainte peuvent être exprimées par une expression linéaire (une expression de la forme $ \ sum_ia_ix_i + b $) liée à la variable. La programmation linéaire est l'une des programmations mathématiques les plus simples, mais elle dispose d'une riche bibliothèque pour les solveurs et la modélisation, offrant un environnement facile à utiliser. En particulier, je pense que les entreprises optimisent souvent des variables contrôlables telles que le volume de production et le volume de transport en utilisant des indicateurs monétaires tels que le profit et le coût comme fonctions objectives.
Dans cet article, à partir des livres suivants qui résument les techniques de modélisation de l'optimisation mathématique, un exercice est sorti et effectivement formulé, et il est implémenté dans PuLP, qui est un langage de modélisation de Python, pour trouver la solution optimale. J'aimerais venir.
Model Building in Mathematical Programming https://www.amazon.co.jp/dp/1118443330/
Cet exercice est destiné aux devoirs de lecture effectués dans Groupe d'optimisation mathématique de TFUG. C'est un. Tout le monde peut rejoindre le groupe TFUG, donc si vous êtes intéressé, vous voudrez peut-être jeter un œil à Slack!
Cet article a la structure suivante. Tout d'abord, nous expliquerons brièvement comment modéliser, puis présenterons la définition du problème de l'exemple et effectuerons la modélisation, la mise en œuvre et la vérification.
--Modélisation du flux
Il y a une section en colonne au milieu, donc vous pouvez l'ignorer, mais j'écris sur un sujet que je trouve personnellement intéressant, alors veuillez le lire.
En général, pour modéliser un plan mathématiquement, vous devez définir deux choses:
Prenons l'exemple du plan de production d'une usine. Tout d'abord, la fonction objectif représente le coût ou l'avantage que vous souhaitez optimiser. Par exemple, lors de la production dans les usines A et B, supposons que le coût de production puisse être exprimé comme suit:
Donc, ensuite, en tant qu'expression de contrainte, nous imposons une condition à la variable pour éviter une telle situation. Par exemple, la contrainte «vous devez produire plus de XX» mentionnée précédemment peut être exprimée comme suit.
De plus, s'il s'agit d'un plan de production, il y a souvent une limite à la capacité de production de l'usine, et il y a souvent une limite supérieure sur le volume de production. Une expression de contrainte exprime ces restrictions et règles métier sous la forme d'une formule mathématique.
De plus, les informations suivantes sont nécessaires pour définir la fonction objectif et l'expression de contrainte.
--Réunion
Si vous voulez réellement modéliser à partir de zéro, personnellement, je pense qu'il est préférable de viser d'abord à définir la fonction objectif. Lorsque vous essayez de définir une fonction objectif, il est nécessaire d'organiser les informations nécessaires dans le processus, ce qui conduit à la détermination d'ensembles, de paramètres et de variables. Ensuite, pour chaque variable, identifiez les contraintes nécessaires et exprimez-les une par une sous forme d'expressions.
Dans ce qui suit, nous présenterons la définition du problème de l'exemple et le modéliserons réellement.
Cette fois, nous traiterons des plans de production alimentaire. Plus précisément, de janvier à juin, on dit que la nourriture se fait en achetant chaque mois de l'huile comme matière première, en la raffinant et en la mélangeant (margarine ou quelque chose du genre ...?). Dans ce plan de production, nous visons à maximiser les profits à la fin en ajustant le montant d'achat et la quantité de consommation de chaque huile de matière première chaque mois.
Dans ce numéro, pour réfléchir aux fonctions objectives et aux expressions de contraintes, nous devons considérer les coûts et les contraintes liés aux facteurs suivants.
--Inventaire --Achat --Purification
J'expliquerai chaque situation en détail.
Les stocks cohésifs d'huile augmentent avec les nouveaux achats et diminuent avec la consommation dans la production alimentaire.
Chaque matière première peut être conservée en stock pour un maximum de 1 000 $ [t] $. Cependant, il y a un coût de stockage de 5 $ [£ / t] $ par mois.
De plus, pour toute source d'huile, l'inventaire commence à 500 $ [t] $ et se termine à 500 $ [t] $ ou plus.
Les huiles ci-dessus seront achetées de janvier à juin aux prix unitaires suivants.
Mois | VEG 1 | VEG 2 | OIL 1 | OIL 2 | OIL 3 |
---|---|---|---|---|---|
Jan | 110 | 120 | 130 | 110 | 115 |
Feb | 130 | 130 | 110 | 90 | 115 |
Mar | 110 | 140 | 130 | 100 | 95 |
Apr | 120 | 110 | 120 | 120 | 125 |
May | 100 | 120 | 150 | 110 | 105 |
Jun | 90 | 100 | 140 | 80 | 135 |
Il n'y a pas de restrictions particulières sur le montant qui peut être acheté.
De la quantité achetée et de la quantité initialement en stock, une certaine quantité est soumise au processus de purification. Dans le processus de purification, il n'y aura pas de perte particulière et le coût de la purification sera négligeable.
Il existe deux types d'huiles brutes, végétales et non végétales, et le processus de raffinage serait effectué sur des lignes de raffinage différentes pour chaque type d'huile. La limite supérieure de la quantité de purification est fixée comme suit.
type | Limite supérieure de la quantité de purification[t/Mois] |
---|---|
Botanique | 200 |
Non végétal | 250 |
En outre, les types d'huile de matière première sont les suivants.
Nom | type |
---|---|
VEG 1 | Botanique |
VEG 2 | Botanique |
OIL 1 | Non végétal |
OIL 2 | Non végétal |
OIL 3 | Non végétal |
En mélangeant toutes les huiles raffinées, la nourriture à expédier ce mois-là est terminée. Encore une fois, aucune perte ne se produit, de sorte que le poids total de l'huile brute mélangée est la quantité de nourriture produite.
De plus, chaque huile de matière première a la dureté indiquée dans le tableau ci-dessous. La dureté de l'aliment produit est moyennée en fonction de la consommation d'huile de matière première, et la dureté de l'aliment doit être comprise entre 3 $ et 6 $.
Nom | dureté |
---|---|
VEG1 | 8.8 |
VEG2 | 6.1 |
OIL1 | 2.0 |
OIL2 | 4.2 |
OIL3 | 5.0 |
Il semble que la nourriture produite puisse être épuisée dans le mois. En d'autres termes, le volume de production devient le volume des ventes tel qu'il est. Le prix de vente unitaire est fixé à 150 $ [£ / t] $ quel que soit le mois.
À partir de maintenant, nous modéliserons en fait le paramètre de problème expliqué précédemment. De plus, j'ai écrit plus tôt que "il est préférable de décider de l'ensemble et des paramètres tout en définissant la fonction objectif", mais dans l'explication, il est plus facile d'écrire d'abord l'ensemble, les paramètres et les variables, donc je le fais. ..
Dans un modèle d'optimisation mathématique, un ensemble est un indice d'un paramètre ou d'une variable. Pour ce numéro, nous examinerons les quatre ensembles suivants:
** Huile brute **
** Période cible (mois) **
** Ligne de purification **
** Objectif de purification **
Puisqu'il est défini pour chaque ligne de purification, il s'agit d'un ensemble d'ensembles (famille d'ensembles) dans son ensemble.
Je le donne ici, mais gardez à l'esprit que la façon dont les ensembles sont définis n'est pas unique. Selon la manière dont l'ensemble est défini, la polyvalence du modèle peut être réduite. Cela sera discuté plus en détail dans la section Expressions de contraintes.
Ensuite, nous définirons les paramètres utilisés pour calculer la fonction objectif et l'expression de contrainte.
Nom | Indice | Plage de valeurs | La description |
---|---|---|---|
Prix unitaire d'achat de l'huile de matière première. | |||
- | Prix unitaire de stockage de l'huile de matière première. | ||
- | Prix de vente unitaire de la nourriture. | ||
Stock initial d'huile de matière première. | |||
La limite inférieure du stock final d'huile de matière première. | |||
- | Limite supérieure du stock d'huile de matière première. | ||
La dureté de l'huile de matière première. | |||
Limite supérieure de la quantité de purification. |
uc est une abréviation de coût unitaire, qui signifie prix unitaire, et lb / ub est une abréviation de limite inférieure / supérieure, respectivement, qui signifie limites supérieure et inférieure.
De même, définissez les variables à optimiser. Il est souhaitable d'utiliser la nomenclature pour les noms de variables, mais si elle est trop longue, l'expression sera difficile à lire, donc certains verbes sont utilisés.
Nom | Indice | Plage de valeurs | La description |
---|---|---|---|
Achetez la quantité d'huile de matière première. | |||
Quantité d'huile de matière première utilisée. | |||
Production alimentaire. | |||
Stock mensuel d'huile de matière première. | |||
Inventaire de fin de mois de l'huile de matière première. |
Pour l'inventaire, il suffit souvent de déclarer un seul parmi $ \ text {opening_stock} $ et $ \ text {closing_stock} $. Il y a aussi des goûts personnels ici.
Maintenant que nous avons les informations nécessaires, définissons la fonction objectif. Cette fois, je voulais maximiser les profits sur toute la période.
Ensuite, notez l'expression de contrainte. Les limites supérieures et inférieures simples des variables sont décrites comme des plages de valeurs dans la section «Variables».
L'inventaire mensuel de janvier correspond à l'inventaire initial.
L'inventaire de fin de mois en juin sera supérieur à la limite d'inventaire final.
L'inventaire mensuel après février correspond à l'inventaire de fin de mois du mois précédent.
L'inventaire de fin de mois est le montant obtenu en ajoutant le montant de l'achat à l'inventaire mensuel du mois et en soustrayant le montant de la consommation.
La production mensuelle est égale à la somme de la consommation d'huile brute.
La partie qui dit: «La dureté de la nourriture produite est moyennée en fonction de la consommation d'huile de matière première, et la dureté de la nourriture doit être comprise entre 3 $ et 6
De plus, dans la formule d'origine, le comportement lorsque le montant de la production est de 0 $ est suspect, mais dans la formule convertie, le montant de la consommation et le montant de la production sont de 0 $, donc on peut voir que la contrainte est satisfaite. Avec ce paramètre de problème, il est possible que la production ne soit pas effectuée, donc il n'y a pas de problème.
Dans ce plan de production, il y avait une limite supérieure sur la quantité de purification pour chaque ligne de purification. Exprimé sous forme d'expression, il peut s'écrire comme suit.
Les informations sur la ligne de purification peuvent être exprimées différemment. Par exemple, au lieu de $ \ text {USED \ _OILS} $, définissez le paramètre $ \ text {ref \ _line} $, ce qui signifie la ligne de raffinement pour chaque matière première, comme suit:
Indice | valeur |
---|---|
VEG1 | VEG |
VEG1 | VEG |
OIL1 | NONVEG |
OIL2 | NONVEG |
OIL3 | NONVEG |
C'est presque le même que le [Tableau des types d'huile de matière première mentionnés dans l'énoncé du problème](# type d'huile), il peut donc être plus naturel de l'utiliser. En utilisant ce paramètre, la limite supérieure de la limite de purification peut être exprimée comme suit:
Ce que nous faisons est le même qu'avant, nous additionnons simplement la consommation de la matière première huile à raffiner et la limitons à la limite supérieure. Avec ce modèle, le même résultat peut être obtenu avec ces données.
Cependant, il est possible de déterminer ce qui est préférable.
Comme test, considérons le cas où une ligne appelée $ \ text {VEGNEW} $ est ajoutée pour raffiner $ \ text {VEG1} $ et $ \ text {VEG2}
\text{USED_OILS}_{VEG} &= \{\text{VEG1}, \text{VEG2}, \text{VEG3}\}, \
\text{USED_OILS}_{VEGNEW} &= \{\text{VEG1}, \text{VEG2}\}, \
\text{USED_OILS}_{NONVEG} &= \{\text{OIL1}, \text{OIL2}\}.
\end{aligned}
$$
Mais que faire si vous aviez une formulation qui utilisait $ \ text {ref \ _line} $? Comme vous pouvez le voir dans le [Tableau ci-dessus](# ref-line), ce paramètre suppose que ** une huile de matière première possède une ligne de raffinage **. Par conséquent, la situation où $ \ text {VEG1} $ appartient à la fois à $ \ text {VEG} $ et $ \ text {VEGNEW} $ ne peut pas être représentée dans le modèle.
Comme vous pouvez le voir, il existe un large éventail de façons d'avoir de la polyvalence, même s'il n'y a qu'une seule façon de définir des ensembles et des paramètres. Une mauvaise compréhension du problème peut conduire à une polyvalence (ou à un échec) dans le mauvais sens, rendant difficile la modification ultérieure du modèle (cf. abstraction prématurée (cf. abstraction prématurée). abstraction prématurée).
Tous les changements ne peuvent pas être prévus à l'avance, et les hypothèses elles-mêmes peuvent changer en raison des révisions de la loi, etc., mais je me rends compte que des hypothèses arbitraires sont mélangées à la manière de définir ces ensembles occasionnels. Je pense que c'est important. De plus, lors de la modélisation, il est essentiel d'approfondir la compréhension de l'entreprise avec l'aide d'utilisateurs (experts du domaine).
Nous implémenterons le modèle ci-dessus avec Python + PuLP. Avec PuLP, les ensembles et les paramètres peuvent utiliser n'importe quelle structure de données Python, il suffit donc d'utiliser quelque chose de facile à utiliser. Dans ce qui suit, nous introduirons la déclaration des variables, la définition des fonctions objectifs et la définition des expressions de contraintes.
Les variables PuLP sont déclarées comme suit:
#Nom Indice Limite inférieure Limite supérieure Type (continu ou entier)
buy = LpVariable.dicts("buy", (OILS, TIME_IDX), lowBound=0, upBound=None, cat='Continuous')
D'ailleurs, bien que cela ne soit pas mentionné dans le document, il semble qu'il puisse être déclaré sous forme de matrice.
buy = LpVariable.matrix("buy", (OILS, TIME_IDX), lowBound=0, upBound=None, cat='Continuous')
Premièrement, la fonction objectif est exprimée en utilisant les variables et paramètres définis.
#Calcul de la fonction objectif
total_sales = lpSum(produce[t] * sell_uc for t in TIME_IDX)
total_buy_cost = lpSum(buy[oil][t] * buy_uc[oil][t] for t in TIME_IDX for oil in OILS)
total_stock_cost = lpSum(closing_stock[oil][t] * stock_uc for t in TIME_IDX for oil in OILS)
total_cost = total_buy_cost + total_stock_cost
total_profit = total_sales - total_cost #Fonction objective
Vous pouvez ensuite définir le problème de planification linéaire LpProblem
et le définir en ajoutant la fonction objectif.
#Définition du modèle et paramètres de la fonction objectif
model = LpProblem("Food manufacture 1", LpMaximize)
model += total_profit
Vous pouvez également utiliser des méthodes pour définir la fonction objectif comme suit:
model.setObjective(total_profit)
Si vous déclarez plus d'une fonction objectif, seule la dernière sera utilisée.
Les expressions de contrainte peuvent être déclarées en les ajoutant à model
, tout comme la fonction objective.
#Balance de production
for t in TIME_IDX:
model += produce[t] == lpSum(use[oil][t] for oil in OILS)
Elle est écrite de la même manière que la fonction objectif, mais elle semble bien identifiée à partir du nom de la classe. Il peut également être défini par une méthode.
model.addConstraint(produce[t] == lpSum(use[oil][t] for oil in OILS))
Bien qu'omis jusqu'à présent, la fonction objectif et l'expression de contrainte peuvent être nommées individuellement.
model += produce[t] == lpSum(use[oil][t] for oil in OILS), "Production balance"
L'ensemble du code du modèle implémenté cette fois est résumé ci-dessous.
import numpy as np
import pandas as pd
from pulp import LpProblem, LpMaximize, LpVariable, lpSum
#Définition de l'ensemble
TIME_IDX = [1, 2, 3, 4, 5, 6]
OILS = ['VEG1', 'VEG2', 'OIL1', 'OIL2', 'OIL3']
REF_LINES = ['VEG', 'NONVEG']
USED_OILS = {
'VEG': ['VEG1', 'VEG2'],
'NONVEG': ['OIL1', 'OIL2', 'OIL3']
}
#Paramètres des paramètres
sell_uc = 150
stock_uc = 5
stock_ub = 1000
stock_init = 500
stock_final_lb = 500
prod_ub = {'VEG': 200, 'NONVEG': 250}
hardness_lb = 3
hardness_ub = 6
hardness = {'VEG1': 8.8, 'VEG2': 6.1, 'OIL1': 2.0, 'OIL2': 4.2, 'OIL3': 5.0}
buy_uc = {
'VEG1': {1: 110, 2: 130, 3: 110, 4: 120, 5: 100, 6: 90},
'VEG2': {1: 120, 2: 130, 3: 140, 4: 110, 5: 120, 6: 100},
'OIL1': {1: 130, 2: 110, 3: 130, 4: 120, 5: 150, 6: 140},
'OIL2': {1: 110, 2: 90, 3: 100, 4: 120, 5: 110, 6: 80},
'OIL3': {1: 115, 2: 115, 3: 95, 4: 125, 5: 105, 6: 135}
}
#Définition variable
buy = LpVariable.dicts("buy", (OILS, TIME_IDX), lowBound=0)
use = LpVariable.dicts("use", (OILS, TIME_IDX), lowBound=0)
produce = LpVariable.dicts("produce", TIME_IDX, lowBound=0)
opening_stock = LpVariable.dicts("opening_stock", (OILS, TIME_IDX), lowBound=0, upBound=stock_ub)
closing_stock = LpVariable.dicts("closing_stock", (OILS, TIME_IDX), lowBound=0, upBound=stock_ub)
#Calcul de la fonction objectif
total_sales = lpSum(produce[t] * sell_uc for t in TIME_IDX)
total_buy_cost = lpSum(buy[oil][t] * buy_uc[oil][t] for t in TIME_IDX for oil in OILS)
total_stock_cost = lpSum(closing_stock[oil][t] * stock_uc for t in TIME_IDX for oil in OILS)
total_cost = total_buy_cost + total_stock_cost
total_profit = total_sales - total_cost
#Définition du modèle et paramètres de la fonction objectif
model = LpProblem("Food manufacture 1", LpMaximize)
model += total_profit
#Expression de contrainte
#Stock initial, stock final
for oil in OILS:
model += opening_stock[oil][TIME_IDX[0]] == stock_init
model += closing_stock[oil][TIME_IDX[-1]] >= stock_final_lb
#Concernant chaque mois
for t in TIME_IDX:
#Solde des stocks
for oil in OILS:
if t != TIME_IDX[0]:
model += opening_stock[oil][t] == closing_stock[oil][t - 1]
model += closing_stock[oil][t] == opening_stock[oil][t] + buy[oil][t] - use[oil][t]
#Solde du volume des ventes
model += produce[t] == lpSum(use[oil][t] for oil in OILS)
#dureté
total_hardness = lpSum(hardness[oil] * use[oil][t] for oil in OILS)
model += total_hardness <= hardness_ub * produce[t]
model += total_hardness >= hardness_lb * produce[t]
#Limite supérieure de la quantité de purification
for line in REF_LINES:
total_prod_amount = lpSum(use[oil][t] for oil in USED_OILS[line])
model += total_prod_amount <= prod_ub[line]
model.solve()
print(model.objective.value()) #résultat: 107842.59264500001
L'exécution du code ci-dessus vous donnera la valeur «107842.59264500001» comme valeur de la fonction objectif. C'est la même chose que ce qui était écrit dans le texte original, il semble donc bon de penser que la solution optimale est recherchée.
Dans la section précédente, la même valeur optimale que le texte a été trouvée. Cependant, lorsqu'on utilise réellement l'optimisation mathématique au travail, il arrive souvent que ni la valeur optimale ni la solution optimale ne soient connues, et il est rare de pouvoir "faire correspondre les réponses" comme cette fois. Par conséquent, nous vérifierons la validité des résultats en analysant qualitativement le modèle.
L'analyse qualitative consiste ici à faire une prédiction sur la valeur à prendre par la solution optimale à partir de la définition du modèle et à la comparer avec le résultat réel du calcul. Par exemple, cette fois, le premier et le dernier inventaire (la limite inférieure) sont fixes, et cela coûte en fonction du montant de l'inventaire chaque mois, il est donc rentable de consommer l'inventaire en premier et de récupérer l'inventaire au milieu. Sera plus élevé. "
Maintenant, affichons la solution optimale et confirmons cette hypothèse. La solution optimale pour l'inventaire de fin d'année peut être obtenue comme suit.
closing_stock_value = {oil: {t: closing_stock[oil][t].value() for t in TIME_IDX} for oil in OILS}
Tracons avec le code suivant.
df = pd.DataFrame(closing_stock_value, index=TIME_IDX, columns=OILS)
df.plot()
A l'exception de OIL1, qui n'est pas du tout utilisé, tous sont sortis du stock initial une fois puis récupérés, confirmant que les résultats d'optimisation semblent raisonnables.
Nous n'avons testé qu'une seule hypothèse ici, mais en pratique, nous ferons autant d'hypothèses raisonnables que possible pour tester les résultats d'optimisation. Et si la solution optimale est aussi bonne que toutes les hypothèses, il semble qu'elle puisse être mise en œuvre correctement. Inversement, si la solution optimale ne répond pas à l'hypothèse, alors soit la mise en œuvre du modèle, soit l'hypothèse est incorrecte. Ceci est très utile car cela vous donne la possibilité de modifier le modèle lui-même et d'acquérir une meilleure compréhension du modèle.
À propos, certaines personnes peuvent se sentir mal à l'aise avec la méthode de vérification que j'ai écrite plus tôt. Si vous êtes un ingénieur logiciel, vous vous demandez peut-être: "Si l'on vous donne des contraintes une par une, pourquoi ne pas écrire un test unitaire pour chacune?" C'est vrai, et si vous pouvez l'écrire, vous devriez l'écrire.
Cependant, les modèles d'optimisation mathématique sont des ** énormes ** ensembles de contraintes ** étroitement couplées **, et les tests unitaires au niveau des contraintes sont souvent difficiles. Les formules de contraintes mentionnées précédemment semblent également être distinctes, mais en fait elles dépendent les unes des autres dans le modèle. Par exemple, si vous réduisez la limite supérieure de la quantité de purification, vous ne pourrez pas respecter la contrainte de dureté. Bien sûr, il est possible de tester le modèle lui-même en tant que fonction énorme, mais il est difficile de connaître la classe d'équivalence, la valeur limite, etc. (Bien qu'il puisse être automatisé).
En fait, en regardant le code de test du solveur d'optimisation mathématique open source, il semble que nous n'ayons résolu que quelques problèmes de jouets qui sont faciles à comprendre et qui n'ont pas été très rigoureux (test de modèle et solveur). Bien que cela puisse être différent dans le test).
https://github.com/SCIP-Interfaces/CSIP/blob/6d24c495750c7927d1d9b1bae0e906d9c54fa439/test/test.c#L57-L63
J'ai également recherché des recherches et de la littérature sur les tests d'optimisation mathématique, mais je n'ai rien trouvé de tel. Il est possible que vous l'ayez manqué, donc si vous avez une opinion telle que "C'est bien", j'apprécierais que vous puissiez commenter.
Pour le moment, la difficulté de tester ici semble être proche du problème de tester les modèles d'apprentissage automatique sur lesquels travaille la communauté MLSE, il est donc préférable de suivre les tendances de cette communauté.
Challenges for machine learning systems toward continuous improvement https://www.slideshare.net/chezou/challenges-for-machine-learning-systems-toward-continuous-improvement
Au fait, cela n'a pas d'importance, mais j'ai eu l'impression de ne rien dire quand j'ai vu l'article suivant, qui semble utiliser l'optimisation mathématique, brûlé et commenté comme "Test it". (Je ne suis pas une personne apparentée ...).
Ça devrait être "quelques secondes avec l'IA" ... Sélection école maternelle, travail après des vacances consécutives Saitama City --Mainichi Shimbun https://mainichi.jp/articles/20200204/k00/00m/040/176000c
Même si vous faites de votre mieux pour vérifier avec la méthode décrite jusqu'à présent, c'est un casse-tête car le modèle peut devenir illimité ou irréalisable en raison de données inattendues. Épicé: chien:
Donc, j'ai modélisé le plan de production comme une méthode de programmation linéaire, je l'ai résolu avec PuLP et j'ai essayé de vérifier le résultat. J'ai l'intention d'écrire non seulement une simple explication de la modélisation, mais aussi mes propres réflexions sur la modélisation basées sur une petite expérience pratique.
Si vous commencez à vous entraîner à la modélisation, vous souhaiterez peut-être changer ce modèle à votre manière. Par exemple, vous pouvez définir des limites supérieures et inférieures pour chaque type de mois et de pétrole dans le montant de l'achat, ou définir une perte de 1% dans le processus de raffinage.
Je voulais vraiment en faire une série et résoudre tous les exercices, mais j'étais épuisé: joie: Si vous venez de le résoudre, il est toujours difficile d'écrire un article.
Alors, si vous aimez cet article, inscrivez-vous! (Style YouTuber).
Recommended Posts