Visão geral
Oteste de primalidadeé um algoritmo para determinar se um determinado inteiro positivo é um número primo ou não. Existem muitos métodos para verificar se um número é primo ou não, como,o método escolar,Método de Divisão de Julgamento,Teste de primalidade de Fermat, eTeste de primalidade de Miller-Rabin.
Âmbito do artigo
- Neste artigo vamos discutir diferentestestes de primalidadeemestruturas de dados.
- Todostestes de primalidadesão explicados usando etapas e pseudocódigo neste artigo.
- A análise da complexidade de cada método também será discutida neste artigo.
- Os programas são executados emC++,Java, ePitãoneste artigo.
:::
Algoritmo para determinar se um dado inteiro positivo é um número primo ou não:
- método escolar
- Método de Divisão de Julgamento
- Teste de primalidade de Fermat
- Teste de Primalidade de Miller-Rabin
O que é Teste de Primalidade?
Oteste de primalidadeé um algoritmo para determinar se um dado inteiro positivo é um número primo ou não.
A primalidade de um número também pode ser verificada determinando se é um número composto ou não, porque se o número não for umnúmero compostonem1, então deve ser um número primo.
Exemplo
Código Fonte - C++17
Código Fonte - Java (1.8)
Código fonte - Python 3
A saída é a mesma para todas as implementações, pois elas executam a mesma coisa, sendo a única diferença a linguagem de programação.
Saída
Nos exemplos acima, estamos verificando se o número dado é um número primo ou não, para isso, estamos iterando de2paran−1para verificar se esses números dividem o número dado. Se o fizerem, então o número dado não é um número primo, caso contrário, é um número primo.
método escolar
Ométodo escolaré uma solução simples que vem primeiro à mente de todos para verificação de primalidade, pois é a mais simples de todas.
NoMétodo Escolaralgoritmo, iteramos todos os números de2paran−1(o número a ser verificado én) e verifique se eles dividem o númeron.
Análise de Complexidade
Complexidade de tempo:O(N)
Ocomplexidade de tempoda verificação de primalidade do Método Escolar éO(N)enquanto iteramosN−2vezes.
Complexidade Espacial:O(1)
Ocomplexidade do espaçoaqui é constante.
O algoritmo no exemplo acima é apenas School Method.
Método Escolar Otimizado
NoMétodo Escolar, podemos fazer algumas otimizações como:
- Em vez de verificar atén, vamos verificar aténporque um fator denmaior quendeve ser um múltiplo de um número menor quenque já foi verificado e não deve ser verificado novamente.
- Vamos primeiro verificar a divisibilidade denpor2e3, então verifique sua divisibilidade por números da forma6k−1e6k+1Começando àsk=1. Fazemos isso porque qualquer inteiro maior que4pode ser expresso na forma de6k−1,6k,6k+1,6k+2,6k+3, e6k+4(parak>0), mas inteiros da forma6k,6k+2,6k+3, e6k+4será divisível por2ou3.
Vamos dar uma olhada em sua implementação na seção abaixo.
Implementação do Método Escolar Otimizado
Código Fonte - C++17
Código Fonte - Java (1.8)
Código fonte - Python 3
A saída é a mesma para todas as implementações, pois elas executam a mesma coisa, sendo a única diferença a linguagem de programação.
Saída
Nos exemplos acima, estamos verificando se o número dado é um número primo ou não, para isso, primeiro verificamos sua divisibilidade por2e3, verificando então sua divisibilidade por números da forma6k−1e6k+1. Se o número dado for divisível por qualquer número, então não é um número primo, senão é.
Análise de Complexidade
Complexidade de tempo:O(N)
O assintóticocomplexidade de tempoda verificação de primalidade do Método Escolar Otimizado éO(N)porque nós iteramosN/6(eu+=6no loop for) vezes neste algoritmo.
Complexidade Espacial:O(1)
Ocomplexidade do espaçoaqui é constante.
Método de Divisão de Julgamento
OMétodo de Divisão de Julgamentoé um algoritmo de verificação de primalidade no qual aceitamos algum inteiron, verifique se algum número de2parandivide o inteiro dado, se um divisor for encontrado, entãoné um número composto, caso contrário, é um número primo. É muito semelhante ao método escolar.
Análise de Complexidade
Complexidade de tempo:O(N)
Ocomplexidade de tempoda verificação de primalidade do The Trial Division éO(N)enquanto iteramosN−1vezes.
Complexidade Espacial:O(1)
Ocomplexidade do espaçoaqui é constante.
Teste de primalidade de Fermat
OPrimalidade de FermatO teste é um método probabilístico para determinar se o inteiro dado é um número primo provável ou não.
É baseado emPequeno Teorema de Fermatque afirma sepé um número primo eanão é divisível porp, entãoap−1≡1(modp), ou sejaap−1=k∗p+1(ondeké uma constante inteira).
Se quisermos testarppara um número primo, então vamos pegar alguns números inteiros aleatóriosaque não são divisíveis porpe veja se a congruência se mantém ou não. Se a congruência não for válida para um valor dea, então será uma prova de quepé um número composto, mas se a congruência for válida para mais de um valor dea, entãopé um provável número primo.
Passos do Algoritmo
- Repita o seguintekvezes (maior valor dekindica maior probabilidade de resultados corretos):
- Lidar com casos de canto parap<3(pé o número a ser testado).
- Escolha um número aleatórioano intervalo1<a<p.
- Seap−1̸≡1(modp), então retorneFaeuse.
- RetornarTrvocêe,pé provavelmente um número primo.
Exemplo
Vamos supor, temos que verificar sen=221é um número primo ou não. Vamos escolher aleatoriamente um númeroano intervalo1<a<221. Em seguida, verificaremos se a congruência é válida ou não.
Paraa=38,
38221−1≡1(mod221), comoap−1≡1(modp)=>38220≡1(mod221),
Agora pode haver dois casos,221é um número primo, ou38é um mentiroso Fermat. Para prosseguir, vamos pegara=24.
mas,24220̸≡1(mod221), como24220≡81(mod221).
Isso prova que221é um número composto e38é Fermat mentiroso,24sendo a testemunha de Fermat para a composição de221.
Análise de Complexidade
Complexidade de tempo:O(k∗euog(N))
Aqui,ké o número de iterações eNé o número a ser testado quanto à primalidade.euog(N)é a complexidade de tempo para computaçãoap−1e o algoritmo é repetidokvezes. Então a complexidade de tempo éO(k∗euog(N)).
Complexidade Espacial:O(1)
Não há necessidade de espaço extra, portanto a complexidade do espaço é constante.
O pequeno teorema de Fermat é usado para mais um teste de Primalidade, chamado de Teste de Primalidade de Miller-Rabin.
Teste de Primalidade de Miller-Rabin
OTeste de Primalidade de Miller-Rabintambém é um método probabilístico para determinar se o inteiro dado é um número primo ou não, semelhante ao Teste de Primalidade de Fermat. Também é baseado no Pequeno Teorema de Fermat (discutido na seção acima).
Este teste foi descoberto por Gary Lee Miller em1976, posteriormente modificado por Michael Oser Rabin em1980.
O resultado deste teste será se o número dado é um número composto ou um provável número primo. Os prováveis números primos noTeste de Primalidade de Miller-Rabinsão chamados de números prováveis fortes, pois têm uma chance maior de ser um número primo do que noTeste de Primalidade de Fermat.
Um númeroné dito ser um número primo provável forte para basearase uma dessas relações de congruência (relações de equivalência na aritmética de módulo,A≡B(modC)significaAé congruente comBmóduloC) detém:
- ad≡1(modn)
- a2r∗d≡−1(modn)
Passos do Algoritmo
né o número a ser testado.
kindica a precisão do teste.
dé um número ímpar tal quen−1pode ser escrito na forma ded∗2r(Desdené estranho,n−1deve ser par er>0).
eusPreume(euntn,euntk)
- Lidar com casos base paran<3.
- sené par, retorneFaeuse.
- Encontrar um número ímpard.
- Faça o seguintekvezes:
- Verifique semeueueuerTest(n,d)==faeuse, se sim, retorneFaeuse.
- RetornarTrvocêe.
meueueuerRabeunTest(euntn,euntd)
- Escolha um número aleatórioano intervalo2≤a≤n−2.
- CalcularErro de análise do KaTeX: Esperado 'EOF', obtido '%' na posição 15: x = pow(a, d) %̲ n.
- RetornarTrvocêesex==1orx==n−1.
- Faça o loop a seguir atéd==n−1.
- x=(x∗x)%n.
- RetornarFaeusesex==1.
- RetornarTrvocêesex==n−1.
Implementação daTeste de Primalidade de Miller-Rabin
Código Fonte - C++17
Código Fonte - Java (1.8)
Código fonte - Python 3
A saída é a mesma para todas as implementações, pois elas executam a mesma coisa, sendo a única diferença a linguagem de programação.
Saída
Nos exemplos acima, estamos verificando se o número dado é um provável número primo ou um número composto, para isso, estamos utilizando o Teste de Primalidade de Miller-Rabin. Se a função retornarTrvocêe, então o número dado é um provável número primo, caso contrário, é um número composto.
O Teste de Miller-Rabin, sendo uma extensão do Teste de Primalidade de Fermat, é mais preciso do que o Teste de Primalidade de Fermat, portanto, é preferível a ele.
Análise de Complexidade
Complexidade de tempo:O(k∗euog3(N)
Ocomplexidade de tempodo teste de primalidade de Miller-Rabin éO(k∗euog3(N), ondeNé o número a ser verificado quanto à primalidade eké o número de iterações executadas para precisão de acordo com o requisito.
Complexidade Espacial:O(1)
Não há necessidade de espaço extra, portanto a complexidade do espaço é constante.
Conclusão
- testes de primalidadesão usados para determinar se um determinado número é primo ou não.
- O método School é um algoritmo ingênuo deO(N)complexidade do tempo.
- O método Optimized School e o algoritmo Trial Division têm uma complexidade de tempo deO(n).
- OTeste de primalidade de Fermate o teste de primalidade de Miller-Rabin retornam se um número é composto ou um primo provável e são baseados no Pequeno Teorema de Fermat.
- A complexidade temporal doTeorema da Primalidade de FermatéO(k∗euog(N)).
- A complexidade temporal doTeste de Primalidade de Miller-RabinéO(k∗euog3(N).