Digamos que eu tenha uma lista de n elementos, eu sei que existem n! maneiras possíveis de solicitar esses elementos. O que é um algoritmo para gerar todos os pedidos possíveis desta lista? Exemplo, eu tenho a lista [a, b, c]. O algoritmo retornaria [[a, b, c], [a, c, b,], [b, a, c], [b, c, a], [c, a, b], [c, b , uma]].
Estou lendo isso aqui http://en.wikipedia.org/wiki/Permutation#Algorithms_to_generate_permutations
Mas a Wikipedia nunca foi boa em explicar. Eu não entendo muito disso.
algorithm
list
permutation
fent
fonte
fonte
Respostas:
Basicamente, para cada item da esquerda para a direita, todas as permutações dos itens restantes são geradas (e cada uma é adicionada com os elementos atuais). Isso pode ser feito recursivamente (ou iterativamente, se você gosta de dor) até que o último item seja atingido, momento em que existe apenas um pedido possível.
Portanto, com a lista [1,2,3,4], todas as permutações que começam com 1 são geradas, depois todas as permutações que começam com 2, depois 3 e 4.
Isso reduz efetivamente o problema de encontrar permutações de uma lista de quatro itens para uma lista de três itens. Após reduzir para 2 e, em seguida, 1 lista de itens, todos eles serão encontrados.
Exemplo mostrando permutações de processo usando três esferas coloridas:
(de https://en.wikipedia.org/wiki/Permutation#/media/File:Permutations_RGB.svg - https://commons.wikimedia.org/wiki/File:Permutations_RGB. svg )
fonte
Aqui está um algoritmo em Python que funciona no local em uma matriz:
Você pode experimentar o código por si mesmo aqui: http://repl.it/J9v
fonte
Já existem muitas soluções boas aqui, mas eu gostaria de compartilhar como resolvi esse problema sozinho e espero que isso possa ser útil para alguém que também gostaria de obter sua própria solução.
Depois de refletir sobre o problema, cheguei a duas conclusões a seguir:
L
de tamanhon
, haverá um número igual de soluções começando com L 1 , L 2 ... L n da lista. Como no total existemn!
permutações da lista de tamanhon
, obtemosn! / n = (n-1)!
permutações em cada grupo.[a,b]
e[b,a]
.Usando essas duas idéias simples, derivamos o seguinte algoritmo:
Aqui está como eu implementei isso em c #:
fonte
A resposta da Wikipedia para "ordem lexicográfica" parece perfeitamente explícita no estilo de um livro de receitas para mim. Ele cita uma origem do século XIV para o algoritmo!
Acabei de escrever uma rápida implementação em Java do algoritmo da Wikipedia como uma verificação e não foi problema. Mas o que você tem no seu Q como exemplo NÃO é "listar todas as permutações", mas "uma LISTA de todas as permutações", portanto, a Wikipedia não será de grande ajuda para você. Você precisa de um idioma no qual as listas de permutações sejam construídas de maneira viável. E acredite, listas de alguns bilhões de comprimento geralmente não são tratadas em idiomas imperativos. Você realmente deseja que uma linguagem de programação funcional não estrita, na qual as listas sejam um objeto de primeira classe, apareça, sem aproximar a máquina da morte por calor do Universo.
Isso é fácil. No Haskell padrão ou em qualquer linguagem FP moderna:
e
fonte
Como o WhirlWind disse, você começa do começo.
Você troca o cursor com cada valor restante, incluindo o próprio cursor, todas essas são instâncias novas (usei um
int[]
earray.clone()
no exemplo).Em seguida, execute permutações em todas essas listas diferentes, certificando-se de que o cursor esteja à direita.
Quando não houver mais valores restantes (o cursor está no final), imprima a lista. Esta é a condição de parada.
fonte
A recursiva sempre exige algum esforço mental para manter. E para grandes números, o fatorial é facilmente enorme e o excesso de pilha será facilmente um problema.
Para números pequenos (3 ou 4, o que é encontrado principalmente), vários loops são bastante simples e diretos. É lamentável que as respostas com loops não tenham sido votadas.
Vamos começar com enumeração (em vez de permutação). Basta ler o código como código pseudo-perl.
A enumeração é mais frequentemente encontrada do que a permutação, mas se ela for necessária, basta adicionar as condições:
Agora, se você realmente precisa de um método geral potencialmente para grandes listas, podemos usar o método radix. Primeiro, considere o problema de enumeração:
O incremento de base é essencialmente a contagem de números (na base do número de elementos da lista).
Agora, se você precisar de permissão, basta adicionar as verificações dentro do loop:
Edit: O código acima deve funcionar, mas para permutação, radix_increment pode ser um desperdício. Portanto, se o tempo é uma preocupação prática, temos que mudar radix_increment para permute_inc:
Claro que agora esse código é logicamente mais complexo, deixarei para o exercício do leitor.
fonte
Referência: Geeksforgeeks.org
fonte
Se alguém se perguntar como fazer permutação em javascript.
Ideia / pseudocódigo
por exemplo. 'a' + permuto (bc). permuto de bc seria bc & cb. Agora adicione estes dois dará abc, acb. da mesma forma, escolha b + permute (ac) provará bac, bca ... e continuará.
agora olhe o código
Tome seu tempo para entender isso. Eu recebi esse código de ( pertumation em JavaScript )
fonte
Outro em Python, não está no lugar do @ cdiggins, mas acho que é mais fácil entender
fonte
Eu estava pensando em escrever um código para obter as permutações de qualquer número inteiro de qualquer tamanho, ou seja, fornecendo um número 4567, obteremos todas as permutações possíveis até 7654 ... Então trabalhei nele e encontrei um algoritmo e finalmente o implementei. é o código escrito em "c". Você pode simplesmente copiá-lo e executar em qualquer compilador de código aberto. Mas algumas falhas estão esperando para serem depuradas. Por favor aprecie.
Código:
fonte
Eu criei este. com base em pesquisas muito permutadas (qwe, 0, qwe.length-1); Só para você saber, você pode fazê-lo com ou sem retorno
fonte
Aqui está um método Ruby de brinquedo que funciona assim
#permutation.to_a
pode ser mais legível para pessoas loucas. É hella lento, mas também 5 linhas.fonte
Eu escrevi essa solução recursiva em ANSI C. Cada execução da função Permutate fornece uma permutação diferente até que todas sejam concluídas. Variáveis globais também podem ser usadas para variáveis fact e count.
fonte
Versão Java
Por exemplo
resultado:
fonte
em PHP
fonte
Aqui está o código em Python para imprimir todas as permutações possíveis de uma lista:
Eu usei um algoritmo de ordem lexicográfica para obter todas as permutações possíveis, mas um algoritmo recursivo é mais eficiente. Você pode encontrar o código do algoritmo recursivo aqui: Permutações de recursão do Python
fonte
fonte
Na cidade Scala
fonte
esta é uma versão java para permutação
fonte
Aqui está uma implementação do ColdFusion (requer CF10 devido ao argumento de mesclagem para ArrayAppend ()):
Baseado na solução js de KhanSharp acima.
fonte
Sei que isso é muito muito antigo e até fora de tópico no stackoverflow de hoje, mas ainda queria contribuir com uma resposta javascript amigável pela simples razão de que ela é executada no seu navegador.
Também adicionei o
debugger
ponto de interrupção da diretiva para que você possa percorrer o código (é necessário o cromo) para ver como esse algoritmo funciona. Abra seu console de desenvolvedor no chrome (F12
no Windows ouCMD + OPTION + I
no mac) e clique em "Executar trecho de código". Isso implementa o mesmo algoritmo exato que o @WhirlWind apresentou em sua resposta.Seu navegador deve pausar a execução na
debugger
diretiva. UseF8
para continuar a execução do código.Percorra o código e veja como ele funciona!
fonte
Na solução Java a seguir, aproveitamos o fato de que Strings são imutáveis para evitar a clonagem do conjunto de resultados a cada iteração.
A entrada será uma String, digamos "abc", e a saída terá todas as permutações possíveis:
Código:
A mesma abordagem pode ser aplicada a matrizes (em vez de uma string):
fonte
É a minha solução em Java:
fonte
Você realmente não pode falar sobre resolver um problema de permeação em recursão sem postar uma implementação em uma linguagem (dialeta) que foi pioneira na idéia . Portanto, por uma questão de integridade, aqui está uma das maneiras que podem ser feitas no Scheme.
chamando
(permof (list "foo" "bar" "baz"))
vamos obter:Não vou entrar nos detalhes do algoritmo porque já foi explicado o suficiente em outras postagens. A ideia é a mesma.
No entanto, problemas recursivos tendem a ser muito mais difíceis de modelar e pensar em meios destrutivos, como Python, C e Java, enquanto no Lisp ou ML, isso pode ser expresso de forma concisa.
fonte
Aqui está uma solução recursiva em PHP. A publicação do WhirlWind descreve com precisão a lógica. Vale ressaltar que a geração de todas as permutações é executada em tempo fatorial; portanto, pode ser uma boa ideia usar uma abordagem iterativa.
A função strDiff usa duas strings,
s1
es2
, e retorna uma nova string com tudo dentros1
sem elementos ems2
(matéria duplicada). Então,strDiff('finish','i')
=>'fnish'
(o segundo 'i' não é removido).fonte
Aqui está um algoritmo no R, caso alguém precise evitar o carregamento de bibliotecas adicionais, como eu precisei.
Exemplo de uso:
fonte
fonte
Este é um código recursivo para java, a idéia é ter um prefixo que adicione o restante dos caracteres:
Exemplo:
Entrada = "ABC"; Resultado:
ABC ACB BAC BCA CAB CBA
fonte
str
quando chamar recursivamente, caso contrário, ele não será encerrado.Apenas para ser completo, C ++
...
fonte
Aqui está uma solução não recursiva em C ++ que fornece a próxima permutação em ordem crescente, semelhante à funcionalidade fornecida por std :: next_permutation:
fonte