Algoritmo para verificar se uma lista de números inteiros é coprime em pares


8

Existem algoritmos eficientes para verificar se uma lista de números inteiros é coprime em pares, ou um algoritmo mais geral seria a melhor opção disponível?


Só para ter certeza, você quer dizer que todo par de números inteiros no seu conjunto é coprime?
Draconis

2
sim, todas as combinações de 2 inteiros devem ser coprime
user2782067

Respostas:


8

Primeiro, dois fatos sobre números inteiros de coprime:

  • Se e são coprime, entãoumabumab=eucm(uma,b)
  • Sse é coprime para ambos e , em seguida, é para coprimeumabcumabc

Daqui resulta que um conjunto de números inteiros distintos é coprime em pares se seu produto for igual ao seu múltiplo menos comum.{uma,b,z}

Você pode calcular o múltiplo menos comum usando a seguinte identidade:

eucm(uma,b,c)=eucm(uma,eucm(b,c))

Supondo que você tenha números com dígitos cada e multiplicando / dividindo / modificando dois números seja (que pode ou não ser uma boa suposição, dependendo do seu modelo), então:nkO(1)

  • O cálculo do produto do seu conjunto levaO(n)
  • Calcular o MDC de dois números levaO(k)
  • Calcular o lcm de dois números também leva , reduzindo para gcdO(k)
  • Portanto, calcular o lcm de todo o seu conjunto levaO(nk)

Assim, a complexidade do tempo de todo o algoritmo é .O(nk)


2
Se o OP estiver realmente implementando isso, pode valer a pena avaliar se o produto / cm3 é igual para cada número conforme são lidos, em vez de multiplicar todos / cmcm todos eles. Isso não vai mudar a complexidade, mas se você espera que a maioria das listas para não ser coprime (como seria o caso de uma longa lista de números aleatórios), então ele provavelmente será mais rápido
sudo rm -rf cortar

5
@DW Eu acredito que o ponto é que, testando de forma incremental, você pode resgatar cedo assim que o primeiro exemplo não coprime for encontrado, em vez de somente após o processamento de toda a lista. Como esperamos que a maioria das listas não seja coprime em pares e não tenhamos informações sobre a lista sendo testada, devemos esperar que a lista provavelmente não seja coprime em pares e, portanto, prossiga com um procedimento otimizado para esse caso comum .
Andrea Reina

@AndreaReina exatamente obrigado por escrever com mais clareza #
sudo rm -rf slash

Outra nota implementação ... Usando gcd == 1 em vez de lcm == prod é provavelmente mais fácil desde que, tanto quanto eu sei que os melhores algos LCM usar o mdc de qualquer maneira
sudo rm -rf cortar

2
Se você contar o número de dígitos dos números, não faz sentido supor que a multiplicação e a divisão sejam . Eles são por alguns . O(1)Ω(kuma)k>1
Gilles 'SO- stop be evil'

4

Sim. A abordagem ingênua de verificar cada par de números leva tempo quadrático, mas existem algoritmos mais eficientes. Existe um algoritmo de tempo quase linear, descrito no artigo a seguir:

Daniel J. Bernstein. Factoring em coprimes em tempo essencialmente linear . Jornal de Algoritmos 54 (2005), 1--30.

Consulte também https://cstheory.stackexchange.com/q/3393/5038 . Isso é quase tão eficiente quanto você poderia esperar.

Para esclarecer como isso ajuda na sua situação, uma vez que você encontrou uma base de coprime e fatorou cada elemento sobre a base, é trivial verificar se eles são coprimes em pares: se eles não são coprimes em pares, alguns pares terão um fator, e esse será um fator que está na base do coprime e que está presente na fatoração de ambos. Se não houver um fator comum na fatoração de dois ou mais números, você sabe que os números são coprime em pares. Depois de ter as fatorações, é fácil verificar em tempo linear se existem números em mais de uma fatoração.


2
Não vejo como Factoring over a coprime basese relaciona com checking if a list of integers is pairwise coprime(ainda).
58568

@greybeard, veja resposta editada - adicionei um parágrafo no final explicando.
DW

2

Encontre os fatores primos de cada número. Os números são coprime em pares, se e somente se todos os primos de toda a coleção forem distintos. Essa verificação pode ser feita em O (n) tempo usando uma tabela de hash.

Edit: A resposta de Draconis é melhor, porque não exige nenhuma fatoração. O cálculo do GCD é mais rápido se seus números forem grandes e / ou primos.


2
Factoring é muito lento. Tanto quanto sabemos, não existe um algoritmo eficiente para fatoração - e certamente não sabemos de um que leva tempo O (n). Basicamente, esse algoritmo estará próximo do tempo exponencial (tecnicamente, tempo subexponencial, mas superpolinomial).
DW
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.