Hiệu quả tìm GCD cặp đôi tối đa của một tập hợp các số tự nhiên


9

Hãy xem xét vấn đề sau:

Đặt là tập con hữu hạn của các số tự nhiên.S={s1,s2,...sn}

Đặt g c d ( s i , s j ) | s i , s jS , s is j } trong đó g c d ( x , y ) là ước số chung lớn nhất của xyG={ gcd(si,sj)si,sjS, sisj}gcd(x,y)xy

Tìm các yếu tố tối đa của .G

Vấn đề này có thể được giải quyết bằng cách lấy ước số chung lớn nhất của mỗi cặp bằng thuật toán của Euclid và theo dõi số lớn nhất.

Có cách nào hiệu quả hơn để giải quyết điều này?


3
Bạn có thể muốn xem Phần 3.3 về Khai thác Ps ​​và Q của bạn: Phát hiện các khóa yếu phổ biến trong các thiết bị mạng (Heninger et al, Usenix Security 2012). Chúng mô tả một thuật toán để tính toán các gcd của cặp đôi trong gcd, trong một cài đặt nhất định, sử dụng các cây sản phẩm và các cây còn lại. Tôi không biết nếu nó kéo dài đến vấn đề của bạn, mặc dù. O(nlgn)
DW

Bạn đã thử bất cứ điều gì với các yếu tố chính?
Ryan

1
Giả sử tất cả các số tương đối nguyên tố nhưng khó tính (ví dụ: mỗi bằng p i q i cho các số nguyên tố phân biệt lớn p i , q i ). Sau đó, có vẻ khó tránh việc kiểm tra tất cả các GCD cặp. (Nói tôi nói với bạn rằng sau khi kiểm tra tất cả các cặp nhưng ( s n - 1 , s n ) rằng tất cả các GCD theo cặp là 1. Làm thế nào bạn có thể đoán g c d ( s n - 1 , s n ) mà không tính toán nó?)sipiqipi,qi(sn1,sn)1gcd(sn1,sn)
usul

Liên kết của @usul DW chính xác là vấn đề đó. Một con số khổng lồ, ví dụ một tỷ, khóa mã hóa nên là sản phẩm của hai số nguyên tố riêng biệt. Nhưng chúng tôi nghi ngờ rằng một số khóa mã hóa có một yếu tố chung (đó sẽ là gcd của cả hai khóa, làm cho cả hai yếu tố dễ dàng). Thuật toán đó cho phép bạn tìm các khóa có hệ số chung mà không cần tính n (n-1) / 2 gcd cho n = 1 tỷ.
gnasher729

Câu trả lời:


-2

Đây là một thuật toán hiệu quả (bằng Python ). Vui lòng tìm lời giải thích dưới đây.

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

Giải thích về đoạn mã trên:

Chúng tôi quan sát những điều sau đây trong vấn đề này:

  1. Kết quả không thể nhiều hơn max(S)
  2. Kết quả là một số, có hai hoặc nhiều bội số trong danh sách này S
  3. Trong thực tế, kết quả là maxcủa tất cả các số như vậy với tài sản được đề cập ở trên.

Với những quan sát này, chương trình thực hiện như sau:

  1. Tạo một setdanh sách. Vì bộ có thể được tìm kiếm hiệu quả trongO(log(n))
  2. Tìm max của danh sách và lưu nó trong biến m.
  3. Bắt đầu từ mđến 1, tìm ra số đầu tiên có hai hoặc nhiều hơn bội trong bộ này. Con số đầu tiên được tìm thấy là kết quả.

Tôi hy vọng điều này là rõ ràng. Xin vui lòng cho tôi biết nếu bạn cần một lời giải thích chi tiết hơn.


1
Bạn có thể giải thích thuật toán của bạn bằng lời? Đây không phải là một trang web lập trình.
Yuval Filmus

@YuvalFilmus Tôi đã thêm lời giải thích. Hi vọng điêu nay co ich.
Subhendu Ranjan Mishra

2
{2,4}

@YuvalFilmus cho mỗi lần ibắt đầu mcho đến khi 1chúng tôi kiểm tra xem có hai hoặc nhiều bội số itrong tập hợp không. Trong ví dụ này, hai bội số của 2 nằm trong tập '2 và 4`. vì vậy câu trả lời là 2. whileVòng lặp bên trong kiểm tra tất cả các đa số icho đến m' as m` là masx của danh sách.
Subhendu Ranjan Mishra

1
x,yn
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.