การหา GCD สูงสุดตามลำดับสูงสุดของชุดตัวเลขธรรมชาติอย่างมีประสิทธิภาพ


9

พิจารณาปัญหาต่อไปนี้:

ปล่อย S={s1,s2,...sn} เป็นเซตย่อยของตัวเลขธรรมชาติ

ให้ | โดยที่เป็นตัวหารร่วมมากที่สุดของและG={ gcd(si,sj)si,sjS, sisj}gcd(x,y)xy

ค้นหาองค์ประกอบสูงสุดของGG

ปัญหานี้สามารถแก้ไขได้โดยการใช้ตัวหารสามัญที่ยิ่งใหญ่ที่สุดของแต่ละคู่โดยใช้อัลกอริทึมของ Euclid และติดตามตัวที่ใหญ่ที่สุด

มีวิธีที่มีประสิทธิภาพมากขึ้นในการแก้ปัญหานี้หรือไม่?


3
คุณอาจต้องการดูหัวข้อ 3.3 ของการขุด Ps ​​และ Qs ของคุณ: การตรวจหาคีย์ที่อ่อนแออย่างกว้างขวางในอุปกรณ์เครือข่าย (Heninger et al, Usenix Security 2012) พวกเขาอธิบายอัลกอริทึมสำหรับการคำนวณ gcd ของ pairwise ใน gcd's ในการตั้งค่าบางอย่างโดยใช้แผนผังผลิตภัณฑ์และต้นไม้ที่เหลือ แต่ฉันไม่รู้ว่ามันครอบคลุมปัญหาของคุณหรือไม่ O(nlgn)
DW

คุณเคยลองอะไรที่มีความสำคัญเป็นพิเศษหรือไม่?
Ryan

1
สมมติว่าตัวเลขทั้งหมดนั้นค่อนข้างดี แต่ยากที่จะแยกตัวประกอบ (เช่นแต่ละตัว si เท่ากับ piqi สำหรับช่วงเวลาที่แตกต่างกันขนาดใหญ่ pi,qi) ดูเหมือนยากที่จะหลีกเลี่ยงการตรวจสอบ GCD ตามเข็มนาฬิกาทั้งหมด บอกฉันว่าหลังจากตรวจสอบทุกคู่แล้ว(sn1,sn) GCD นั้นเป็นจำนวนเต็ม 1. คุณเดาได้ยังไงgcd(sn1,sn)โดยไม่ต้องคำนวณมัน?)
usul

ลิงก์ @usul DW นั้นเป็นปัญหานั้น คีย์เข้ารหัสจำนวนมากควรเป็นผลคูณของสองช่วงเวลาที่แตกต่างกัน แต่เราสงสัยว่าคีย์เข้ารหัสบางตัวมีปัจจัยสำคัญร่วมกัน (ซึ่งจะเป็น gcd ของทั้งสองคีย์ทำให้ทั้งสองเป็นเรื่องง่ายที่จะแยกปัจจัย) อัลกอริทึมนั้นให้คุณค้นหากุญแจที่มีปัจจัยร่วมโดยไม่ต้องคำนวณ n (n-1) / 2 gcd สำหรับ 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 ลองพิจารณาตัวอย่างชุด{2,4}โดยที่ GCD สูงสุดคือ 2
Yuval Filmus

@YuvalFilmus ทุกiที่เริ่มต้นด้วยmจนกว่า1เราจะตรวจสอบถ้าสองคนหรือมากกว่าหลายแห่งiอยู่ในชุด ใน exmaple นี้สองทวีคูณของ 2 อยู่ในชุด '2 และ 4` ดังนั้นคำตอบคือ 2. whileวงในจะตรวจสอบมวลทั้งหมดของiจนถึงm' as m` คือค่ามาสค์ของรายการ
Subhendu Ranjan Mishra

1
นี่เป็นอัลกอริธึมที่แย่มาก สำหรับอาร์เรย์ของตัวเลขสองจำนวนx,y ความยาว nบิตแต่ละการคำนวณ GCD ใช้เวลาพหุนามในขณะที่อัลกอริทึมของคุณใช้เวลาชี้แจงในกรณีที่เลวร้ายที่สุด (เมื่อตัวเลขค่อนข้างสำคัญ)
Yuval Filmus
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.