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

Lisp Discussion :

[Lisp] Construction d un arbre n-aire


Sujet :

Lisp

  1. #1
    Membre régulier
    Inscrit en
    Décembre 2005
    Messages
    271
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 271
    Points : 91
    Points
    91
    Par défaut [Lisp] Construction d un arbre n-aire
    Bonjour,

    Voilà, je travaille sous LISP, sur l'algorithme du sac à dos.

    Pour optimiser le traitement, je pense utiliser un arbre n-aire mais j'ai beaucoup de mal à le générer par récursivité.

    Par exemple, à partir de cette liste :
    ( x y z )

    J'aimerais générer (l'ordre n'est pas important) :
    ( ( x y z ) ( x z ) ( y z ) ( z ) )

    Je pense utiliser les fonctions ajout_en_tete, reste(liste), tete(liste),

    Bien sûr cette fonction doit être extensible à n termes :
    ( a b c d )

    donne la séquence :
    ( ( a b c d ) (a b d) (a c d ) ( c d ) ( b c d ) ( b d ) ( c d ) ( d ) )

    Merci d'avance pour votre aide

  2. #2
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Points : 6 498
    Points
    6 498
    Par défaut
    Je n'ai pas bien compris le principe de construction
    Le second ne serait pas
    ( ( a b c d ) (a b d) (a c d ) ( b c d ) (a d) ( b d ) ( c d ) ( d ) )
    par hasard ?
    Si c'est ça voilà un code en Scheme
    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
    ;; pour chaque element de l on garde l'element et on ajoute en tête x
    (define (sac-a-dos l)
      (let* ((ll (reverse l))
             (tete (list(list (car ll))))
             (reste (cdr ll)))
        (let foo1 ((x reste) (y tete))
          (cond ((null? x) y)
                (else (foo1 (cdr x) 
                            (let foo2 ((xx (car x)) (yy y))
                              (cond ((null? yy) yy)
                                    (else (append (list (cons xx (car yy)) (car yy)) (foo2 xx (cdr yy))))))))))))
     
     
     
     
     
    (sac-a-dos '(a b c d))
     
    (sac-a-dos '(1 2 3))
    Sortie
    ((a b c d) (b c d) (a c d) (c d) (a b d) (b d) (a d) (d))
    ((1 2 3) (2 3) (1 3) (3))
    "La haine seule fait des choix" - Koan Zen
    "Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
    "Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
    Faites du Prolog, ça vous changera les idées !
    Ma page Prolog
    Mes codes sources commentés

    Mon avatar : La Madeleine à la veilleuse de Georges de La Tour

  3. #3
    Membre régulier
    Inscrit en
    Décembre 2005
    Messages
    271
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 271
    Points : 91
    Points
    91
    Par défaut
    Merci ! Oui je me suis trompe ... mais je en comprends rien a ce que tu as fait

  4. #4
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Points : 6 498
    Points
    6 498
    Par défaut
    Le principe est de créer une liste avec le dernier élément d.
    Puis pour chaque élément restant, je parcours la liste créée au tour précédent, pour chaque membre de cette liste, j'ajoute dans la nouvelle liste, ce membre et le membre augmenté de l'élément à ajouter en cours

    ce qui donne pour la liste (a b c d)

    init : ((d))
    tour 1 : ((c d ) (d))
    tour 2 : ((b c d) (c d) (b d) (d))
    tour 3 : ((a b c d) (b c d) (a c d) (c d) (a b d) (b d) (a d) (d))

    Ce qui donne dans le détail du code
    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
    ;; pour chaque element de l on garde l'element et on ajoute en tête x
    (define (sac-a-dos l)
      ;; j'ai besoin de la liste à l'envers
      ;; le let* permet en Scheme d'utiliser le résultat de "l'affectation précédent"
      ;; je mets des " car je ne connais pas le terme Scheme
      (let* ((ll (reverse l))
             ;; je crée le premier élément de l'init ((d))
             (tete (list(list (car ll))))
             ;; le reste est donc (c b a)
             (reste (cdr ll)))
        ;; création de la première fonction interne récursive
        ;; elle permet d'ajouter chaque élément à la liste
       ;; d'abord c puis b puis a
       ;; les arguments d'appel sont initialisés avec tete et reste
       ;; précédemment créés
        (let foo1 ((x reste) (y tete))
           ;; si tete est vide, on a fini, on renvoie la liste y
          (cond ((null? x) y)
                ;; sinon on rappelle foo1 avec comme premier argument
                ;; le reste de x (cdr x) et   comme second argument
                ;; la liste construite a partir de y et de (car x)
                (else (foo1 (cdr x) 
                            ;; appel de la fonction interne foo2
                            ;; qui construit récursivement la nouvelle liste en ajoutant
                            ;;  un membre de la liste et ce membre augmenté de xx
                            (let foo2 ((xx (car x)) (yy y))
                                ;; si la liste yy est vide c'est fini, on renvoie yy 
                              (cond ((null? yy) yy)
                                ;; sinon on construit la liste en ajoutant les deux nouveaux éléments crés à partir du premier élément de yy
                                ;; à la liste qui sera crée à partir des éléments restant de yy
                                    (else (append (list (cons xx (car yy)) (car yy)) (foo2 xx (cdr yy))))))))))))
    J'espère que tu as compris, ce n'est pas très simple à expliquer, tu peux essayer de faire ceci en utilisant des fonctions externes foo1 et foo2 au lieu d'être internes à sac-a-dos.
    "La haine seule fait des choix" - Koan Zen
    "Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
    "Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
    Faites du Prolog, ça vous changera les idées !
    Ma page Prolog
    Mes codes sources commentés

    Mon avatar : La Madeleine à la veilleuse de Georges de La Tour

  5. #5
    Membre régulier
    Inscrit en
    Décembre 2005
    Messages
    271
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 271
    Points : 91
    Points
    91
    Par défaut
    Je me renseigne sur le Scheme pour comprendre ton programme , je suis sous emacs lisp...

    J ai teste tt ca avecv drscheme , ca marche aussi pour une liste de 5 atom
    Vraiment bravo ! Car ss savoir quelle logique je suivais, tu as trouve le bon algo, impressionnant !

    Est ce que tu peux m explqiuer quelle methode/raisonnement tu as utilisé ?

  6. #6
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Points : 6 498
    Points
    6 498
    Par défaut
    Ben, c'est en regardant les deux exemples que tu as fournis que j'en ai déduit ce que tu recherchais (je n'étais d'ailleurs pas trop sûr puisque tu avais fait une erreur).
    Après il suffit d'avoir une idée comment le faire à la main, (en ce moment il y a beaucoup de questions de ce genre sur les listes), connaître un peu le principe de fonctionnement de Lisp / Scheme et ça roule.
    "La haine seule fait des choix" - Koan Zen
    "Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
    "Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
    Faites du Prolog, ça vous changera les idées !
    Ma page Prolog
    Mes codes sources commentés

    Mon avatar : La Madeleine à la veilleuse de Georges de La Tour

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

Discussions similaires

  1. Représentation arbre n-aire en C++ et construction de l'arbre pendant l'algo MiniMax
    Par Cornellus1985 dans le forum Intelligence artificielle
    Réponses: 1
    Dernier message: 28/11/2010, 00h39
  2. Construction d'un arbre n-aire à partir de listes
    Par xino972 dans le forum Algorithmes et structures de données
    Réponses: 1
    Dernier message: 08/07/2008, 09h58
  3. [debutant] parcours en profondeur arbre n-aire
    Par tx dans le forum Langage
    Réponses: 1
    Dernier message: 15/02/2006, 03h56
  4. construire un arbre n-aire
    Par emidelphi77 dans le forum Langage
    Réponses: 2
    Dernier message: 11/10/2005, 18h47
  5. arbre n-aire delete
    Par Fry dans le forum C++
    Réponses: 13
    Dernier message: 19/10/2004, 21h22

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