Boucler sur Python

Bea - Modifié le 11 avril 2024 à 18:49
mamiemando Messages postés 33088 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 30 avril 2024 - 12 avril 2024 à 15:11

Bonjour,

J'ai un travail assez conséquent à faire sur Python, malheureusement je ne suis pas dans ce domaine et je me retrouve complètement bloquée. 

J'ai une base de données, que j'ai créé, de 500 produits végétaux. On y retrouve beaucoup d'informations, mais le plus important reste leurs compositions en protéines et en acides aminés (en g/100g de produit végétal). Je souhaite crée un mélange de produits végétaux qui égalise ou surpasse (mais doit toujours être le plus proche possible) de ma référence, la whey. 

Pour ceci, je souhaite utiliser Python et des boucles, comme dans une simulation de Monte Carlo. Je veux que mon programme passe en revue tous les mélanges possibles de végétaux, avec un pas de 10g et un poids max de 300g du même produit dans le mélange. Pour donner un exemple de à quoi devrait ressembler la boucle : 0g de soja + 10g de blé, puis 0g de soja + 20g de blé, puis 0g de soja + 30g de blé, etc. jusqu'au poids max, puis 10g de soja + 0g de blé, puis 20g de soja + 0g de blé, etc. ... 

J'ai beau chercher par moi même sur tous les sites, je n'arrive pas à faire comprendre cette commande à Python. Voici un début de code (après import des bibliothèques et de mes données bien entendu) que je pensais juste mais qui ne l'est pas : 

# Poids maximal du produit végétal
p_max = 301 #grammes

# Pas 
pas = 10 #grammes

# Boucles : 
for poids in range(0, p_max, pas):
    poids_g = poids / 100.0  # Convertir le poids en grammes
    
    # Calculer la composition en acides aminés et en protéines du mélange pour le poids retenu
    melange = np.sum(veg_data * poids_g, axis=0)
    
    if np.all(melange < ref_data):
            continue
    if np.all(melange == ref_data):
            break
    if np.all(melange > ref_data):
            break        

if melange is not None : 
    # Calculer la distance par rapport à la Whey en utilisant la racine carrée de l'erreur quadratique moyenne
    difference = melange - ref_data
    mse = np.sqrt(np.mean(difference ** 2))
    print("Distance par rapport à la Whey :", mse)
    print()
    
    # Convertir melange en DataFrame
    melange_df = pd.DataFrame([melange], columns=veg_data.columns)
    # Ajouter une colonne "Type" au DataFrame melange_df pour identifier le type de données (mélange ou whey)
    melange_df.insert(0, 'Type', 'Melange')
    # Insérer une colonne "Type" au début de ref_data pour identifier le type de données (mélange ou whey)
    ref_data.insert(0, 'Type', 'Whey')
    # Concaténer les DataFrames melange_df et ref_data
    resultat_final = pd.concat([melange_df, ref_data], ignore_index=True)
    # Afficher le tableau final
    print(resultat_final)
    
    print("Quantité minimale de chaque produit végétal utilisée :", poids_g * 100, "g")

else:
    print("Aucun mélange satisfaisant trouvé.")   

Je ne l'ai pas précisé ci-dessus, mais étant donné la taille de la base de données, j'ai commencé ce code pour seulement deux produits. Je me dis que si le code marche pour 2 produits, il pourra marcher pour 500 même si il me faudra surement une machine plus performante pour faire tourner ce programme. 

Si vous avez une idée ou une question, je suis preneuse. Je veux vraiment faire ce travail ... Merci pour votre aide ! 
Windows / Chrome 123.0.0.0

3 réponses

yg_be Messages postés 22744 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 1 mai 2024 1 477
9 avril 2024 à 10:29

bonjour,

merci de partager un programme complet et testable.  donc avec les import et les données.

Tu écris "poids max de 300g du même produit", donc tu peux avoir 15kg au total?

Je suppose qu'il est inutile, après avoir testé 10g de soja + 10g de blé, de tester ensuite 20g de soja + 20g de blé, que c'est le même "mélange"?

0
yg_be Messages postés 22744 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 1 mai 2024 1 477
9 avril 2024 à 10:47

essaie plutôt ceci:

import itertools
import numpy as np
# Poids maximal du produit végétal
p_max = 301 #grammes

# Pas 
pas = 10 #grammes

# Boucles : 
for comb_poids in itertools.product(range(0, p_max, pas),repeat=2):
    print(comb_poids)
0
mamiemando Messages postés 33088 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 30 avril 2024 7 751
11 avril 2024 à 19:12

Bonjour,

Pour un faible nombre de produits, tu peux te contenter d'un produit cartésien (et donc utiliser comme yg_be le propose, itertools.product)

from itertools import product

for (i, j, k) in product(
    range(0, 5),      # i = 0, 1, 2, 3, 4
    range(1, 3),      # j = 1, 2
    range(10, 21, 5)  # k = 10, 15, 20
):
    print(i, j, k)

Cette fonction permet, de considérer un nombre arbitraire de dimension (3 dimensions dans l'exemple ci-dessus).

Maintenant, parlons complexité (algorithmique). Supposons que mes dimensions comportent chacune N éléments. Alors exécuter cette boucle se fait en O(N^3), c'est-à-dire à un coût qui croit de manière cubique avec le nombre d'éléments. Si tu as m dimensions, on a donc un coup en O(N^m) ce qui est bien trop coûteux en pratique (de manière générale, on évite d'aller au delà de m=2 pour de grands jeux de données). Ce sera donc "trop cher" d'évaluer toutes les configurations possibles.

Avant de considérer une éventuelle implémentation, l'idéal serait donc de formuler ton problème sous la forme d'un problème d'optimisation. Si tu n'es pas familière de cette discipline, peut-être peux tu exprimer les différents aspects de ton problème en français et on t'aidera à les traduire. En fonction du modèle d'optimisation obtenu, on verra quelle est la manière la plus efficace de le résoudre. Je m'explique.

De manière générale, quand tu modélises un problème d'optimisation, il faut caractériser :

  • L'objectif : ce que tu cherches à optimiser (soit minimiser, soit maximiser)
  • Les variables de décisions : dans ton cas la quantité de chaque type d'ingrédient
  • Les contraintes :
    • Contraintes de domaines : quel est le domaine de définition de chaque variable de décision
    • Autre contraintes : potentiellement n'importe quoi, par exemple la quantité totale d'ingrédient A + d'ingrédient B ne doit pas excéder une certaine masse.

D'un point de vue pratique, on préfère :

  • les objectifs formulés sous forme d'une fonction linéaire ;
  • les variables continues (par opposition aux variables discrètes) ;
  • les contraintes linéaires.

... car on tombe alors sur un programme linéaire qui se résout rapidement et facilement (par exemple en python avec PuLP).

Bonne chance

0
yg_be Messages postés 22744 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 1 mai 2024 1 477
Modifié le 11 avril 2024 à 21:46

En réalité, tout est déjà expliqué:

J'ai une base de données, que j'ai créé, de 500 produits végétaux. On y retrouve beaucoup d'informations, mais le plus important reste leurs compositions en protéines et en acides aminés (en g/100g de produit végétal). Je souhaite crée un mélange de produits végétaux qui égalise ou surpasse (mais doit toujours être le plus proche possible) de ma référence, la whey.

Il recherche la proportion de produits dont la composition en protéines et la composition en acides aminés sont supérieures ou égales, et les plus proches, des compositions correspondantes de la whey.

  • Il a donc 500 variables continues, nulles ou positives, dont la somme doit faire 1, Pi.
  • Deux fois 500 constantes, les compositions en protéines et en acides aminés de chacun des 500 produits, PRi & AAi
  • 2 constantes, les compositions en protéines et en acides aminés de la Whey, WPR et WAA
  • 2 contraintes, sommes sur i des Pi*PRi >= WPR et iPi*AAi >= WAA
  • à optimiser, disons (choix peut-être à affiner) minimiser la somme de (sommes sur i des Pi*PRi) et de (sommes sur i des Pi*AAi)
1
mamiemando Messages postés 33088 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 30 avril 2024 7 751 > yg_be Messages postés 22744 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 1 mai 2024
12 avril 2024 à 15:11

Hello yg_be,

Merci d'avoir pris le message initiale dans une formulation qui est beaucoup plus clair pour moi (cela répond donc à la question que je me posais dans #3). Le modèle me paraît correct et rentre bien dans un solveur de programme linéaire genre PuLP. Juste quelques remarques à ce sujet :

  • Si j'ai bien compris tu nommes Pi le pourcentage d'ingrédient i dans le produit final. Tes contraintes indique que le produit final doit satisfaire des critères de composition (cf tes contraintes sur WPR et WAA), et la composition est bien relié à chaque ingrédient.
  • Je suspecte que l'objectif sera plutôt économiser le "coût" du produit et donc il faudrait probablement introduire le prix de chaque ingrédient (disons Ki) et minimiser sum_i Ki.Pi (aux unités près, puisque le prix sera probablement en €/g plutôt qu'en €/%). Mais bon c'est peut-être moi qui tire des conjectures hâtives, toujours est-il que c'est notamment pour ça que je demandais des précisions sur l'objectif de l'étude...
0