Disons que j'ai une liste de n éléments, je sais qu'il y en a n! moyens possibles de commander ces éléments. Qu'est-ce qu'un algorithme pour générer tous les ordres possibles de cette liste? Exemple, j'ai la liste [a, b, c]. L'algorithme renverrait [[a, b, c], [a, c, b,], [b, a, c], [b, c, a], [c, a, b], [c, b , une]].
Je lis ceci ici http://en.wikipedia.org/wiki/Permutation#Algorithms_to_generate_permutations
Mais Wikipédia n'a jamais été bon pour expliquer. Je n'y comprends pas grand-chose.
Réponses:
En gros, pour chaque élément de gauche à droite, toutes les permutations des éléments restants sont générées (et chacune est ajoutée avec les éléments courants). Cela peut être fait de manière récursive (ou itérative si vous aimez la douleur) jusqu'à ce que le dernier élément soit atteint, auquel point il n'y a qu'un seul ordre possible.
Donc avec la liste [1,2,3,4] toutes les permutations qui commencent par 1 sont générées, puis toutes les permutations qui commencent par 2, puis 3 puis 4.
Cela réduit efficacement le problème de la recherche de permutations d'une liste de quatre éléments à une liste de trois éléments. Après avoir réduit à 2 puis 1 listes d'éléments, toutes seront trouvées.
Exemple montrant des permutations de processus utilisant 3 boules colorées:
(à partir de https://en.wikipedia.org/wiki/Permutation#/media/File:Permutations_RGB.svg - https://commons.wikimedia.org/wiki/File:Permutations_RGB. svg )
la source
Voici un algorithme en Python qui fonctionne en place sur un tableau:
Vous pouvez essayer le code par vous-même ici: http://repl.it/J9v
la source
Il y a déjà beaucoup de bonnes solutions ici, mais je voudrais partager comment j'ai résolu ce problème par moi-même et j'espère que cela pourrait être utile pour quelqu'un qui voudrait également trouver sa propre solution.
Après avoir réfléchi au problème, je suis arrivé à deux conclusions suivantes:
L
de taille,n
il y aura un nombre égal de solutions commençant par L 1 , L 2 ... L n éléments de la liste. Comme au total il y a desn!
permutations de la liste de taillen
, nous obtenons desn! / n = (n-1)!
permutations dans chaque groupe.[a,b]
et[b,a]
.En utilisant ces deux idées simples, j'ai dérivé l'algorithme suivant:
Voici comment j'ai implémenté cela en C #:
la source
La réponse de Wikipedia à «l'ordre lexicographique» me semble parfaitement explicite dans le style des livres de cuisine. Il cite une origine du 14ème siècle pour l'algorithme!
Je viens d'écrire une implémentation rapide en Java de l'algorithme de Wikipédia comme vérification et ce n'était pas un problème. Mais ce que vous avez dans votre Q comme exemple n'est PAS "lister toutes les permutations", mais "une LISTE de toutes les permutations", donc wikipedia ne vous sera pas d'une grande aide. Vous avez besoin d'un langage dans lequel les listes de permutations sont construites de manière réalisable. Et croyez-moi, les listes de quelques milliards de dollars ne sont généralement pas traitées dans des langages impératifs. Vous voulez vraiment un langage de programmation fonctionnel non strict, dans lequel les listes sont un objet de première classe, pour sortir des choses sans amener la machine près de la mort thermique de l'Univers.
C'est facile. En Haskell standard ou dans tout autre langage FP moderne:
et
la source
Comme WhirlWind l'a dit, vous commencez par le début.
Vous échangez le curseur avec chaque valeur restante, y compris le curseur lui-même, ce sont toutes de nouvelles instances (j'ai utilisé un
int[]
etarray.clone()
dans l'exemple).Ensuite, effectuez des permutations sur toutes ces différentes listes, en vous assurant que le curseur est à droite.
Lorsqu'il n'y a plus de valeurs restantes (le curseur est à la fin), imprimez la liste. C'est la condition d'arrêt.
la source
Récursif demande toujours un effort mental à maintenir. Et pour les grands nombres, le factoriel est facilement énorme et le débordement de pile sera facilement un problème.
Pour les petits nombres (3 ou 4, ce qui est le plus souvent rencontré), les boucles multiples sont assez simples et directes. Il est regrettable que les réponses avec des boucles n'aient pas été votées.
Commençons par l'énumération (plutôt que la permutation). Lisez simplement le code sous forme de pseudo code Perl.
L'énumération est plus souvent rencontrée que la permutation, mais si une permutation est nécessaire, ajoutez simplement les conditions:
Maintenant, si vous avez vraiment besoin d'une méthode générale potentiellement pour de grandes listes, nous pouvons utiliser la méthode radix. Tout d'abord, considérons le problème d'énumération:
L'incrément de Radix est essentiellement le comptage des nombres (dans la base du nombre d'éléments de liste).
Maintenant, si vous avez besoin de permutation, ajoutez simplement les vérifications à l'intérieur de la boucle:
Edit: Le code ci-dessus devrait fonctionner, mais pour la permutation, radix_increment pourrait être un gaspillage. Donc, si le temps est une préoccupation pratique, nous devons changer radix_increment en permute_inc:
Bien sûr maintenant ce code est logiquement plus complexe, je vais partir à l'exercice du lecteur.
la source
Référence: Geeksforgeeks.org
la source
Si quelqu'un se demande comment faire en permutation en javascript.
Idée / pseudocode
par exemple. 'a' + permute (bc). permute de bc serait bc & cb. Maintenant, ajoutez ces deux qui donneront abc, acb. de même, choisissez b + permute (ac) fournira bac, bca ... et continuez.
regarde maintenant le code
Prenez votre temps pour comprendre cela. J'ai obtenu ce code de ( pertumation en JavaScript )
la source
Un autre en Python, il n'est pas en place comme celui de @ cdiggins, mais je pense que c'est plus facile à comprendre
la source
Je pensais écrire un code pour obtenir les permutations de tout entier donné de n'importe quelle taille, c'est-à-dire en fournissant un nombre 4567, nous obtenons toutes les permutations possibles jusqu'à 7654 ... J'ai donc travaillé dessus et trouvé un algorithme et finalement mis en œuvre, ici est le code écrit en "c". Vous pouvez simplement le copier et l'exécuter sur n'importe quel compilateur open source. Mais certaines failles attendent d'être déboguées. Veuillez apprécier.
Code:
la source
J'ai créé celui-ci. basé sur des recherches trop permutées (qwe, 0, qwe.length-1); Juste pour que vous le sachiez, vous pouvez le faire avec ou sans retour en arrière
la source
Voici une méthode de jouet Ruby qui fonctionne comme
#permutation.to_a
ça pourrait être plus lisible pour les fous. C'est hella lent, mais aussi 5 lignes.la source
J'ai écrit cette solution récursive en ANSI C. Chaque exécution de la fonction Permutate fournit une permutation différente jusqu'à ce que tout soit terminé. Les variables globales peuvent également être utilisées pour les variables fact et count.
la source
Version Java
Par exemple
production:
la source
en PHP
la source
Voici le code en Python pour imprimer toutes les permutations possibles d'une liste:
J'ai utilisé un algorithme d'ordre lexicographique pour obtenir toutes les permutations possibles, mais un algorithme récursif est plus efficace. Vous pouvez trouver le code de l'algorithme récursif ici: Permutations de récursivité Python
la source
la source
Dans Scala
la source
ceci est une version java pour la permutation
la source
Voici une implémentation pour ColdFusion (nécessite CF10 en raison de l'argument de fusion de ArrayAppend ()):
Basé sur la solution js de KhanSharp ci-dessus.
la source
Je sais que c'est un très très ancien et même hors sujet dans le stackoverflow d'aujourd'hui, mais je voulais toujours apporter une réponse javascript amicale pour la simple raison qu'elle s'exécute dans votre navigateur.
J'ai également ajouté le
debugger
point d'arrêt de la directive afin que vous puissiez parcourir le code (chrome requis) pour voir comment cet algorithme fonctionne. Ouvrez votre console de développement dans Chrome (F12
sous Windows ouCMD + OPTION + I
sur Mac), puis cliquez sur "Exécuter l'extrait de code". Cela implémente le même algorithme exact que @WhirlWind a présenté dans sa réponse.Votre navigateur doit interrompre l'exécution au niveau de la
debugger
directive. UtilisationF8
pour continuer l'exécution du code.Parcourez le code et voyez comment cela fonctionne!
la source
Dans la solution Java suivante, nous tirons parti du fait que les chaînes sont immuables afin d'éviter de cloner le jeu de résultats à chaque itération.
L'entrée sera une chaîne, disons "abc", et la sortie sera toutes les permutations possibles:
Code:
La même approche peut être appliquée aux tableaux (au lieu d'une chaîne):
la source
C'est ma solution sur Java:
la source
Vous ne pouvez pas vraiment parler de résolution d'un problème de permultation en récursivité sans publier une implémentation dans un (dialecte de) langage qui a lancé l'idée . Donc, par souci d'exhaustivité, voici l'une des méthodes qui peuvent être faites dans Scheme.
en appelant
(permof (list "foo" "bar" "baz"))
nous aurons:Je n'entrerai pas dans les détails de l'algorithme car cela a été suffisamment expliqué dans d'autres articles. L'idée est la même.
Cependant, les problèmes récursifs ont tendance à être beaucoup plus difficiles à modéliser et à réfléchir dans un milieu destructeur comme Python, C et Java, alors qu'en Lisp ou ML, ils peuvent être exprimés de manière concise.
la source
Voici une solution récursive en PHP. Le message de WhirlWind décrit avec précision la logique. Il convient de mentionner que la génération de toutes les permutations s'exécute en temps factoriel, il peut donc être judicieux d'utiliser une approche itérative à la place.
La fonction strDiff prend deux chaînes,
s1
ets2
, et retourne une nouvelle chaîne avec tout ce qui ests1
sans éléments danss2
(les doublons comptent). Donc,strDiff('finish','i')
=>'fnish'
(le deuxième «i» n'est pas supprimé).la source
Voici un algorithme en R, au cas où quelqu'un aurait besoin d'éviter de charger des bibliothèques supplémentaires comme je devais le faire.
Exemple d'utilisation:
la source
la source
Il s'agit d'un code récursif pour java, l'idée est d'avoir un préfixe qui ajoute le reste des caractères:
Exemple:
Entrée = "ABC"; Production:
ABC ACB BAC BCA CAB CBA
la source
str
lors d'un appel récursif, sinon il ne se terminera pas.Juste pour être complet, C ++
...
la source
Voici une solution non récursive en C ++ qui fournit la permutation suivante dans l'ordre croissant, de la même manière que la fonctionnalité fournie par std :: next_permutation:
la source