Algorithme génétique en santé (2/5)
🩺 Le problème#
Dans la première partie de cet article nous avons défini un problème où on devait aider une amie médecin à définir quelles compétences elle devait chercher chez un(e) associé(e) pour pouvoir amortir son investissement dans les locaux de son nouveau cabinet médical.
Nous avons démarré le problème par dire qu’une distribution identique des charges de travail (des actes médicaux) était peut être la solution la plus simple.
En faisant comme ça, les médecins feraient 118,44€ / heure. Mais est-ce que c’est vraiment la meilleure solution ?
Pour le savoir on va utiliser une méthodologie qui s’appelle Optimisation Linéaire. Mais qu’est-ce ?
🧮 Optimisation linéaire#
Pas de panique. Je ne vais pas rentrer dans les détails mathématiques mais rester dans les grands traits de cette technique.
En gros cela veut dire qu’on a 3 éléments essentiels :
- Une équation comme par exemple : $$ f(x, y) = 300x + 500y $$
- La volonté de trouver le maximum ou minimum de cette fonction
- Des contraintes, comme par exemple le fait que x + y ne peut pas dépasser la valeur de 100
Voilà c’est tout ce que vous devez savoir. Mais si le sujet vous inspire, il y a plus d’information ici .
👩🏽💻 Ecrire les contraintes#
Imaginons que l’on souhaite maximiser le montant total journalier de ce médecin.
Il souhaiterait néanmoins ne pas travailler plus de 7 heures par jour.
Combien de consultations devrait t’il faire pendant la journée ?
L’équation est : $$ \max 25x1+38.40x2+40.28x3+25x4+41.80x5+37.46x6+68.80x7 $$
Et les contraintes : $$ 15x1 + 22x2 + 17x3 + 13x4 + 25x5 + 23x6 + 55x7 \leq 420 $$
420 = 7 heures * 60 minutes
🐈 Un exemple plus général#
On va partir un peu loin mais restez-avez moi, cela reste pertinent pour notre problème…
Un producteur de nourriture pour chat souhaite créer des cannettes nutritives avec différentes viandes. En effet ils ont besoin de certains acides aminés issus de la viande pour survivre. Les chats ne peuvent donc pas devenir végétariens car sinon il serait gravement malades (petite info utile pour briller en société).
Les différentes sources dont on dispose sont :
- Poulet
- Boeuf
- Riz
- Son de blé
Qui a leur tour on des compositions différentes de protéines, acides gras, fibre et sel.
On aimerait avoir un mélange entre poulet, boeuf, riz et son de blé qui respecte les nutriments minimaux d’un chat mais qui minimise le coût de production de la canette afin de pouvoir garder un revenu correct.
Imaginons que les canettes font 100g et que la viande de poulet coûte 0.013 €/g et le boeuf 0.008 €/g
L’équation est : $$ \min 0.013x1 + 0.008x2 $$
Je vous éparge les nutriments de chaque viande et les besoins nutritionnels des chats, mais disons que les contraintes sont :
$$ 1.000x1 + 1.000x2 = 100.0 $$ $$ 0.100x1 + 0.200x2 \geq 8.0 $$ $$ 0.08x1 + 0.100x2 \geq 6.0 $$ $$ 0.001x1 + 0.005x2 \leq 2.0 $$ $$ 0.002x1 + 0.005x2 \leq 0.4 $$
Nous allons utiliser une libraire en python qui s’appelle PuLP pour trouver la solution à cette équation.
"""
The Simplified Whiskas Model Python Formulation for the PuLP Modeller
Authors: Antony Phillips, Dr Stuart Mitchell 2007
"""
# Import PuLP modeler functions
from pulp import *
# Create the 'prob' variable to contain the problem data
prob = LpProblem("The Whiskas Problem",LpMinimize)
# The 2 variables Beef and Chicken are created with a lower limit of zero
x1=LpVariable("ChickenPercent",0,None,LpInteger)
x2=LpVariable("BeefPercent",0)
# The objective function is added to 'prob' first
prob += 0.013*x1 + 0.008*x2, "Total Cost of Ingredients per can"
# The five constraints are entered
prob += x1 + x2 == 100, "PercentagesSum"
prob += 0.100*x1 + 0.200*x2 >= 8.0, "ProteinRequirement"
prob += 0.080*x1 + 0.100*x2 >= 6.0, "FatRequirement"
prob += 0.001*x1 + 0.005*x2 <= 2.0, "FibreRequirement"
prob += 0.002*x1 + 0.005*x2 <= 0.4, "SaltRequirement"
# The problem data is written to an .lp file
prob.writeLP("WhiskasModel.lp")
# The problem is solved using PuLP's choice of Solver
prob.solve()
# The status of the solution is printed to the screen
print("Status:", LpStatus[prob.status])
# Each of the variables is printed with it's resolved optimum value
for v in prob.variables():
print(v.name, "=", v.varValue)
# The optimised objective function value is printed to the screen
print("Total Cost of Ingredients per can = ", value(prob.objective))
La solution est qu’il faut 33,33% de viande de poulet et 66,67% de boeuf pour un coût total de 96 c€ par canette.
🎉 Notre solution#
Nous appliquons la même méthodologie chez nous, et on retrouve ….
🥁
🎉 Qu’il faut faire 23 spirométries et 2 téléconsultations par jour. 🎉
De cette manière il travaillera 6 heures et 57 minutes pour faire 976,44€ de chiffre d’affaires.
Vous pouvez faire vos propres tests ici .
Comparativement cela correspond à 147,36 euros de plus que ce qu’il gagnait en répartissant de manière identique son temps.
Pourquoi 2 téléconsultations et non pas 2 consultations alors qu’elle sont côtées pareil ? Puisqu’une téléconsultation dure moins de temps qu’une consultation alors qu’ils ont la même valeur.
En effet, si un acte est très bien valorisé mais il prend beaucoup plus de temps à être réalisé, vous aurez pu pendant ce même temps faire plusieurs actes moins valorisés mais plus rapides et donc pour la même quantité de temps le médecin aurait pu avoir plus de revenus.
Vous pouvez mettre d’autres contraites au système ! Par exemple distribuer les consultations et les téléconsultations à part égales, ou que l’ensemble ne soit pas plus de 40% de votre temps.
😡 Tout ça pour ça ?
Bon, je comprends si vous n’êtes pas impréssionés, même si vous venez de découvrir un outil qui peut dépanner dans pas mal de situations.
Sauf que, pour les plus perspicaces d’entre vous, vous remarquerez qu’on est assez limités. Imaginons que la durée des consultations évolue avec le temps ou que le médecins souhaitent travailler plus ou moins d’heures une même journée ou pendant la semaine ou finalement qu’il souhaite diviser la charge de travail entre plusieurs collègues. Il serait plus pratique dans ce cas là non pas de parler en consultations par jour mais plutôt de la proportion de consultations. Auquel cas, ce que l’on souhaite maximiser n’est pas juste la valeur moyenne de l’acte mais plutôt le revenu par heure. Or le revenu par heure est une multiplication du revenu moyen / acte multiplié par le nombre d’actes faits en moyenne par heure.
Sauf que l’optimisation linéaire ne peut résoudre que des équations avec des relations additives entre les différents paramètres. Donc, on ne peut pas l’utiliser pour notre problème 👋🏼.
Donc il faudra utiliser un algorithme plus adapté à ce type de situations ….
C’est là où arrive le type d’algorithme qui est dans le titre de cette série : Les algorithmes génétiques.
Mais ça sera pour la prochaine fois…