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

Langage PHP Discussion :

Moyenne des noeuds d'un arbres [PHP 5.4]


Sujet :

Langage PHP

  1. #1
    Membre du Club
    Inscrit en
    Novembre 2010
    Messages
    135
    Détails du profil
    Informations forums :
    Inscription : Novembre 2010
    Messages : 135
    Points : 53
    Points
    53
    Par défaut Moyenne des noeuds d'un arbres
    Bonjour,

    Je souhaiterai calculer la moyenne d'un noeud d'un arbre par ses feuilles enfants en récursif.
    Je n'ai pas l'habitude de travailler en récursif et je sèche vraiment.

    Mon tableau est de la forme ci-dessous :

    T[0]['id']=>27
        ['libelle']=>Feuille 1
        ['valeur']=>?
        ['noeudEnfant']=>T[0]['id']=>26
                ['libelle']=>Feuille 1.1
                ['valeur']=>1
                ['noeudEnfant']=> null
            T[1]['id']=>25
                ['libelle']=>Feuille 1.2
                ['valeur']=>?
                ['noeudEnfant']=> T[0]['id']=>24
                        ['libelle']=>Feuille 1.2.1
                        ['valeur']=>4
                        ['noeudEnfant']=> null
                    T[1]['id']=>23
                        ['libelle']=>Feuille 1.2.2
                        ['valeur']=>1
                        ['noeudEnfant']=>null
                    T[...]...
    T[...]...

    Comment puis je procéder?

    J'arrive bien à faire la somme pour un noeud mais je ne pense pas que cela soit optimisé et de plus c'est la moyenne qui m'interesse.
    Fonction pour calculer la somme que j'ai crée :
    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
    function SommeNoeudsRecursif($tabGlobal){
        foreach($tabGlobal as $tab){
            $tab['valeur']=$this->SommeRecursif($tab);
        }
     
        return $tabGlobal;
    }
     
    function SommeRecursif($noeud){
        $somme=0;
        if(count($noeud['indicateurSuivant'])>0){
            foreach($noeud['indicateurSuivant'] as $enfant){
                if(count($enfant['indicateurSuivant'])>0){
                    $somme += $this->SommeRecursif($enfant);
                } else {
                     $somme +=  $enfant['valeur'];
                }
            }
        } else {
             $somme +=  $noeud['valeur'];
        }
     
        return $somme;
    }
    Help please.

  2. #2
    Membre actif
    Avatar de Micmaya
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2010
    Messages : 131
    Points : 202
    Points
    202
    Billets dans le blog
    3
    Par défaut
    Bonjour,
    Je ne connaissais pas cette notion d'arbre en programmation, bien que je l'ai déjà fait sur papier
    Sinon, je peux te conseiller d'aller voir sur le site suivant: http://fr.wikipedia.org/wiki/Arbre_binaire pour savoir comment parcourir correctement un arbre "binaire".
    ou encore: http://zanotti.univ-tln.fr/algo/PARCOURS-FIXE.html & http://recursivite.developpez.com/?page=page_8 (ce sont des algorithmes, reste à transformer cela en PHP)
    Et pour calculer la moyenne je sais qu'il faut faire la somme divisé par le nombre de noeud. Maintenant, reste à savoir si tu veux calculer la moyenne de tout ton arbre ou bien de chaque noeud (premier noeud de l'arbre ou encore ceux qui contient plus 1 enfant).

    Bien à toi,
    Pensez à mettre comme si c'est le cas !

  3. #3
    Membre expert
    Avatar de Spartacusply
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2011
    Messages
    1 723
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2011
    Messages : 1 723
    Points : 3 274
    Points
    3 274
    Par défaut
    Voici un algorithme qui calcul récursivement la moyenne par parcours en profondeur pré-fixé (le noeud est traité avant les enfants). On recalcule à chaque fois la moyenne directement et on la passe en paramètre pour les noeuds enfants :

    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
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    <?php
     
    $array = array(
        array(
            'valeur' => 7,
            'noeudEnfant' => array(
                array('valeur' => 15),
                array('valeur' => 16),
            )
        ),
        array(
            'valeur' => 7,
            'noeudEnfant' => array(
                array(
                    'valeur' => 15,
                    'noeudEnfant' => array(
                        array('valeur' => 18)
                    )
                ),
                array('valeur' => 16),
            )
        )
    );
     
    function moyenneRecursive($array, $moyenne = 0, $ponderation = 0) {
        foreach ($array as $key => $tab) {
            $moyenne = ($moyenne * $ponderation + $tab['valeur']) / ( ++$ponderation);
            if (isset($tab['noeudEnfant']) AND is_array($tab['noeudEnfant']) AND ! empty($tab['noeudEnfant'])) {
                $moyenne = moyenneRecursive($tab['noeudEnfant'], $moyenne, $ponderation);
            }
        }
        return $moyenne;
    }
     
    echo moyenneRecursive($array);
    Un message utile vous a aidé ? N'oubliez pas le

    www.simplifions.fr - Simplifier vos comptes entre amis !

  4. #4
    Membre actif
    Avatar de Micmaya
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2010
    Messages : 131
    Points : 202
    Points
    202
    Billets dans le blog
    3
    Par défaut
    Merci "Spartacusply", j'avais oublié la pondération mais sinon cela me semble correcte Je n'avais simplement pas le temps de faire le test en PHP vu que je suis au boulot, hi!
    Pensez à mettre comme si c'est le cas !

  5. #5
    Membre du Club
    Inscrit en
    Novembre 2010
    Messages
    135
    Détails du profil
    Informations forums :
    Inscription : Novembre 2010
    Messages : 135
    Points : 53
    Points
    53
    Par défaut
    Merci à vous deux, je regarde ca et vous tiens au courant.

  6. #6
    Membre expert
    Avatar de Spartacusply
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2011
    Messages
    1 723
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2011
    Messages : 1 723
    Points : 3 274
    Points
    3 274
    Par défaut
    Une remarque: ma méthode précédente donne un résultat très approximatif, car elle arrondit à chaque tour de boucle la moyenne.

    Voici un autre algorithme dans la même veine mais beaucoup plus précis : on calcul la somme total, et le nombre total d'élément, pour avoir une moyenne la plus juste possible :

    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
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    <?php
     
    $array = array(
        array(
            'valeur' => 7,
            'noeudEnfant' => array(
                array('valeur' => 15),
                array('valeur' => 16),
            )
        ),
        array(
            'valeur' => 7,
            'noeudEnfant' => array(
                array(
                    'valeur' => 15,
                    'noeudEnfant' => array(
                        array('valeur' => 18)
                    )
                ),
                array('valeur' => 16),
            )
        )
    );
     
    function sumNoeud($array) {
        $sum = 0;
        $ponderation = 0;
        foreach ($array as $key => $tab) {
            $sum += $tab['valeur'];
            $ponderation++;
            if (isset($tab['noeudEnfant']) AND is_array($tab['noeudEnfant']) AND ! empty($tab['noeudEnfant'])) {
                $res = sumNoeud($tab['noeudEnfant']);
                $sum += $res['sum'];
                $ponderation += $res['ponderation'];
            }
        }
        return array('sum' => $sum, 'ponderation' => $ponderation);
    }
     
    function moyenneRecursive($array, $sum = 0, $ponderation = 0) {
        $res = sumNoeud($array);
     
        return $res['sum'] / $res['ponderation'];
    }
     
    echo moyenneRecursive($array);
    Citation Envoyé par Micmaya
    Je ne connaissais pas cette notion d'arbre en programmation, bien que je l'ai déjà fait sur papier
    Et encore, en Php ce sont juste des tableaux ordonnés de telle manière qu'ils représentent un arbre. Dans d'autre langage (comme Java par exemple), il y a des structures spécifiques pour représenter des arbres qui possèdent des méthodes assez poussés sur ce type de structure.

    pour savoir comment parcourir correctement un arbre "binaire".
    Son arbre n'est pas binaire, car chaque noeud n'est pas limité à 2 fils maximums.
    Un message utile vous a aidé ? N'oubliez pas le

    www.simplifions.fr - Simplifier vos comptes entre amis !

  7. #7
    Membre du Club
    Inscrit en
    Novembre 2010
    Messages
    135
    Détails du profil
    Informations forums :
    Inscription : Novembre 2010
    Messages : 135
    Points : 53
    Points
    53
    Par défaut
    Bon j'en étais pas tres loin de cette solution.
    Par contre ce que je souhaiterais faire c'est de renseigner chacun des noeuds avec la moyenne de ces enfants.
    Donc au plus simple serait de partir du bas vers le haut.

    Une idée?

    En tout cas merci à vous.

  8. #8
    Membre du Club
    Inscrit en
    Novembre 2010
    Messages
    135
    Détails du profil
    Informations forums :
    Inscription : Novembre 2010
    Messages : 135
    Points : 53
    Points
    53
    Par défaut
    Avec de la persévérance et votre aide je viens de finir.
    Désormais je parcours chaque noeud et je renseigne leur valeur par la somme de celle de leurs enfants.
    Par contre je ne sais pas si on peut ou non optimiser.

    Qu'en pensez vous?

    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
    26
     
    function SommeNoeudsRecursif($tabGlobal){
        foreach($tabGlobal as $key => $tab){
            $nbEnfants=count($tab['indicateurSuivant']);
            $noeud=$this->SommeRecursif($tab,$nbEnfants);
            $tabGlobal[$key]=$noeud;
        }
        return $tabGlobal;
    }
     
    function SommeRecursif($noeud,$nbEnfants){
        if(count($noeud['indicateurSuivant'])>0){
            foreach($noeud['indicateurSuivant'] as $key => $enfant){
                $nbEnfants=count($enfant['indicateurSuivant']);
                if($nbEnfants>0){
                    $enfant['valeur'] = ($enfant['valeur'] + $this->SommeRecursif($enfant,$nbEnfants)['valeur']) / $nbEnfants;
                    $noeud['indicateurSuivant'][$key]= $enfant;
                    $noeud['valeur'] = ($noeud['valeur'] + $enfant['valeur']) / count($noeud['indicateurSuivant']);
                } else {
                       $noeud['valeur'] = $noeud['valeur'] + $enfant['valeur'];
                }
            }
        }
     
        return $noeud;
    }

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réduction ou classement des noeuds d'une arbre
    Par daniel1985 dans le forum Intelligence artificielle
    Réponses: 0
    Dernier message: 01/10/2012, 09h32
  2. Echange des noeuds d'un Arbre de Huffman
    Par tompote dans le forum C
    Réponses: 2
    Dernier message: 21/01/2011, 10h26
  3. [AC-2003] Créer des Noeud dans un arbre
    Par sassene dans le forum IHM
    Réponses: 0
    Dernier message: 01/07/2010, 10h41
  4. edition ou modification des noeuds d'une arbre JTREE
    Par foufoulina2007 dans le forum Composants
    Réponses: 1
    Dernier message: 30/11/2007, 21h52
  5. somme des noeuds d'un arbre binaire
    Par bibi182 dans le forum Langage
    Réponses: 6
    Dernier message: 08/11/2007, 11h30

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