Score:2

ความซับซ้อนของเวลาของอัลกอริทึมการค้นหาแบบหมดจด

ธง in

ฉันมีชุด $S_1=\{2,10,20,6\}$ และ $S_2=\{25,26,20\}$ และฉันต้องการหาว่าตัวเลขใดรวมกันได้ 32 การตรวจสอบทำได้ง่ายมาก 6 และ 26 ดูเหมือนจะคล้ายกับปัญหาเป้ แต่ฉันไม่ใช่ผู้เชี่ยวชาญ

อย่างไรก็ตาม สมมติว่าฉันมี 1,000 ชุด โดยแต่ละชุดมีองค์ประกอบ 500 รายการ ซึ่งการบวกหนึ่งพจน์จากแต่ละชุดจะให้ค่าที่ไม่ซ้ำกันเสมอ สิ่งนี้ตรวจสอบและแก้ไขได้ยากกว่ามาก โดยเฉพาะอย่างยิ่งหากเซ็ตต่างๆ เป็นไปตามโครงสร้างที่ดูเหมือนสุ่ม (พวกมันจะถูกสร้างจากเซ็ตที่มีโครงสร้างที่ยุ่งเหยิง และแทบจะเป็นไปไม่ได้เลยที่จะคาดเดาการผสมและย้อนกลับของเซ็ต)

ดังนั้นวิธีเดียวจึงต้องเป็นอัลกอริทึมการค้นหาแบบหมดจด เนื่องจากหมายเลขของฉันคือ 52,485,332 จึงมี $1000^{500}$ ตัวเลือกที่เป็นไปได้ในการดู แน่นอนว่าจะมีวิธีในการทำให้การค้นหานี้สั้นลง (เช่น เมื่อชุดมีตัวเลขมากกว่าค่าเป้าหมายของคุณ คุณสามารถเพิกเฉยต่อตัวเลขเหล่านั้นได้) แต่อย่างอื่นคุณอาจจะยังดูอยู่ $750^{500}$ ทางเลือกที่เป็นไปได้

ดังนั้นความซับซ้อนของเวลาของอัลกอริทึมการค้นหาดังกล่าวคืออะไร? $O(n^{k})$, กับ $n$ จำนวนชุดและ $k$ จำนวนองค์ประกอบในชุดเหล่านั้น? พวกเขาต้องตรวจสอบการรวมกันของคำศัพท์ที่เป็นไปได้ "ทั้งหมด" จนกว่าจะตรงกับค่าที่กำหนด

คำถามหลักดูเหมือนจะเป็น "มีกี่ชุด" และ "ชุดใหญ่แค่ไหน". แท้จริงแล้วชุดสามารถมีขนาดต่างๆ ได้ทั้งหมด ไม่ใช่แค่ชุดเดียว

ฉันไม่ใช่คนเข้ารหัส การวิจัยของฉันเพียงแค่เจ้าชู้กับความคิดที่อยู่ในมือ ความช่วยเหลือใด ๆ ที่จะได้รับการชื่นชม

poncho avatar
my flag
"ดังนั้น วิธีเดียวที่จะต้องเป็นอัลกอริทึมการค้นหาแบบหมดจด" - อืมมม ไม่ แม้จะไม่มีโครงสร้างใดๆ ในค่า แต่ก็ยังมีวิธีการค้นหาที่มีประสิทธิภาพมากกว่าอย่างมาก สิ่งที่อยู่ในใจทันทีใช้เวลา $O(nm)$ (โดยที่ $m$ คือผลรวมเป้าหมาย ด้วย $m=52485332$ ซึ่งดูเหมือนจะแก้ไขได้จริง) คุณสนใจหรือคำถามของคุณเจาะจงเกี่ยวกับเวลาที่อัลกอริทึมการค้นหาไร้เดียงสาใช้หรือไม่
MeBadMaths avatar
in flag
@poncho ขอบคุณสำหรับความคิดเห็น ฉันไม่ทราบว่ามีวิธีการที่ดีกว่าวิธีการค้นหาที่ "ไร้เดียงสา" ฉันจะสนใจสิ่งที่คุณแนะนำ - อะไรก็ตามที่คุณสามารถแนะนำได้จะดีมาก
jjj avatar
cn flag
jjj
มีตัวเลือก 500^1000 ไม่ใช่ 1,000^500
Score:2
ธง my

ดังนั้นวิธีเดียวจึงต้องเป็นอัลกอริทึมการค้นหาแบบหมดจด

ดังที่ฉันได้กล่าวไว้ในความคิดเห็นของฉัน มีวิธีปฏิบัติสำหรับมูลค่าที่ไม่มากของ $m$ (และ $m=52485332$ ไม่ใหญ่โตนัก) ต่อไปนี้เป็นโครงร่างของวิธีการดังกล่าว (ซึ่งถือว่าชุดทั้งหมดประกอบด้วยจำนวนเต็มที่ไม่เป็นลบ):

  • เรามีอาร์เรย์ $A_{n, ม+1}$; แต่ละองค์ประกอบของอาร์เรย์ $A_{a, ข}$ จะสังเกตว่าเราสามารถสร้างผลรวมได้อย่างไร $ข$ จากครั้งแรก $a$ ชุด (หรือ $\perp$ ถ้ายังหาช่องทางนั้นไม่เจอ)

  • เริ่มต้นองค์ประกอบทั้งหมด $A$ ถึง $\perp$

  • สำหรับ $i := 1$ ถึง $n$ ค้นหาองค์ประกอบ $A_{i-1}$ สำหรับผู้ที่ไม่ใช่$\perp$ องค์ประกอบ (และสำหรับ $i=1$องค์ประกอบที่ 0 จะถือว่าเป็นองค์ประกอบเดียวที่ไม่ใช่$\perp$ ธาตุ. สำหรับแต่ละองค์ประกอบดังกล่าว $A_{i-1, x}$, ชุด $A_{i, x + S_{i,j}}$ ถึง $เจ$ (สำหรับแต่ละองค์ประกอบ $S_{i,j}$ ของชุด $S_i$) ถ้า $x + S_{i,j} > ม$ไม่สนใจมัน

  • สุดท้ายถ้า $A_{n,m} = \perp$ไม่มีเซตย่อยที่นำไปสู่ผลรวม $m$. หากเป็นอย่างอื่น เราสามารถกู้คืนเงื่อนไขได้โดยย้อนรอยผ่านอาร์เรย์ $A$.

นี่ควรเป็นอัลกอริทึมที่ใช้งานได้จริงสำหรับการกู้คืนเงื่อนไขตามพารามิเตอร์ที่คุณระบุไว้

jjj avatar
cn flag
jjj
ในคำถามระบุว่าผลรวมจะให้ค่าเฉพาะเสมอ ซึ่งหมายความว่ามีผลลัพธ์ที่แตกต่างกัน 1,000^500 รายการ ดังนั้นเราต้องถือว่าเรากำลังพูดถึง m ในขนาดนี้เช่นกัน อัลกอริทึมนี้จะ "ไม่" เสร็จสิ้น
poncho avatar
my flag
@jjj: คำถามยังระบุว่า "เนื่องจากหมายเลขของฉันคือ 52,485,332"; ฉันคิดว่าพวกเขากำลังแสดงมูลค่า $m$; ถ้าไม่ใช่ "หมายเลขของฉัน" คืออะไร
jjj avatar
cn flag
jjj
ฉันเดาว่าผู้เขียนคำถามไม่ทราบข้อเท็จจริงที่ว่าความไม่ซ้ำกันจะส่งผลให้ตัวเลขส่วนใหญ่ของชุดเพียงอย่างเดียวจะใหญ่กว่าผลรวมของพวกเขามาก และการลบออกจะช่วยลดปัญหาได้อย่างมาก
MeBadMaths avatar
in flag
ขอบคุณทั้งคำตอบและความคิดเห็นของคุณ ฉันไม่เชี่ยวชาญในรายละเอียดของการเข้ารหัส ดังนั้นขออภัยที่ทำให้โพสต์ของฉันเกิดความสับสน ความจริงที่ฉันคิดว่า 52,485,332 นั้น "ใหญ่" แสดงว่าฉันไม่รู้ ฮ่าๆ เพื่อชี้แจง; ชุดทั้งหมดเป็นจำนวนเต็มที่ไม่เป็นลบ การนำค่าจากแต่ละชุดมารวมกันจะรับประกันองค์ประกอบที่ไม่ซ้ำกันเสมอ
MeBadMaths avatar
in flag
โดย "หมายเลขของฉัน" ฉันหมายถึงคำที่ฉันเข้ารหัส (บางอย่างที่ฉันไม่ได้ระบุ - ขออภัย!) สมมติว่าฉันได้รับข้อความและเข้ารหัสผ่านชุดเหล่านี้ ผลลัพธ์ที่ได้คือ 52,485,332 (หรืออาจมากกว่านั้น!) งานของอัลกอริทึมการค้นหาคือการค้นหาค่าที่ไม่ซ้ำกันจากผลรวม 1,000 ชุดเพื่อสร้างตัวเลขนี้ จากนั้นคุณสามารถถอดรหัสข้อความได้ 1,000 ชุดทำหน้าที่เป็นกุญแจสาธารณะ ดังนั้น ถ้ามันแคร็กง่าย นั่นล่ะคือปัญหา หวังว่าจะช่วยได้ @jjj คุณช่วยอธิบายความคิดเห็นล่าสุดของคุณเพิ่มเติมได้ไหม ฉันไม่คิดว่าฉันติดตามขอโทษ
MeBadMaths avatar
in flag
@poncho ขอบคุณสำหรับอัลกอริทึม ฉันไม่คิดว่าฉันเข้าใจว่า T กลับหัวหมายถึงอะไร - ความรู้ด้านสัญกรณ์ของฉันเกี่ยวกับการเข้ารหัสเป็นพื้นฐานที่ดีที่สุด ฉันจะตรวจสอบอย่างละเอียดและดูว่าฉันสามารถเข้าใจส่วนที่เหลือได้หรือไม่
poncho avatar
my flag
@MeBadMaths: $\perp$ หมายถึง "ว่าง" นั่นคือ สัญลักษณ์ที่แตกต่างจากค่าที่ถูกต้องใดๆ ในแง่ C ให้คิดว่ามันเป็นตัวชี้ NULL...
MeBadMaths avatar
in flag
@poncho: ขอบคุณสำหรับคำชี้แจง ฉันรู้สึกว่าอัลกอริทึมนั้นคล้ายกับอัลกอริทึมการค้นหา Naïve ในแง่ที่ว่าคุณกำลังทำซ้ำผ่านชุดทั้งหมดและรวบรวมรายการของค่าที่เป็นไปได้จนถึงตอนนี้ที่สามารถสรุปได้ ถ้าผลรวมใดๆ มากเกินไป คุณก็หยุดมองมัน ในที่สุดคุณจะหยุดโฟกัสไปที่ค่าทั้งหมดยกเว้นค่าที่จะเท่ากับหรือน้อยกว่าค่าที่กำหนด ฉันคิดว่าข้อดีอย่างหนึ่งของอัลกอริทึมของคุณคือคุณไม่ได้ตรวจสอบค่าจนกว่าจะสิ้นสุด - ยกเว้นเพื่อเปรียบเทียบว่ามันใหญ่เกินไปหรือไม่
MeBadMaths avatar
in flag
คำถามที่ฉันมีคือ คุณต้องใช้กี่ชุด (ขนาดต่างๆ) เพื่อให้อัลกอริทึมนี้ใช้เวลานานเกินไป ตามที่ @jjj แนะนำ แม้ว่าคุณสามารถหยุดดูชุดที่ยุติธรรมได้ เพราะในที่สุดค่าจำนวนมากของตัวเลขจะใหญ่เกินไป ตัวอย่างเช่น หากตัวเลขที่เข้ารหัสของคุณอยู่กึ่งกลางของจำนวนที่สรุปได้ทั้งหมด ขั้นตอนแรกอาจดูที่ตัวเลข 250 เท่านั้น แต่แต่ละชุดจะเพิ่ม 250 จากชุดที่สอง จากนั้นจึงเพิ่ม 250 ในแต่ละชุดสำหรับ ชุดที่สาม ดูเหมือนว่ามันจะใหญ่ขึ้นในไม่ช้า? ถึงกระนั้นผมก็ยังประเมินความ "ใหญ่" ต่ำไปอยู่ดี ฮ่าๆ
poncho avatar
my flag
@MeBadMaths: อันที่จริง ข้อได้เปรียบที่แท้จริงของอัลกอริทึมของฉัน (เมื่อเทียบกับการค้นหาแบบบังคับเดรัจฉาน) คือหากมีหลายวิธีในการเข้าถึงผลรวมระดับกลาง สมมติว่ามี 1,000 วิธีที่แตกต่างกันในการเข้าถึงค่า 314,159 หลังจาก 42 ขั้นตอน กำลังดุร้ายจะคำนวณซ้ำโดยเริ่มจาก (314159,42) 1,000 ครั้ง; อัลกอริทึมของฉันจะทำเพียงครั้งเดียว
poncho avatar
my flag
@MeBadMaths: สำหรับวิธีทำให้ปัญหาเป็นไปไม่ได้สำหรับอัลกอริทึมของฉัน วิธีที่ชัดเจนที่สุดคือทำให้ m ใหญ่ขึ้นสำหรับ unbounded m ปัญหานี้จริง ๆ แล้วเป็น NP-hard อย่างไรก็ตาม กว่าจะเข้าสู่ช่วงที่ยากจริง ๆ ได้นั้น m ต้องใหญ่หลวงมาก...
MeBadMaths avatar
in flag
@poncho ฉันเชื่อว่าจะมีเพียง 1 วิธีหลังจาก 42 ขั้นตอนแรกที่จะไปถึง 314159 หากมีวิธีมากกว่านี้ ก็จะไม่มีชุดค่าผสมที่ไม่ซ้ำกันสำหรับผลรวมแต่ละรายการ แต่ฉันเห็นว่าอัลกอริทึมของคุณทำในสิ่งที่คุณระบุได้อย่างไร มันเป็นอัลกอริทึมที่ยอดเยี่ยมและคิดมาอย่างดี! ดีกว่าทุกอย่างที่ฉันทำได้ ฮ่าๆ ขอบคุณสำหรับคำชี้แจงเกี่ยวกับ $m$ ด้วย ฉันประเมินความหมายของคำว่า "มหาศาล" ต่ำไปจริงๆ
Score:1
ธง cn
jjj

นี่เป็นคำตอบเพิ่มเติมว่าเหตุใดผลรวมที่ไม่ซ้ำใครจึงส่งผลต่อขนาดอย่างมาก $52485332$ กลายเป็นเรื่องเล็กน้อย (เป็นวิธีที่จะใช้เวลานานสำหรับความคิดเห็น)

เมื่อผลรวมทั้งหมดต้องไม่ซ้ำกัน ผลรวมทั้งหมดจึงต้องเป็นจำนวนเต็มที่แตกต่างกัน เพราะมี $500^{1000}$ ผลรวมที่เป็นไปได้นอกจากนี้ยังมี $500^{1000}$ ผลลัพธ์จำนวนเต็มที่แตกต่างกันสำหรับสิ่งนั้น กรณีต่ำสุดจะเป็นจำนวนเต็มทั้งหมดจาก $0$ ถึง $500^{1000}-1$.

ตัวอย่างเช่น,

$S_1 = \{0, 1, 2, ..., 499\}$

$S_2 = \{0, 500, 1,000, ..., 249500\}$

$S_3 = \{0, 250000, 500000, ..., 124750000\}$

...

$S_{1000} = \{0, 500^{999}, 2*500^{999}, ..., 499*500^{999}\}$

จะเป็นวิธีที่รับประกันความเป็นเอกลักษณ์ของผลลัพธ์ อย่างที่คุณเห็น ตัวเลขเพิ่มขึ้นเร็วมากจริงๆ

ในตัวอย่างนี้ ง่ายต่อการค้นหาผลลัพธ์ (เพียงเลือกจำนวนที่มากที่สุดที่พอดีจากชุดสุดท้ายถึงชุดแรกเสมอ) แม้แต่ตัวเลขส่วนใหญ่ก็คือ $S_3$ มีค่ามากกว่า $52485332$ ดังนั้นจึงสามารถละเว้นได้

คุณอาจต้องการค่าที่ค่อนข้างสุ่มในชุดของคุณ ในกรณีนี้ ช่วงของค่าต้องมากกว่าเล็กน้อยเป็นอย่างน้อย

อย่างไรก็ตาม ไม่น่าเป็นไปได้อย่างยิ่งที่ค่าใดๆ จะต่ำกว่าหรือเท่ากับ $52485332$ (เมื่อคุณเลือกแบบเดียวกัน $500000$ ค่าออกจาก $500^{1000}$)

การเขียนโปรแกรมแบบไดนามิกตามที่ @poncho แนะนำนั้นใช้งานได้กับจำนวนน้อยเท่านั้น และประสิทธิภาพของมันก็ไม่ได้ดีไปกว่าการค้นหาแบบละเอียดถี่ถ้วน (ความแตกต่างเชิงเส้นในจำนวนชุด) เนื่องจากผลรวมย่อยที่สามารถนำมาใช้ซ้ำได้นั้นไม่ซ้ำกัน ข้อได้เปรียบ การไม่ดูความเป็นไปได้อย่างอื่นก็ไม่มี รันไทม์ควรเป็นลำดับเดียวกับการค้นหาแบบละเอียด การปรับปรุงเพียงอย่างเดียวคือต้องดำเนินการเมื่อค่ามีขนาดใหญ่หรือเล็กเพื่อบรรลุเป้าหมาย แต่สำหรับเป้าหมายที่สมเหตุสมผลนั้นไม่มีข้อได้เปรียบมากนัก

On สามารถลดปัญหาผลรวมย่อยหรือปัญหาเป้ได้อย่างง่ายดายเพียงแค่ใช้ชุดเดียวกันหลาย ๆ ครั้งตามจำนวนที่คุณต้องการรวมปัญหาของสิ่งนี้คือนี่ไม่ใช่มดลดเวลาพหุนาม ดังนั้นจึงไม่เพียงพอที่จะพิสูจน์ว่าปัญหาคือ NP ยากหรือไม่

MeBadMaths avatar
in flag
ขอบคุณสำหรับการตอบสนอง ตัวอย่างของชุดที่คุณให้มานั้นเป็นชุดที่ผมรู้จักดีและเป็นชุดพื้นฐานที่สุดของชุดเหล่านี้ แต่จากตรงนั้น คุณสามารถ "ยุ่งเหยิง" การตั้งค่านี้ในลักษณะที่ไม่สามารถกู้คืนได้ทั้งหมดโดยไม่มีข้อมูลเพิ่มเติม (คีย์ส่วนตัว) ชุดที่ "ยุ่งเหยิง" ที่เกิดขึ้นจะดูสุ่มและจะสร้างชุดที่หลากหลาย ฉันยอมรับว่า 52485332 ที่ให้มานั้นเล็กเกินไป - คิดไม่ถึงจริงๆ ฮ่าๆ แต่บอกว่าค่าของฉันมีขนาดเพียงพอที่ติดตามอย่างถูกต้องด้วยชุด "สุ่ม" - ฉันคิดว่านั่นทำให้ปัญหานี้แก้ไขได้ยากขึ้น?
jjj avatar
cn flag
jjj
@MeBadMaths จำนวนวิธีที่จะทำให้สิ่งนี้ยุ่งเหยิงค่อนข้างจำกัด (ถ้าเป็นไปได้เลย) ตัวอย่างเช่น เมื่อคุณแยก {0, 1, 2, 3, 0, 4, 8, 12} (โครงสร้างเดียวกันตัวอย่างที่เล็กกว่า) ออกเป็นสองชุดที่มีขนาด 4 จะมีวิธีเดียวเท่านั้นที่จะทำสิ่งนี้ได้ (ละเว้นลำดับของชุดและ สั่งซื้อภายในชุด)
MeBadMaths avatar
in flag
เป็นไปได้ที่จะ "ยุ่งเหยิง" การตั้งค่าเหล่านี้ แต่มันจะใหญ่ขึ้นเรื่อย ๆ เมื่อคุณได้รับค่าที่มากขึ้นเรื่อย ๆ ให้ $N=\prod_{j=1}^n |S_{j}|$ แล้วหา $d>N$ หา $r$ โดยที่ $r$ และ $d$ เป็น co-prime และหา $0\leq t_1,t_2,\dots,t_n
jjj avatar
cn flag
jjj
@MeBadMaths โอเค ถูกต้อง ฉันคิดว่าคุณแค่ต้องการเปลี่ยนองค์ประกอบ ไม่ใช่แก้ไข ฉันตรวจสอบแล้วว่าสูตรของคุณมีอยู่และไม่สามารถแยกความแตกต่างจากค่าสุ่มได้ ฉันจะปรับส่วนสุดท้ายของคำตอบของฉัน
MeBadMaths avatar
in flag
ขอบคุณสำหรับความคิดเห็นและคำตอบทั้งหมดของคุณ - และขออภัยสำหรับคำอธิบายที่ไม่ดีของฉัน ฉันไม่เคยใช้ฟอรัมเหล่านี้มาก่อน ดังนั้นฉันจึงยังใหม่กับวิธีการจัดรูปแบบคำถาม ฯลฯ ฉันขอขอบคุณสำหรับการสนับสนุนของคุณ ไม่ต้องการพิสูจน์ NP แน่นอน ฮ่าๆ การป้อนข้อมูลของคุณช่วยได้ คำถามสุดท้ายจะเป็น; ลำดับของการค้นหาที่ครอบคลุม $O(n^k)$ ตามที่ฉันคิดไว้ในโพสต์ของฉัน หรือ $O(k^n)$ หรือเป็นอย่างอื่น? ขอขอบคุณอีกครั้ง
jjj avatar
cn flag
jjj
ฉันอยากจะบอกว่ามันไม่เพียงพอที่จะพิสูจน์ว่าปัญหานี้ NP ยาก ^^. การค้นหาอย่างละเอียดถี่ถ้วนจะเป็น O(k^n) (องค์ประกอบ k ทุกตัวในชุดที่ 1 สามารถรวมกับองค์ประกอบ k ทุกตัวในชุดที่ 2...)
MeBadMaths avatar
in flag
ใช่ มันสมเหตุสมผลมากกว่า $n^k$ ฉันได้อ่านหน้า wiki เกี่ยวกับ Time Complexity และฉันไม่สามารถบอกได้ว่า $O(k^n)$ เป็นเวลาพหุนามหรือเวลาเอกซ์โพเนนเชียล (หรือไม่ก็ได้!) ฉันสาบานว่านี่เป็นคำถามสุดท้าย ฮ่าฮ่าฮ่า ขอบคุณสำหรับความช่วยเหลือของคุณ @jjj

โพสต์คำตอบ

คนส่วนใหญ่ไม่เข้าใจว่าการถามคำถามมากมายจะปลดล็อกการเรียนรู้และปรับปรุงความสัมพันธ์ระหว่างบุคคล ตัวอย่างเช่น ในการศึกษาของ Alison แม้ว่าผู้คนจะจำได้อย่างแม่นยำว่ามีคำถามกี่ข้อที่ถูกถามในการสนทนา แต่พวกเขาไม่เข้าใจความเชื่อมโยงระหว่างคำถามและความชอบ จากการศึกษาทั้ง 4 เรื่องที่ผู้เข้าร่วมมีส่วนร่วมในการสนทนาด้วยตนเองหรืออ่านบันทึกการสนทนาของผู้อื่น ผู้คนมักไม่ตระหนักว่าการถามคำถามจะมีอิทธิพลหรือมีอิทธิพลต่อระดับมิตรภาพระหว่างผู้สนทนา