Comptabiliser des permutations en C++
Résolu/Fermé
kjones
Messages postés
4
Date d'inscription
dimanche 3 juin 2007
Statut
Membre
Dernière intervention
5 juin 2007
-
4 juin 2007 à 18:15
mamiemando Messages postés 33407 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 29 novembre 2024 - 22 oct. 2008 à 12:06
mamiemando Messages postés 33407 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 29 novembre 2024 - 22 oct. 2008 à 12:06
3 réponses
mamiemando
Messages postés
33407
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
29 novembre 2024
7 806
5 juin 2007 à 01:40
5 juin 2007 à 01:40
La manière la plus simple de programmer ça c'est d'écrire un appel récursif qui va parcourir l'arbre de recherche correspondant à l'ensemble des permutations. L'appel récursif doit passer à ses fils
- la profondeur à laquelle il est rendu (par exemple 3 si j'ai déjà tiré les trois premiers chiffres)
- la profondeur max (par exemple 8 dans le cas des 8 chiffres)
- les chiffres tirés jusqu'ici (par exemple stocké dans un std::vector<short>)
Dans le cas ou les permutations doivent vérifier certaines propriétés, il est possible de définir des coupes qui éviteront de poursuivre l'appel récursif vers des feuilles qui ne serviront de toute façon à rien.
Je ne suis pas sûre d'avoir compris ce que tu comptais mais si ce sont tous les nombres de K chiffres, où chaque chiffre est distinct et prend une valeur comprise entre 0 et 9 ça donne ce genre de chose (ici K=3)
Ce qui donne
Tu as donc bien toutes les permutations de taille 3 d'un ensemble à 10 éléments (valeurs de 0 à 9). C'est ce que tu voulais ?
Bonne chance
- la profondeur à laquelle il est rendu (par exemple 3 si j'ai déjà tiré les trois premiers chiffres)
- la profondeur max (par exemple 8 dans le cas des 8 chiffres)
- les chiffres tirés jusqu'ici (par exemple stocké dans un std::vector<short>)
Dans le cas ou les permutations doivent vérifier certaines propriétés, il est possible de définir des coupes qui éviteront de poursuivre l'appel récursif vers des feuilles qui ne serviront de toute façon à rien.
Je ne suis pas sûre d'avoir compris ce que tu comptais mais si ce sont tous les nombres de K chiffres, où chaque chiffre est distinct et prend une valeur comprise entre 0 et 9 ça donne ce genre de chose (ici K=3)
#include <vector> #include <iostream> #include <cassert> void f( unsigned prof, // la profondeur courante (nombre de chiffre choisis) const unsigned & prof_max, // la profondeur max (nombre de chiffre à choisir) std::vector<short> perm, // la permutation courante std::vector<bool> marked, // les nombres utilisés unsigned & compteur // le nombre de permutations rencontrées ){ if (prof < prof_max){ for(unsigned i=0;i<=9;++i){ if (marked[i]) continue; std::vector<short> perm_suivant = perm; perm_suivant.push_back(i); std::vector<bool> marked_suivant = marked; marked_suivant[i] = true; f(prof+1,prof_max,perm_suivant,marked_suivant,compteur); } }else{ // le nombre a la taille voulue for(unsigned i=0;i<perm.size();++i) std::cout << perm[i]; std::cout << std::endl; ++compteur; } } void perm(const unsigned & prof_max){ assert(prof_max<=10); std::vector<short> perm0; std::vector<bool> marked0(10,false); unsigned compteur = 0; // partagé par tous les appels recursifs f(0,prof_max,perm0,marked0,compteur); std::cout << "compteur = " << compteur << std::endl; } int main(){ perm(3); return 0; }
Ce qui donne
(mando@aldur) (~) $ ./a.out 012 013 014 015 016 017 018 019 021 023 024 025 ... 975 976 978 980 981 982 983 984 985 986 987 compteur = 720
Tu as donc bien toutes les permutations de taille 3 d'un ensemble à 10 éléments (valeurs de 0 à 9). C'est ce que tu voulais ?
Bonne chance
mamiemando
Messages postés
33407
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
29 novembre 2024
7 806
21 oct. 2008 à 19:52
21 oct. 2008 à 19:52
Oui mais ouvre un nouveau sujet en faisant référence à celui-ci pour maintenir la clarté de ce fil de discussion.
mslider
Messages postés
109
Date d'inscription
jeudi 21 octobre 2004
Statut
Membre
Dernière intervention
7 mars 2010
21 oct. 2008 à 20:54
21 oct. 2008 à 20:54
je viens de le faire, voir le sujet "Permutations avec répétitions en C++"
mamiemando
Messages postés
33407
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
29 novembre 2024
7 806
22 oct. 2008 à 12:06
22 oct. 2008 à 12:06
Parfait je vais y jeter un oeil tout à l'heure
5 juin 2007 à 09:17
En fait ça marche bien! Merci!
Kjones
21 oct. 2008 à 17:28
je voudrais m'inspirer de ton programme qui est très rapide pour essayer de faire une liste
de permutations avec répetitions.
Je m'explique:
étant donnés un nombre n et un alphabet Z constitué seulement de 4 lettres tel que Z= {A,T,G,C},
produire toutes les chaines de caractères de longueur n=10 pris parmis l'alphabet Z.
Un exemple avec Z = {A, C} et n = 3 nous donnerait un total de 9 motifs:
aaa
aac
aca
caa
acc
cac
cca
ccc
Pour augmenter la rapidité du code on pourrait aussi assigner à chaque lettre A,T,G,C une valeur binaire:
00,01,10,11.
Puis ensuite refaire la reconversion en lettres après les boucles de traitement.
On a alors 2^(2n) motifs en binaire et 4^n motifs en lettres après conversion.
Tu peux m'aider STP ?