Encontrar eficientemente o GCD máximo em pares de um conjunto de números naturais


9

Considere o seguinte problema:

Deixe S={s1,s2,...sn} ser um subconjunto finito dos números naturais.

Seja G={ gcd(sEu,sj) | onde é o maior divisor comum de esEu,sjS, g c d ( x , y ) x ysEusj}gcd(x,y)xy

Localize o elemento máximo de .G

Esse problema pode ser resolvido usando o maior divisor comum de cada par usando o algoritmo de Euclides e mantendo o controle do maior.

Existe uma maneira mais eficiente de resolver isso?


3
Você pode dar uma olhada na Seção 3.3 de Minerando seus Ps e Qs: detecção de chaves fracas generalizadas em dispositivos de rede (Heninger et al, Usenix Security 2012). Eles descrevem um algoritmo para calcular MDCs pares em MDCs, em uma determinada configuração, usando árvores de produtos e árvores restantes. Mas não sei se isso se estende ao seu problema. O(nlgn)
DW

Você já tentou alguma coisa com fatorações primárias?
22714 Ryan

11
Suponha que todos os números sejam relativamente primos, mas difíceis de fatorar (por exemplo, cada é igual a para números primos distintos grandes ). Parece difícil evitar a verificação de todos os GCDs aos pares. (Diga que eu lhe disse que depois de verificar todos os pares, mas que todos os GCDs em pares são Como você adivinhoup i q i p i , q i ( s n - 1 , s n ) 1 g c d ( s n - 1 , s n ) sem computação lo)?sEupEuqEupEu,qEu(sn-1 1,sn)1 1gcd(sn-1 1,sn)
usul

O link do @usul DW é exatamente esse problema. Um grande número, digamos um bilhão, de chaves de criptografia deve ser produto de dois primos distintos. Mas suspeitamos que algumas chaves de criptografia tenham um fator primordial em comum (que seria o MDC de ambas as chaves, facilitando o fator). Esse algoritmo permite encontrar as chaves com fator comum sem calcular n (n-1) / 2 gcd para n = 1 bilhão.
precisa saber é o seguinte

Respostas:


-2

Aqui está um algoritmo eficiente (em Python ). Por favor, encontre a explicação abaixo.

def max_gcd_pair(S):
    # Assumption 1: S is the list of numbers
    # Assumption 2: There are no duplicates in S

    s = set(S)
    m = max(S)

    res = 0
    i = m

    while(i > 0):
        a = i
        cnt = 0
        while (a<=m): # a maxed at max of the list
            if a in s:   
               cnt += 1
            a += i

        if cnt >= 2:  # we have found the result
            res = i
            break

        i = i -1 

    return res

Explicação do trecho de código acima:

Observamos o seguinte neste problema:

  1. O resultado não pode ser superior a max(S)
  2. O resultado é um número que possui dois ou mais múltiplos nesta lista S
  3. De fato, o resultado é maxde todos esses números com a propriedade mencionada acima.

Com essas observações, o programa faz o seguinte:

  1. Faça uma setlista. Como os conjuntos podem ser pesquisados ​​eficientemente emO(log(n))
  2. Encontre o máximo de lista e armazená-lo na variável m.
  3. Começando de maté 1, encontre o primeiro número que tem dois ou mais múltiplos no conjunto. O primeiro número encontrado é o resultado.

Espero que isso esteja claro. Entre em contato se precisar de uma explicação mais detalhada.


11
Você pode explicar seu algoritmo em palavras? Este não é um site de programação.
Yuval Filmus

@YuvalFilmus Adicionei a explicação. Espero que isto ajude.
Subhendu Ranjan Mishra

2
{2,4}

@YuvalFilmus para cada icomeçando com maté 1vamos verificar se duas ou mais múltiplos de iestão no conjunto. Neste exemplo, dois múltiplos de 2 estão no conjunto '2 e 4'. então a resposta é 2. O whileloop interno verifica todos os múltiplos de iaté m' as m` é o masx da lista.
Subhendu Ranjan Mishra

11
x,yn
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.