Ефективне знаходження максимального парного GCD набору натуральних чисел


9

Розглянемо наступну проблему:

Нехай є кінцевим підмножиною натуральних чисел.S={s1,s2,...sn}

Нехай | s_i, s_j \ in S, s_i \ neq s_j \} де gcd (x, y) - найбільший спільний дільник x і yG={ gcd(si,sj)si,sjS, sisj}gcd(x,y)xy

Знайти максимальний елемент G .

Цю проблему можна вирішити, взявши найбільшого спільного дільника кожної пари за допомогою алгоритму Евкліда та відстежуючи найбільшу.

Чи існує більш ефективний спосіб вирішення цього питання?


3
Ви можете ознайомитись з розділом 3.3 Видобуток ваших психічних питань: виявлення широких слабких ключів у мережевих пристроях (Heninger та ін, Usenix Security 2012). Вони описують алгоритм для обчислення парних gcd's в gcd, у певних умовах, використовуючи дерева продуктів та залишки дерев. Я не знаю, чи поширюється це на вашу проблему. О(нlgн)
DW

Ви щось пробували з простими чинниками?
Райан

1
Припустимо, що всі числа є відносно простими, але важкодоступними (наприклад, кожен дорівнює для великих чітких простих чисел ). Тоді здається важким уникнути перевірки всіх парних GCD. (Скажіть, я скажу вам, що після перевірки всіх пар, але що всі парні GCD є Як ви могли здогадатися не обчислюючи його?)sipiqipi,qi(сн-1,сн)1гcг(сн-1,сн)
usul

Посилання @usul DW - саме ця проблема. Величезна кількість, скажімо, мільярд, ключів шифрування повинні бути продуктами двох чітких простих. Але ми підозрюємо, що деякі ключі шифрування мають спільний основний фактор (який був би gcd обох клавіш, що робить обидва простими для фактора). Цей алгоритм дозволяє знаходити ключі із загальним коефіцієнтом без обчислення n (n-1) / 2 gcd's для n = 1 мільярд.
gnasher729

Відповіді:


-2

Ось ефективний алгоритм (в Python ). Будь ласка, знайдіть пояснення нижче.

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

Пояснення вищевказаного фрагмента коду:

У цій проблемі ми спостерігаємо:

  1. Результат не може бути більше max(S)
  2. Результат - це число, яке містить два чи більше кратних у цьому списку S
  3. Фактично результат - це maxвсі такі числа із зазначеним вище властивістю.

За допомогою цих спостережень програма робить наступне:

  1. Складіть setсписок. Оскільки в наборах можна ефективно шукатиO(log(n))
  2. Знайдіть максимум списку і зберігайте його у змінній m.
  3. Починаючи з mдо 1, знайдіть перше число, яке містить два чи більше кратних у наборі. Перше таке знайдене число - результат.

Сподіваюся, це зрозуміло. Будь ласка, дайте мені знати, якщо вам потрібно більш детальне пояснення.


1
Чи можете ви пояснити свій алгоритм словами? Це не сайт програмування.
Yuval Filmus

@YuvalFilmus Я додав пояснення. Сподіваюсь, це допомагає.
Subhendu Ranjan Mishra

2
Що робити, якщо всі елементи унікальні? Це не означає, що максимальний GCD дорівнює 1. Розглянемо, наприклад, множину , де максимальний GCD дорівнює 2.{2,4}
Yuval Filmus

@YuvalFilmus для кожного iпочинаючи з, mпоки 1ми не перевіримо, чи є два чи більше кратних значень iу наборі. У цьому прикладі два кратні 2 є у множині "2 і 4". тому відповідь є 2. Внутрішня whileпетля перевіряє всі кратності iдо m' as m '- макс списку.
Subhendu Ranjan Mishra

1
Ну, це жахливий алгоритм. Для масиву з двох чисел довжиною біт кожне, обчислення GCD займає багаточлен, тоді як ваш алгоритм займає експоненціальний час у гіршому випадку (коли числа відносно прості). x,yн
Yuval Filmus
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.