Qual é a melhor abordagem para calcular o maior fator primo de um número?
Estou pensando que o mais eficiente seria o seguinte:
- Encontre o número primo mais baixo que divide corretamente
- Verifique se o resultado da divisão é primo
- Caso contrário, encontre o próximo menor
- Vá para 2.
Estou baseando essa suposição em que é mais fácil calcular os pequenos fatores primos. Isso é certo? Quais outras abordagens devo analisar?
Edit: Agora eu percebi que minha abordagem é inútil se houver mais de 2 fatores primos em jogo, uma vez que a etapa 2 falha quando o resultado é um produto de duas outras primas, portanto, é necessário um algoritmo recursivo.
Edite novamente: e agora percebi que isso ainda funciona, porque o último número primo encontrado deve ser o mais alto; portanto, qualquer teste adicional do resultado não primo da etapa 2 resultaria em um primo menor.
algorithm
math
prime-factoring
mercutio
fonte
fonte
1.
encontrar qualquer número que divide claramente (para i = 2 a int (sqr (num)))2.
dividir por esse número (num = num / i) e recorrência até que nada é encontrado em 1. 's intervalo3.
num é o maior fatorRespostas:
Na verdade, existem várias maneiras mais eficientes de encontrar fatores de grandes números (para os menores, a divisão de ensaios funciona razoavelmente bem).
Um método que é muito rápido se o número de entrada tiver dois fatores muito próximos de sua raiz quadrada é conhecido como fatoração de Fermat . Utiliza a identidade N = (a + b) (a - b) = a ^ 2 - b ^ 2 e é fácil de entender e implementar. Infelizmente, não é muito rápido em geral.
O método mais conhecido para calcular números de até 100 dígitos é a peneira quadrática . Como bônus, parte do algoritmo é facilmente executada com processamento paralelo.
Outro algoritmo de que ouvi falar é o algoritmo Rho de Pollard . Não é tão eficiente quanto a Peneira Quadrática em geral, mas parece ser mais fácil de implementar.
Depois de decidir como dividir um número em dois fatores, eis o algoritmo mais rápido em que consigo encontrar o maior fator primordial de um número:
Crie uma fila de prioridade que inicialmente armazene o número em si. A cada iteração, você remove o número mais alto da fila e tenta dividi-lo em dois fatores (não permitindo que 1 seja um desses fatores, é claro). Se esta etapa falhar, o número é primo e você tem a sua resposta! Caso contrário, você adiciona os dois fatores à fila e repete.
fonte
Aqui está o melhor algoritmo que eu conheço (em Python)
O método acima é executado no
O(n)
pior dos casos (quando a entrada é um número primo).EDIT:
Abaixo está a
O(sqrt(n))
versão, conforme sugerido no comentário. Aqui está o código, mais uma vez.fonte
O(sqrt(n))
pior dos casos" - Não, é executado noO(n)
pior dos casos (por exemplo, quandon
é primo).Minha resposta é baseada no Triptych , mas melhora muito. É baseado no fato de que além de 2 e 3, todos os números primos têm a forma 6n-1 ou 6n + 1.
Eu escrevi recentemente um artigo de blog explicando como esse algoritmo funciona.
Atrevo-me a que um método no qual não há necessidade de um teste de primalidade (e nenhuma construção de peneira) seja executado mais rapidamente do que aquele que os utiliza. Se for esse o caso, este é provavelmente o algoritmo mais rápido aqui.
fonte
while (multOfSix - 1 <= n)
Código JavaScript:
Exemplo de uso:
Aqui está um exemplo do código :
fonte
Semelhante à resposta @Triptych, mas também diferente. Neste exemplo, lista ou dicionário não é usado. O código está escrito em Ruby
fonte
Todos os números podem ser expressos como o produto de números primos, por exemplo:
Você pode encontrá-los simplesmente começando em 2 e continuando a dividir até o resultado não ser um múltiplo do seu número:
usando esse método, você não precisa calcular primos: eles serão primos, com base no fato de que você já fatorou o número o máximo possível com todos os números anteriores.
fonte
currFactor = 3513642
, sabemos que 12345678987667 é excelente e deve devolvê-lo como resposta. Em vez disso, esse código continuará a enumeração até o próprio 12345678987667. Isso é 3.513.642x mais lento que o necessário.fonte
while
loop passará pori
valores de2,2,2,2,2,2,2,2,2,2,2,2, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5
. Todas as 60 iterações. Mas para (10 ^ 12 + 39) haverá (10 ^ 12 + 38) iteraçõesi=2,3,4,5,6,...,10^12+39
,. Mesmo que 10 ^ 10 operações levem um segundo, 10 ^ 12 levará 100 segundos. Mas apenas 10 ^ 6 iterações são realmente necessárias e, se 10 ^ 10 operações demorarem um segundo, 10 ^ 6 levariam 1/1000 de segundo.long n = 2*1000000000039L
? Funciona o mais rápido que deveria? (além disso, você pode simplificar seu código usando umareturn;
instrução?). (se você quer que eu pare te empurrando, é só dizer;))A solução mais simples é um par de funções recursivas mutuamente .
A primeira função gera todos os números primos:
A segunda função retorna os fatores primos de um determinado número
n
em ordem crescente.n
.O maior fator primo de
n
é o último número fornecido pela segunda função.Esse algoritmo requer uma lista lenta ou um idioma (ou estrutura de dados) com semântica chamada por necessidade .
Para esclarecimento, aqui está uma implementação (ineficiente) do acima mencionado em Haskell:
Tornar isso mais rápido é apenas uma questão de ser mais inteligente sobre a detecção de quais números são primos e / ou fatores
n
, mas o algoritmo permanece o mesmo.fonte
Existem alguns testes de módulo que são supérfluos, pois n nunca pode ser dividido por 6 se todos os fatores 2 e 3 tiverem sido removidos. Você só pode permitir números primos para i, o que é mostrado em várias outras respostas aqui.
Você pode realmente entrelaçar a peneira de Eratóstenes aqui:
Veja também esta pergunta .
fonte
Estou ciente de que essa não é uma solução rápida. Postagem como esperançosamente mais fácil de entender solução lenta.
fonte
Abordagem iterativa Python removendo todos os fatores primos do número
fonte
Eu estou usando um algoritmo que continua dividindo o número pelo atual fator primo.
Minha solução em python 3:
Entrada:
10
Saída:5
Entrada:
600851475143
Saída:6857
fonte
Aqui está minha tentativa em c #. A última impressão é o maior fator principal do número. Eu verifiquei e funciona.
fonte
fonte
Calcula o maior fator primo de um número usando a recursão em C ++. O funcionamento do código é explicado abaixo:
fonte
Aqui está minha abordagem para calcular rapidamente o maior fator primo. É baseado no fato de que modificado
x
não contém fatores não primos. Para conseguir isso, dividimosx
assim que um fator é encontrado. Então, a única coisa que resta é retornar o maior fator. Já seria nobre.O código (Haskell):
fonte
O seguinte algoritmo C ++ não é o melhor, mas funciona para números abaixo de um bilhão e é muito rápido
fonte
Encontrei esta solução na web por "James Wang"
fonte
Fator principal usando a peneira:
fonte
Parece-me que o passo 2 do algoritmo dado não será uma abordagem tão eficiente. Você não tem uma expectativa razoável de que seja primordial.
Além disso, a resposta anterior que sugere a Peneira de Eratóstenes está totalmente errada. Acabei de escrever dois programas para o fator 123456789. Um foi baseado na peneira, um foi baseado no seguinte:
Esta versão foi 90x mais rápida que a peneira.
O problema é que, nos processadores modernos, o tipo de operação importa muito menos que o número de operações, sem mencionar que o algoritmo acima pode ser executado em cache, o Sieve não. A peneira usa muitas operações eliminando todos os números compostos.
Observe, também, que a divisão dos fatores conforme identificados reduz o espaço que deve ser testado.
fonte
Calcule uma lista armazenando números primos primeiro, por exemplo, 2 3 5 7 11 13 ...
Toda vez que você fatorar um número primo, use a implementação do Triptych, mas iterando essa lista de números primos, em vez de números inteiros naturais.
fonte
Com Java:
Para
int
valores:Para
long
valores:fonte
Provavelmente nem sempre é mais rápido, mas mais otimista quanto ao fato de você encontrar um grande divisor principal:
N
é o seu númeroreturn(N)
Sqrt(N)
N is divisible by Prime
entãoReturn(Prime)
Editar: na etapa 3, você pode usar a peneira de Eratóstenes ou a peneira de Atkins ou o que quiser, mas por si só a peneira não encontrará o maior fator primordial. (É por isso que eu não escolheria a postagem do SQLMenace como resposta oficial ...)
fonte
Eu acho que seria bom armazenar em algum lugar todos os números possíveis menores que n e simplesmente percorrer eles para encontrar o maior divisor. Você pode obter primos em prime-numbers.org .
Claro que presumo que seu número não seja muito grande :)
fonte
Não é o mais rápido, mas funciona!
fonte
Aqui está a mesma função @ Triptych fornecida como gerador, que também foi ligeiramente simplificada.
o max prime pode ser encontrado usando:
e uma lista de fatores encontrados usando:
fonte
fonte