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

Algorithmes et structures de données Discussion :

générer toutes les permutations d'un ensemble fini d'éléments


Sujet :

Algorithmes et structures de données

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    144
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 144
    Points : 54
    Points
    54
    Par défaut générer toutes les permutations d'un ensemble fini d'éléments
    bonjour,
    je cherche à faire une fonction qui genere tous les mots possibles
    de 10 lettres en majuscule.
    Petit problème, je n'arrive pas à trouver la ou les boucles pour generer ces mots...

  2. #2
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut générer toutes les permutations d'un ensemble fini d'éléments
    L'énoncé générique du problème est de trouver comment générer toutes les permutations d'un ensemble fini d'éléments. Un fois l'algo posé sur papier, l'implantation en langage C devrait être aisée.

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    144
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 144
    Points : 54
    Points
    54
    Par défaut
    effectivement c'est bien ça le probleme

  4. #4
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  5. #5
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Points : 9 818
    Points
    9 818
    Par défaut
    Peut être devrais tu jetter un oeil à :

    Generating all permutations: http://www-cs-faculty.stanford.edu/~knuth/fasc2b.ps.gz
    Je ne répondrai à aucune question technique en privé

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    144
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 144
    Points : 54
    Points
    54
    Par défaut
    merci pour les liens je pense que je vais bien me prendre la tete lol

  7. #7
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    Voici une idée naïve d'algorithme. Si tu n'a pas de répétition de lettre et que tu désires générer toutes les permutations possibles:
    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
    procedure PERMUTATIONS(chaine: chaine de caractères)
        tampon: chaine de caractères de longueur longueur(chaine)
        a <- 0
        b <- 1
        c <- 2
     
        tant que a < longeur(chaine) alors
            j <- 0
            echanger(0, a)
            tampon[j] <- chaine[0];
            incrémenter(a)
            incrémenter(j)
     
            tant que b < longueur(chaine) alors
                echanger(1, b)
                tampon[j] <- chaine[1];
                incrémenter(b)
                incrémenter(j)
     
                tant que c < longueur(chaine) alors
                    echanger(2, c)
                    tampon[j] <- chaine[2];
                    incrémenter(c)
                    incrémenter(j);
                    ecrire_dans_fichier(tampon)
                ftant
            ftant
        ftant
    fprocedure
    Pour un mot de 10 lettres, tu obtiendras 10! = 3'628'800 permutations. Si tu as des répétitions de lettre, soit tu génères les doublons et tu les élimines par la suite, soit tu trouve un algo qui te permette de ne pas générer de doublon.

    Je n'ai pas passé tellement de temps à vérifier la validité de l'algo...

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    144
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 144
    Points : 54
    Points
    54
    Par défaut
    C'est exactement ce que j'ai dit à mon chargé de tp et il a rigolé en me disant me donnerait une solution, j'ai hate de voir!
    je donnerai la soluce

  9. #9
    Membre averti

    Profil pro
    Étudiant
    Inscrit en
    Décembre 2004
    Messages
    499
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2004
    Messages : 499
    Points : 422
    Points
    422
    Par défaut
    salut

    ton ennoncé c'était pour générer tous les mots en majuscule et pas pour générer les permutations ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    char mot[11] = "AAAAAAAAAA";
    char *ptr = mot + 10;
    while(1) {
      printf("%s\n",mot);
      char *ptr2 = ptr;
      while (*ptr2 == 'Z') {
        if (ptr2 == mot) goto fin;
        *ptr2-- = 'A';
      }
      (*ptr2)++;
    }
    fin:;

  10. #10
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 942
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 942
    Points : 5 654
    Points
    5 654
    Par défaut
    Koi,
    Citation Envoyé par Thierry Chappuis Voir le message
    C'est pas comme ça que je voyais le problème. J'avais compris que l'ensemble des 10 lettres de départ était déjà défini... Ca réguit considérablement la taille du problème.

    Thierry
    C'est bien comme ça que je prends le problème aussi, exercice tellement classique qu'on a dû le voir quelques centaines de fois, voire plus.

    D'ailleurs,
    Citation Envoyé par Thierry Chappuis
    L'énoncé générique du problème est de trouver comment générer toutes les permutations d'un ensemble fini d'éléments. Un fois l'algo posé sur papier, l'implantation en langage C devrait être aisée.
    et
    Citation Envoyé par Didier77
    effectivement c'est bien ça le probleme
    Si les cons volaient, il ferait nuit à midi.

  11. #11
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 603
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par acx01b Voir le message
    salut

    ton ennoncé c'était pour générer tous les mots en majuscule et pas pour générer les permutations ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    char mot[11] = "AAAAAAAAAA";
    char *ptr = mot + 10;
    while(1) {
      printf("%s\n",mot);
      char *ptr2 = ptr;
      while (*ptr2 == 'Z') {
        if (ptr2 == mot) goto fin;
        *ptr2-- = 'A';
      }
      (*ptr2)++;
    }
    fin:;
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  12. #12
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Points : 9 818
    Points
    9 818
    Par défaut
    Aaah, désolé, il y avait eu une discussion dans le forum Algo sur la génération de permutation et une autre dans le langage C, j'avais cru que c'était également sur les permutations, donc pour que tout le monde puisse écrire dans un seul sujet, j'ai tout mis dans algo.
    Mais la génération de tous les mots de lettre en majuscule, c'est un problème de combinaison, dont la solution est donnée par le lien de Jean-Marc.

    Il y a également un autre poste ici : http://www.developpez.net/forums/sho...d.php?t=228599
    Je ne répondrai à aucune question technique en privé

  13. #13
    alex_pi
    Invité(e)
    Par défaut
    Citation Envoyé par Didier77 Voir le message
    bonjour,
    je cherche à faire une fonction qui genere tous les mots possibles
    de 10 lettres en majuscule.
    Petit problème, je n'arrive pas à trouver la ou les boucles pour generer ces mots...
    J'espère qu'il ne te faut pas les stocker, parequ'il te faudrait quand même 1553 tera-octet :-) (en les séparants par un retour chariot)

    Citation Envoyé par acx01b Voir le message
    salut

    ton ennoncé c'était pour générer tous les mots en majuscule et pas pour générer les permutations ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    char mot[11] = "AAAAAAAAAA";
    char *ptr = mot + 10;
    while(1) {
      printf("%s\n",mot);
      char *ptr2 = ptr;
      while (*ptr2 == 'Z') {
        if (ptr2 == mot) goto fin;
        *ptr2-- = 'A';
      }
      (*ptr2)++;
    }
    fin:;
    Tiens, pour rigoler, et puisqu'on est dans la rubrique algorithimique (et non "concours du programme C le plus crade"), tu pourrais
    1. Nous dire ce que fait ton programme
    2. le prouver

    Ca te donnera peut être envie d'apprendre à programmer proprement :-D
    Dernière modification par PRomu@ld ; 25/09/2007 à 07h46. Motif: Fusion

  14. #14
    Membre averti

    Profil pro
    Étudiant
    Inscrit en
    Décembre 2004
    Messages
    499
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2004
    Messages : 499
    Points : 422
    Points
    422
    Par défaut
    salut

    je ne trouve pas ces lignes crades ^^
    tous les algorithmes d'énumérations combinatoires sont par définitions crades
    celui ci est probablement l'un des plus simples ?

    il génére tous les mots en majuscules:

    on démarre avec le tableau AAAAAAAAAA

    à chaque itération on se place sur la dernière lettre:
    - on affiche le tableau
    - tant qu'on a un Z on met A à la place et se place sur la lettre juste avant
    - une fois qu'on est sur une case qui ne contient pas Z on l'incrémente
    - le test d'arret c'est si toutes les cases sont à Z

    ainsi on a énuméré tous les mots majuscules de 10 lettres

    la preuve c'est que c'est le même principe qui permet de compter avec les nombres décimaux (passage de 98 à 99 puis de 99 à 100...) appris en primaire

  15. #15
    alex_pi
    Invité(e)
    Par défaut
    Citation Envoyé par acx01b Voir le message
    salut

    je ne trouve pas ces lignes crades ^^
    Moi si :-) Déjà, un goto... Mais au fait, avant de "le démontrer", vu que c'est un exemple trivial, tu aurais pu l'exécuter nan ? Tu te serais par exemple apperçu que ton "+ 10" était faux et aurait du être un "+9", parce que là, tu effaces joyeusement le \000 final, et le printf imprime des octet jusqu'à en trouver un autre (sur le code produit par mon gcc, c'est une 20aine d'octets plus loin, on a de la chance)

    Citation Envoyé par acx01b Voir le message
    tous les algorithmes d'énumérations combinatoires sont par définitions crades
    celui ci est probablement l'un des plus simples ?
    C'est l'un des plus simple, et tu arrives à le rendre totalement illisible


    Citation Envoyé par acx01b Voir le message
    il génére tous les mots en majuscules:

    on démarre avec le tableau AAAAAAAAAA

    à chaque itération on se place sur la dernière lettre:
    - on affiche le tableau
    - tant qu'on a un Z on met A à la place et se place sur la lettre juste avant
    - une fois qu'on est sur une case qui ne contient pas Z on l'incrémente
    - le test d'arret c'est si toutes les cases sont à Z

    ainsi on a énuméré tous les mots majuscules de 10 lettres

    la preuve c'est que c'est le même principe qui permet de compter avec les nombres décimaux (passage de 98 à 99 puis de 99 à 100...) appris en primaire
    J'espère que tu es conscient de ne *rien* prouver ?

    Prenons une autre version 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
     
    (* module pour permetre l'impression sur la sortie standard *)
    open Printf
     
    (* longueur de la chaine dont on veut produire l'ensemble des permutations *)
    let l = 4
     
    (* enum_n_premier prend une chaine s en entrée et énumère toutes les
       chaines obtenues avec toutes les permutations de ses n + 1 premiers
       caractères. L'écriture est en style impératif pour être plus
       lisible par le formum "algorithmique". L'appel à n = -1 déclanche
       l'impression
    *)
    let rec enum_n_premier s n =
      if n < 0 then printf "%s\n" s else
        for i = (int_of_char 'A') to (int_of_char 'Z') do
          s.[n] <- char_of_int i;
          enum_n_premier s (n - 1);
        done
     
    (* création de la chaine, et appelle de la fonction d'énumération sur la 
        longeur de la chaine *)
    let _ =
      let s = String.make l 'A' in
        enum_n_premier s (l - 1)
    On montre ici facilement que pour n = 0, enum_n_premier s n énumère bien l'ensemble des chaine à 1 caractère variant de A à Z. Puis par récurence, si pour un n fixé, enum_n_premier s (n -1) énumère l'ensemble des chaines à n caractères variants entre A et Z, enum_n_premier s n énumère l'ensemble des chaines à n + 1 caractère, en faisant varier le n + 1 eme caractère de A à Z et en énumérant à chaque fois toutes les chaines possibles.

    On obtient donc ce que l'on veut, bien plus proprement, de façons lisible, et au final aussi concise.

  16. #16
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Suis-je le seul a ne pas voir de differences fondamentales entre les programmes d'Alex et d'acx01b? Enlever la recursion du programme d'Alex (elle n'est pas terminale mais expliciter la pile puis remarquer qu'il y a un lien arithmetique entre le pointeur et les valeurs contenues fait a priori l'affaire) doit donner quelque chose de tres proche de ce que propose acx01b.

    Une autre maniere de voir le rapport -- vraissemblablement plus proche du raisonnement par lequel acx01 a optenu directement le resultat --, c'est d'effectuer une operation de renversement de controle semblable a ce qu'on fait quand on implemente un algo de parcours sous forme d'iterateur ou de generateur.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  17. #17
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Et bien puisqu'on parle d'impératif et de fonctionnel, voici une solution à l'aspect plus fonctionnel en Haskell :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    import Control.Monad
     
    main = putStr $ unlines $ replicateM 10 ['A'..'Z']
    Qui utilise la fonction replicateM pour effectuer 10 fois de suite un choix dans ['A'..'Z'] (la liste des majuscules) de toutes les façons possibles (en utilisant en fait la monade des listes).

    --
    Jedaï

  18. #18
    Expert éminent
    Avatar de PRomu@ld
    Homme Profil pro
    Ingénieur de Recherche
    Inscrit en
    Avril 2005
    Messages
    4 155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Ingénieur de Recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 4 155
    Points : 6 486
    Points
    6 486
    Par défaut
    J'aimerai rappeler que la discussion originale est la recherche d'un algorithme pour générer des permutations. Par conséquent, si vous souhaitez discuter du bienfait de tel ou tel langage, cela n'a pas sa place ici.

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

Discussions similaires

  1. Générer toutes les IP d'un sous-réseau
    Par valarko dans le forum Débuter avec Java
    Réponses: 4
    Dernier message: 13/11/2011, 00h23
  2. Procéder toutes les permutations possibles d'une liste
    Par supergrey dans le forum Mathématiques
    Réponses: 3
    Dernier message: 21/10/2011, 15h08
  3. générer toutes les dates d'une année
    Par docky dans le forum Langage SQL
    Réponses: 7
    Dernier message: 02/07/2008, 16h45
  4. Générer toutes les combinaisons d'une suite
    Par man_coef dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 28/04/2008, 18h56
  5. Réponses: 16
    Dernier message: 20/10/2006, 16h31

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