IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Mathématiques Discussion :

Algorithme récursif de calcul de moyenne


Sujet :

Mathématiques

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 116
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 116
    Par défaut Algorithme récursif de calcul de moyenne
    Bonjour, je veux faire un programme en C de calcul de moyenne, mais je suis confronté à un problème de limitation de type.

    En fait, j'ai un tableau de unsigned long de 5000 points, et je veux réaliser une moyenne sur ce tableau. La difficulté est que la somme directe a toutes les chances de ne pas fonctionner, car la somme de 5000 unsigned long risque ne ne pas tenir dans un unsigned long. Je voudrai faire un algo du type
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    double mean_extreme(unsigned long * tab_in , unsigned long i, unsigned long size);
    {
         double moyenne_calculee;
         while(i!=(size/2)-1)
         {
              moyenne_calculee=((tab_in[i] + tab_in[size-i-1])/2.0 + mean_extreme(tab_in,i+1,size))/2.0;
         }
         return moyenne_calculee;
    }
    Ça a une chance de marcher ?

  2. #2
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 78
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Par défaut
    Une moyenne est un isobarycentre.
    Tu peux appliquer le théorème d'associativité des barycentres.
    Qui dit que le barycentre de
    (P1,m1) .... (Pn,mn)
    est le barycentre du
    barycentre de
    (P1,m1) .... (Pn-1,mn-1) avec la masse m1+m2+ ..mn-1
    avec le point pondéré (Pn,mn)
    dans ce cas de figure la moyenne de
    x1, .....,xn
    est le barycentre de la moyenne de
    x1,...xn-1 avec la masse n-1
    avec le point (xn,1)
    Il suffit d'itérer:
    Moyenne des deux premiers
    Moyenne pondérée de cette moyenne avec la masse 2 et du troisième avec la masse 1
    Moyenne pondérée de cette moyenne avec la masse 3 et du qautrième avec la masse 1
    And so on till the end
    Ce qu'on trouve est plus important que ce qu'on cherche.
    Maths de base pour les nuls (et les autres...)

  3. #3
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Par défaut
    Citation Envoyé par kromartien Voir le message
    La difficulté est que la somme directe a toutes les chances de ne pas fonctionner, car la somme de 5000 unsigned long risque ne ne pas tenir dans un unsigned long.
    c'est pour ca qu'on a inventé les "double"...
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    double moyenne_calculee=0;
    for(int i=0;i<size;i++)
        moyenne_calculee+=tab_in[i];
    moyenne_calculee/=size;
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  4. #4
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 116
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 116
    Par défaut
    Pour la pondération des moyennes successives, ça me paraît être la bonne méthode.
    Et autrement, est-ce que l'appel récursif est correct, l'appel va-t-il marcher ? Ce serait beau d'utiliser la récursion.

  5. #5
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 116
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 116
    Par défaut
    J'ai réécrit la version récursive et fait une version itérative :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
     
    double mean_extreme(unsigned long * tab_in , unsigned long i, unsigned long size)
    {
    	if(i<(size/2))
    	{
    		double moyenne_calculee;
    		moyenne_calculee=((tab_in[i] + tab_in[size-i-1])/2.0 + mean_extreme(tab_in,i+1,size))/2.0;
    	}
    	else
    	{
    		return moyenne_calculee;
    	}
    }
     
    double mean_ponderee(unsigned long * tab_in, unsigned long SIZE)
    {
    	unsigned long i;
    	double current_mean=tab_in[0];
    	for(i=0;i<SIZE-1;i++)
    	{
    		current_mean = (current_mean * ((i+1.0)/(i+2.0))) + tab_in[i+1])*(1.0/(i+2.0));
    	}
    	return current_mean;
    }

  6. #6
    Membre Expert Avatar de Nemerle
    Inscrit en
    Octobre 2003
    Messages
    1 106
    Détails du profil
    Informations personnelles :
    Âge : 55

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 106
    Par défaut
    z'etes un peu fou les gars... pseudocode a tout bien résumé...

  7. #7
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 116
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 116
    Par défaut
    D'accord, j'ai utilisé ces deux algorithmes en concurrence :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    /*(1)*/
    double mean_ponderee(unsigned long * tab_in, unsigned long SIZE)
    {
    	unsigned long i;
    	double current_mean=tab_in[0];
    	for(i=0;i<SIZE-1;i++)
    	{
    		current_mean = (current_mean * ((i+1.0)/(i+2.0))) + tab_in[i+1]*(1.0/(i+2.0));
    	}
    	return current_mean;
    }
     
    /*(2)*/
    double mean_classic(unsigned long * tab_in, unsigned long SIZE)
    {
    	unsigned long i;
    	double mean=0;
    	for(i=0;i<SIZE;i++)
    	{
    		mean=mean+tab_in[i];
    	}
    	mean = mean/SIZE;
    	return mean;
    }
    Et j'obtiens de part et d'autre le même résultat.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    22.498000(1), 22.498000(2)
    Ça marche, voilà, le premier a tout de même l'avantage de prévenir un dépassement de capacité de type.

    Merci beaucoup.

  8. #8
    Inactif  
    Inscrit en
    Mars 2006
    Messages
    352
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 352
    Par défaut
    Bonjour,
    Citation Envoyé par kromartien Voir le message
    Bonjour, je veux faire un programme en C de calcul de moyenne, mais je suis confronté à un problème de limitation de type.

    En fait, j'ai un tableau de unsigned long de 5000 points, et je veux réaliser une moyenne sur ce tableau. La difficulté est que la somme directe a toutes les chances de ne pas fonctionner, car la somme de 5000 unsigned long risque ne ne pas tenir dans un unsigned long. Je voudrai faire un algo du type
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    double mean_extreme(unsigned long * tab_in , unsigned long i, unsigned long size);
    {
         double moyenne_calculee;
         while(i!=(size/2)-1)
         {
              moyenne_calculee=((tab_in[i] + tab_in[size-i-1])/2.0 + mean_extreme(tab_in,i+1,size))/2.0;
         }
         return moyenne_calculee;
    }
    Ça a une chance de marcher ?
    J'ai déroulé ton code à travers un tout petit exemple mais malheureusement ça marche pas !

    Cependant, je voulais faire quelques remarques et suggestions à propos de ce code :
    - Le compteur i n'est pas initialisé,
    - La variable i n'a pas besoin d'être du type long, un simple int suffirait,
    - As-tu vraiment besoin d'une version récursive ? Autrement dit une version itérative ne t'intéresse pas ?
    -Je pense que l'utilisation l'opérateur de comparaison < serait plus propre et plus logique !


    Citation Envoyé par kromartien Voir le message
    Pour la pondération des moyennes successives, ça me paraît être la bonne méthode.
    À mon avis, pourquoi ne pas changer l'échelle : une sorte de petite codification en divisant tous les éléments du tableau par 10, 100, 1000, 10000, ...etc tout dépend des éléments s'ils sont petits, grands, trop grands, ...etc
    Et calculer la moyenne tranquillement sans le moindre souci !

    À bientôt.

Discussions similaires

  1. Algorithme récursif et calcul de complexité
    Par Lithrein dans le forum Algorithmes et structures de données
    Réponses: 3
    Dernier message: 14/12/2011, 01h10
  2. Réponses: 4
    Dernier message: 14/12/2009, 20h31
  3. Réponses: 1
    Dernier message: 24/02/2009, 20h28
  4. [Erreur] algorithme qui calcul une moyenne
    Par quaresma dans le forum Algorithmes et structures de données
    Réponses: 29
    Dernier message: 24/04/2008, 20h58
  5. calculer une moyenne avec une requete externe
    Par allowen dans le forum Langage SQL
    Réponses: 3
    Dernier message: 27/01/2005, 16h02

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo