จำนวนสูงสุดของสตริงย่อยที่ไม่ซ้ำกันจากพาร์ติชัน


30

ฉันแก้ไขชื่อเพื่อให้เข้าใจได้ง่ายขึ้น

นี่คือคำถามรุ่นโดยละเอียด:

เรามีสตริงs และต้องการที่จะแยกไว้ในสตริง สตริงย่อยแต่ละอันจะแตกต่างจากกัน จำนวนสูงสุดของซับสเตรทเฉพาะที่เรามีได้จากการตัดหนึ่งครั้ง ในคำอื่น ๆ สิ่งที่เป็นจำนวนสูงสุดของสตริงที่ไม่ซ้ำกันที่ concatenate sไปยังแบบฟอร์ม

นี่คือตัวอย่างบางส่วน:

Example 1
s = 'aababaa'
output = 4
Explain: we can split `s` into aa|b|aba|a or aab|a|b|aa, 
         and 4 is the max number of substrings we can get from one split.

Example 2
s = 'aba'
output = 2
Explain: a|ba

Example 3
s = 'aaaaaaa'
output = 3
Explain: a|aa|aaaa

หมายเหตุ : sมีอักขระตัวพิมพ์เล็กเท่านั้น ฉันไม่ได้บอกว่าจะต้องใช้เวลานานเท่าใดsจึงไม่สามารถคาดเดาความซับซ้อนของเวลาที่เหมาะสมได้ :(

มันเป็นปัญหาที่หนักหน่วงหรือไม่? ถ้าไม่ฉันจะแก้ไขได้อย่างมีประสิทธิภาพได้อย่างไร

ฉันได้ยินปัญหานี้จากเพื่อนคนหนึ่งของฉันและไม่สามารถตอบได้ ฉันพยายามใช้ Trie + โลภเพื่อแก้ปัญหานี้ วิธีการล้มเหลวสำหรับตัวอย่างแรก

นี่คือวิธีแก้ปัญหา Trie ที่ฉันมาด้วย:

def triesolution(s):
    trie = {}
    p = trie
    output = 0
    for char in s:
        if char not in p:
            output += 1
            p[char] = {}
            p = trie
        else:
            p = p[char]
    return output

ตัวอย่างที่ 1 โค้ดข้างต้นจะกลับ 3 เพราะมันเป็นความพยายามที่จะแยกออกเป็นsa|ab|abaa

เพิ่ม:ขอบคุณความคิดของทุกคนดูเหมือนว่าปัญหานี้ใกล้เคียงกับปัญหา NP มาก ตอนนี้ฉันกำลังพยายามคิดจากทิศทางนี้ Guess(n)สมมติว่าเรามีฟังก์ชั่น ฟังก์ชั่นนี้จะกลับมาTrueถ้าเราสามารถหาวัสดุพิมพ์ที่nไม่ซ้ำกันจากหนึ่งแยกหรือFalseอย่างอื่น หนึ่งสังเกตที่นี่คือว่าถ้าGuess(n) == Trueแล้วทั้งหมดGuess(i) == True i <= nเนื่องจากเราสามารถรวมสองสตริงย่อยที่อยู่ติดกันเข้าด้วยกัน การสังเกตนี้สามารถนำไปสู่การแก้ปัญหาแบบไบนารี อย่างไรก็ตามมันยังต้องการให้เราสามารถคำนวณGuessฟังก์ชันได้อย่างมีประสิทธิภาพ Guess(n)น่าเศร้าที่ฉันยังไม่สามารถหาวิธีพหุนามในการคำนวณ


คนแรกยังสามารถแยกaab|a|b|aaซึ่งยังคงเป็น 4
smac89

3
ความอยากรู้ของคุณจะได้นานแค่ไหน?
templatetypedef

aababaa สามารถแบ่งออกเป็น a | aa | aab | aaba | aabab | aababa | aba | ... และอื่น ๆ คุณได้รับเพียง 4 ได้อย่างไร
Suraj Motaparthy

สตริงมีเพียงaหรือb?
Pham Trung

@PhamTrung ไม่ แต่คุณสามารถสันนิษฐานได้ว่ามันมีตัวอักษรพิมพ์เล็กเท่านั้น
wqm1800

คำตอบ:


15

สิ่งนี้เรียกว่าปัญหาเกี่ยวกับพาร์ทิชันสตริงการชนกันของข้อมูลและแสดงให้เห็นว่า NP-complete โดยการลดลงจาก 3-SAT ในกระดาษโดย Anne Condon, JánMaňuchและ Chris Thachuk - ความซับซ้อนของปัญหาพาร์ทิชันสตริงที่เกิดการชนกันและ ความสัมพันธ์กับการออกแบบโอลิโกเพื่อการสังเคราะห์ยีน ( International Computing and Combinatorics Conference , 265-275, 2008)


ฉันดูคร่าวๆเกี่ยวกับกระดาษแผ่นนั้นและดูเหมือนว่าผลลัพธ์ที่พิสูจน์มีเพียงแสดงว่าปัญหานี้เป็นปัญหาที่เกิดขึ้นยากในกรณีที่มีการ จำกัด จำนวนอักขระที่สามารถอยู่ในแต่ละสตริงย่อยได้ ถูกต้องหรือไม่ ถ้าเป็นเช่นนั้นนั่นทำให้แตกต่างจากปัญหานี้เล็กน้อย การใช้เหตุผลโดยการเปรียบเทียบการค้นหา MST สามารถทำได้ในเวลาพหุนามแม้ว่าปัญหาของ "การหา MST ภายใต้ข้อ จำกัด ระดับบนโหนดในต้นไม้" คือ NP-hard
templatetypedef

1
เพื่อแสดงให้เห็นว่าปัญหานี้คือปัญหา NP-hard เราจำเป็นต้องสามารถลดปัญหา NP-hard ที่รู้จัก (การแบ่งพาร์ติชัน k) ให้เป็นปัญหานี้ได้ (การแบ่งพาร์ติชันแบบไม่มีข้อ จำกัด ) แทนที่จะเป็นวิธีอื่น ตัวแก้ปัญหาสำหรับการแบ่งพาร์ติชัน k สามารถแก้ปัญหานี้ได้อย่างแน่นอน แต่นั่นไม่ได้พิสูจน์ความกระด้างของ NP
templatetypedef

ฉันไม่เห็นว่ากระดาษแก้ปัญหา: ตามที่ฉันเข้าใจว่ามันเป็นกระดาษเกี่ยวกับการตัดสินใจปัญหาหากมีพาร์ทิชันที่มีอยู่ในสารตั้งต้นที่มีความยาวมากที่สุด k หาก k มีค่ามากกว่าครึ่งหนึ่งของความยาวสตริงทั้งหมดที่ปัญหาการตัดสินใจเป็นจริงเล็กน้อย (ดังที่ฉันเข้าใจ)
ฮันส์โอลส์สัน

ไม่ความจริงที่ว่าปัญหามีวิธีแก้ปัญหาเล็กน้อยสำหรับ k ขนาดใหญ่ไม่ได้หมายความว่า k จะต้องมีขนาดเล็กและการลดลงจะได้ผล
templatetypedef

8

(ขอบคุณ Gilad Barkan มาก (גלעדברקן) ที่ทำให้ฉันตระหนักถึงการสนทนานี้)

ให้ฉันแบ่งปันความคิดของฉันเกี่ยวกับปัญหานี้จากมุมมองทางทฤษฎีล้วนๆ (โปรดทราบว่าฉันยังใช้ "factor" แทน "subword")

ฉันคิดว่าคำจำกัดความที่เป็นทางการเพียงพอของปัญหา (หรือปัญหา) ที่พิจารณาที่นี่คือต่อไปนี้:

เมื่อได้คำแล้วให้ค้นหาคำว่า u_1, u_2, ... , u_k แบบนั้น

  • u_i! = u_j สำหรับทุก ๆ i, j ที่มี 1 <= i <j <= k และ
  • u_1 u_2 ... u_k = w

ชุดตัวแปรสูงสุด (เราต้องการ u_i หลายตัว): เพิ่ม k

ตัวแปรลดขนาด (เราต้องการ u_i สั้น): ย่อขนาดสูงสุด {| u_i | : 1 <= i <= k}

ปัญหาเหล่านี้กลายเป็นปัญหาในการตัดสินใจโดยการให้ B ที่ถูกผูกไว้ซึ่งตามที่เรากำลังพูดถึง "หลายปัจจัย" - ตัวแปรหรือ "ปัจจัยสั้น" - แปรปรวนเป็นขอบเขตล่างบน k (เราต้องการอย่างน้อย B ปัจจัย) หรือขอบเขตบนสูงสุด {| u_i | : 1 <= i <= k} (เราต้องการตัวคูณความยาวไม่เกิน B) ตามลำดับ สำหรับการพูดคุยเกี่ยวกับความกระด้าง NP เราจำเป็นต้องพูดถึงปัญหาการตัดสินใจ

ลองใช้คำว่า SF สำหรับ "ปัจจัยระยะสั้น" - ตัวแปรและ MF สำหรับ "ปัจจัยหลายอย่าง" - ตัวแปร โดยเฉพาะอย่างยิ่งและนี่คือจุดสำคัญจริง ๆ ปัญหาถูกกำหนดในลักษณะที่เราได้คำเหนือตัวอักษรบางตัวที่ไม่ถูก จำกัด รุ่นของปัญหาคือเรารู้เบื้องต้นว่าเราป้อนเฉพาะคำพูดพูดตัวอักษร {a, b, c, d} เป็นปัญหาอื่น! NP-hardness ไม่ได้ดำเนินการโดยอัตโนมัติจาก "ไม่ จำกัด " ถึง "ตัวอักษรคงที่" ตัวแปร (หลังอาจง่ายกว่า)

ทั้ง SF และ MF เป็นปัญหาที่สมบูรณ์แบบของ NP สิ่งนี้แสดงใน [1, 1b] และ [2] ตามลำดับ (ตามที่ Gilad ได้ชี้ไปแล้ว) ถ้าฉันเข้าใจคำนิยามปัญหาอย่างไม่เป็นทางการที่นี่ในตอนต้นของการสนทนานี้อย่างถูกต้องแสดงว่าปัญหาของการสนทนานี้เป็นปัญหา MF อย่างแท้จริง ในตอนแรกมันไม่ได้กล่าวถึงว่าคำที่ถูก จำกัด ให้มาจากตัวอักษรคงที่บางส่วนในภายหลังมีการกล่าวกันว่าเราสามารถสันนิษฐานได้ว่ามีการใช้ตัวอักษรตัวพิมพ์เล็กเท่านั้น หากนี่หมายความว่าเราจะพิจารณาเฉพาะคำที่ใช้ตัวอักษรคงที่ {a, b, c, ... , z} ดังนั้นสิ่งนี้จะเปลี่ยนไปมากในแง่ของความกระด้าง NP

การมองอย่างใกล้ชิดเผยให้เห็นความแตกต่างของความซับซ้อนของ SF และ MF:

  1. paper [1, 1b] แสดงให้เห็นว่า SF ยังคง NP สมบูรณ์ถ้าเรากำหนดตัวอักษรให้เป็นเลขฐานสอง (แม่นยำยิ่งขึ้น: ได้คำด้วยตัวอักษร a และ b และขอบเขต B) เราสามารถแยกตัวประกอบในความยาวที่แตกต่างกันได้ที่ มากที่สุด B?)
  2. กระดาษ [1, 1b] แสดงให้เห็นว่า SF ยังคงสมบูรณ์ NP หากเราแก้ไขขอบเขต B = 2 (แม่นยำยิ่งขึ้น: ได้คำ w เราสามารถแยกตัวประกอบในความยาวแตกต่างกันได้ไม่เกิน 2)
  3. paper [3] แสดงให้เห็นว่าหากทั้งตัวอักษรและขอบเขต B ได้รับการแก้ไขแล้ว SF สามารถแก้ไขได้ในเวลาพหุนาม
  4. กระดาษ [2] แสดงว่า MF นั้นสมบูรณ์แล้ว แต่ถ้าตัวอักษรไม่ได้ถูก จำกัด หรือคงที่มาก่อน! โดยเฉพาะอย่างยิ่งมันไม่ได้ตอบคำถามหากปัญหานั้นเกิดจากปัญหา NP-complete ถ้าเราพิจารณาเพียงแค่ใส่คำศัพท์ที่มีตัวอักษรตายตัวบางตัวเท่านั้น (ตามปกติในกรณีของการตั้งค่าภาคปฏิบัติ)
  5. กระดาษ [3] แสดงให้เห็นว่า MF สามารถแก้ไขได้ในเวลาพหุนามหากขอบเขต B ถูก จำกัด ขอบเขตบนอีกครั้งโดยค่าคงที่เช่นปัญหาอินพุตคือคำและขอบเขต B จาก {1, 2, ... , K} ที่ K คือค่าคงที่คงที่

ความคิดเห็นบางส่วนเกี่ยวกับผลลัพธ์เหล่านี้: Wrt (1) และ (2) เป็นที่ชัดเจนโดยสัญชาตญาณว่าถ้าตัวอักษรเป็นเลขฐานสองดังนั้นเพื่อทำให้ปัญหา SF ยากลำบากขอบเขต B ก็ไม่สามารถแก้ไขได้เช่นกัน ในทางกลับกันการแก้ไข B = 2 หมายความว่าขนาดตัวอักษรจะต้องมีขนาดค่อนข้างใหญ่เพื่อผลิตอินสแตนซ์ที่ยาก ผลที่ตามมาคือ (3) ค่อนข้างเล็กน้อย (ในความเป็นจริง [3] พูดได้มากกว่านี้เล็กน้อย: เราสามารถแก้ไขได้ในเวลาทำงานไม่เพียง แต่พหุนาม แต่ยัง | w | ^ 2 เท่าของปัจจัยที่ขึ้นอยู่กับขนาดตัวอักษรเท่านั้น และ B) (5) ก็ไม่ยากเช่นกัน: ถ้าคำของเรายาวเมื่อเทียบกับ B เราจะได้การแยกตัวประกอบที่ต้องการเพียงแค่ตัดเป็นปัจจัยที่มีความยาวต่างกัน ถ้าไม่เช่นนั้นเราสามารถบังคับความเป็นไปได้ทั้งหมดซึ่งเป็นเลขชี้กำลังใน B เท่านั้นซึ่งในกรณีนี้ถือว่าเป็นค่าคงที่

ภาพที่เรามีดังต่อไปนี้: SF ดูยากขึ้นเพราะเรามีความแข็งแม้สำหรับตัวอักษรคงที่หรือสำหรับการแก้ไขค่าคงที่ B ปัญหา MF ในทางกลับกันได้รับโพลีเวลาแก้ไขถ้าขอบเขตถูกแก้ไข (ใน เรื่องนี้มันง่ายกว่า SF) ในขณะที่คำถามที่สอดคล้องกัน WRT ขนาดตัวอักษรเปิดอยู่ ดังนั้น MF จึงมีความซับซ้อนน้อยกว่า SF เล็กน้อยแม้ว่า MF จะเป็นตัวอักษรตายตัวก็ตาม อย่างไรก็ตามหากสามารถแสดงให้เห็นว่า MF สามารถแก้ไขได้สำหรับตัวอักษรคงที่ในโพลี - เวลานั้น MF จะแสดงได้ง่ายกว่า SF ... เพราะกรณีหนึ่งซึ่งยากจะค่อนข้างประดิษฐ์ (ตัวอักษรไม่ จำกัด !) .

ฉันใช้ความพยายามในการแก้ไขกรณีของ MF ด้วยตัวอักษรที่มีขอบเขต แต่ฉันไม่สามารถชำระและหยุดทำงานตั้งแต่นั้น ฉันไม่เชื่อว่านักวิจัยคนอื่น ๆ พยายามอย่างหนักในการแก้ปัญหานี้ (ดังนั้นนี่ไม่ใช่หนึ่งในปัญหาการเปิดที่ยากมากเหล่านี้หลายคนพยายามแล้วและล้มเหลวฉันคิดว่ามันเป็นไปได้) ฉันเดาว่ามันเป็น NP-hard สำหรับตัวอักษรคงที่ แต่บางทีการลดลงนั้นซับซ้อนจนคุณจะได้รับบางอย่างเช่น "MF นั้นยากสำหรับตัวอักษรขนาด 35 หรือใหญ่กว่า" หรือบางสิ่งบางอย่างซึ่งอาจไม่ดีอย่างยิ่ง .

เกี่ยวกับวรรณคดีเพิ่มเติมฉันรู้กระดาษ [4] ซึ่งพิจารณาปัญหาการแยกคำ w เป็นปัจจัยที่แตกต่างกัน u_1, u_2, ... , u_k ที่เป็น palindromes ทั้งหมดซึ่งเป็นปัญหา NP-Complete

ฉันมองกระดาษ [5] โดย Gilad ชี้ให้เห็น ดูเหมือนว่าจะพิจารณาการตั้งค่าที่แตกต่างกันแม้ว่า ในบทความนี้ผู้เขียนมีความสนใจในคำถาม combinatorial ว่าเรียงความหรือ subwords ที่แตกต่างกันสามารถมีอยู่ในคำที่กำหนด แต่สิ่งเหล่านี้สามารถทับซ้อนกัน ตัวอย่างเช่น aaabaab มี 20 subwords ต่างกัน a, b, aa, ab, ba, bb, aaa, aab, aba, baa, aaab, aaba, ababa, baab, aaaba, aabaa, aabaab, aaabaa, aaabaab (อาจเป็นฉัน miscounted แต่คุณได้รับความคิด) บางส่วนของพวกเขามีเหตุการณ์เดียวเท่านั้นเช่นบาอาบางคนมีหลายอย่างเช่นเอเอ ไม่ว่าในกรณีใด ๆ คำถามไม่ได้เป็นวิธีที่เราสามารถแยกคำเพื่อให้ได้ปัจจัยที่แตกต่างกันอย่างใดอย่างหนึ่งเนื่องจากนี่หมายความว่าสัญลักษณ์แต่ละบุคคลมีส่วนร่วมในปัจจัยเดียว

เกี่ยวกับการแก้ปัญหาในทางปฏิบัติสำหรับปัญหาประเภทนี้ (โปรดจำไว้ว่าฉันเป็นนักทฤษฎีดังนั้นให้นำสิ่งนี้ไปด้วยเม็ดเกลือ):

  • สำหรับความรู้ของฉันไม่มีขอบเขตทางทฤษฎีที่ต่ำกว่า (เช่น NP-กระด้าง) ที่จะออกกฎเพื่อแก้ปัญหา MF ในเวลาพหุนามถ้าเราพิจารณาเพียงคำที่ใส่ตัวอักษรคงที่ มีข้อแม้อยู่ข้อหนึ่ง: ถ้าคุณได้รับอัลกอริธึมแบบโพลี - ไทม์ดังนั้นสิ่งนี้ควรรันเป็นเลขชี้กำลังแทนจำนวนในสัญลักษณ์จากตัวอักษรคงที่ (หรือเลขยกกำลังในฟังก์ชันบางอย่างของมัน) มิฉะนั้นจะเป็นอัลกอริธึมเวลาพหุนามสำหรับกรณีของตัวอักษรที่ไม่มีขอบเขต ดังนั้นในฐานะที่เป็นนักทฤษฎีฉันจะมองหางานอัลกอริทึมที่สามารถคำนวณได้ในเวลาแบบเลขชี้กำลังหากจำนวนของสัญลักษณ์และวิธีใดก็ตามที่ช่วยในการคิดอัลกอริทึมสำหรับ MF ในทางกลับกันมันอาจเป็นไปได้ว่าอัลกอริธึมดังกล่าวไม่มีอยู่และ MF ก็ยากเช่นกันในกรณีตัวอักษรคงที่

  • หากคุณมีความสนใจในการแก้ปัญหา pratical มันอาจจะเป็นประโยชน์ในการแก้ปัญหาโดยประมาณ ดังนั้นการรับตัวประกอบที่รับประกันว่าจะมีขนาดใหญ่เพียงครึ่งเดียวเท่าที่ดีที่สุดในกรณีที่เลวร้ายที่สุดจะไม่เลวร้ายเกินไป

  • การวิเคราะห์พฤติกรรมซึ่งไม่ได้ให้ค่าประมาณที่พิสูจน์ได้ แต่การทำงานได้ดีในสภาพแวดล้อมจริงก็น่าสนใจเช่นกัน

  • การแปลงอินสแตนซ์ปัญหาเป็น SAT หรือ ILP- อินสแตนซ์ไม่ควรยากเกินไปจากนั้นคุณสามารถเรียกใช้ SAT หรือ ILP-Solver เพื่อรับโซลูชันที่ดีที่สุด

  • ความเห็นส่วนตัวของฉันคือแม้ว่ามันจะไม่รู้ว่ากรณีตัวอักษรตายตัวของ MF นั้นเป็นปัญหาหนักหน่วง แต่ก็มีความเข้าใจในเชิงทฤษฎีมากพอที่ชี้ให้เห็นว่าปัญหานั้นยากพอที่จะหาวิธีแก้ปัญหาแบบแก้ปัญหาได้ ฯลฯ ทำงานได้ดีในสภาพแวดล้อมจริง


บรรณานุกรม:

[1] แอน Condon, Ján Manuch, Chris Thachuk: ความซับซ้อนของการแบ่งสตริง J. ขั้นตอนวิธีแบบไม่ต่อเนื่อง 32: 24-43 (2015)

[1b] แอนน์คอนดอน, จานานนุช, คริสธัคุก: ความซับซ้อนของปัญหาการแบ่งส่วนรู้รอบและความสัมพันธ์กับการออกแบบ Oligo สำหรับการสังเคราะห์ยีน COCOON 2008: 265-275

[2] Henning Fernau, Florin Manea, Robert Mercas, Markus L. Schmid: การจับคู่รูปแบบกับตัวแปร: อัลกอริทึมที่รวดเร็วและผลลัพธ์ความแข็งแบบใหม่ STACS 2015: 302-315

[3] Markus L. Schmid: การคำนวณตัวคูณสตริงที่ไม่เท่าเทียมกันและซ้ำซ้อน theor คอมพิวเต วิทย์ 618: 42-51 (2559)

[4] Hideo Bannai, Travis Gagie, Shunsuke Inenaga, Juha Kärkkäinen, Dominik Kempa, Marcin Piatkowski, Shiho Sugimoto: การแยกตัวประกอบ Palindromic ที่หลากหลายคือ NP-Complete int พบเจ คอมพิวเต วิทย์ 29 (2): 143-164 (2018)

[5] Abraham Flaxman, Aram Wettroth Harrow, Gregory B. Sorkin: สตริงที่มีผลสืบเนื่องและ substrings ที่แตกต่างกันมากที่สุด และอิเล็กทรอ J. หวี 11 (1) (2004)


(ขอบคุณสำหรับการโพสต์โดยวิธี!) เพียงชี้แจงความคิดเห็นของฉันข้างต้นเกี่ยวกับการอ้างอิง [5] เป็นจริงเกี่ยวกับคำถามที่แตกต่าง - มันเป็นการตอบสนองต่อคำถาม LukStorms ในส่วนความคิดเห็นหลัก "สำหรับสตริงของ N ใด ๆ ความยาวของอักขระที่เป็นไปได้ของ P สตริงย่อยที่ไม่ซ้ำกันสูงสุดที่สตริงดังกล่าวควรมีมีเท่าไหร่ "
גלעדברקן

3

นี่เป็นวิธีแก้ปัญหา แต่มันก็ระเบิดเร็วมากและไม่ได้อยู่ใกล้กับโซลูชันที่มีประสิทธิภาพ ก่อนจะแบ่งสตริงลงในรายการของสตริงย่อยที่ไม่ซ้ำกันโดยไม่ต้องกังวลในการสั่งซื้อจากนั้นพยายามใช้ itertools.permutation เพื่อรวมสตริงย่อยเหล่านั้นกลับเข้าไปในสตริงเดิมโดยทดสอบการเรียงสับเปลี่ยนของ EACH เพื่อดูว่าตรงกับสตริงต้นฉบับหรือไม่

import itertools as it

def splitter(seq):                                                             
    temp = [seq]
    for x in range(1, len(seq)):
        print(seq[:x], seq[x:])
        temp.append(seq[:x])
        temp.append(seq[x:])
    return temp

if __name__ == "__main__":
    test = input("Enter a string: ")
    temp = splitter(test)
    copy = temp[::]
    condition = True
    for x in temp:
        if len(x) > 1:
            copy.extend(splitter(x))
    copy = sorted(list(set(copy)))
    print(copy)
    count = []
    for x in range(len(test)):
        item = it.permutations(copy, x)
        try:
            while True:
                temp = next(item)
                if "".join(list(temp)) == test:
                    if len(temp) == len(set(temp)):
                        count.append((len(temp), temp))
        except StopIteration:
            print('next permutation begin iteration')
            continue
    print(f"All unique splits: {count}")
    print(f"Longest unique split : {max(count)[0]}")

สำหรับการทดสอบครั้งแรกเราได้สิ่งนี้:

All unique splits: [(1, ('aababaa',)), (2, ('a', 'ababaa')), (2, ('aa', 'babaa')), (2, 
('aab', 'abaa')), (2, ('aaba', 'baa')), (2, ('aabab', 'aa')), (2, ('aababa', 'a')), (3, 
('a', 'ab', 'abaa')), (3, ('a', 'aba', 'baa')), (3, ('a', 'abab', 'aa')), (3, ('aa', 'b',
 'abaa')), (3, ('aa', 'ba', 'baa')), (3, ('aa', 'baba', 'a')), (3, ('aab', 'a', 'baa')),
 (3, ('aab', 'ab', 'aa')), (3, ('aab', 'aba', 'a')), (3, ('aaba', 'b', 'aa')), (3,
 ('aaba', 'ba', 'a')), (4, ('a', 'aba', 'b', 'aa')), (4, ('aa', 'b', 'a', 'baa')), (4,
 ('aa', 'b', 'aba', 'a')), (4, ('aab', 'a', 'b', 'aa'))]
Longest unique split : 4

บางทีสิ่งนี้สามารถปรับให้เหมาะสม แต่อย่างใด แต่มันใช้เวลาสักครู่ในเครื่องนี้


3

ฉันให้ปัญหานี้ลองและคิดในแง่หรือว่าจะทำให้พาร์ทิชันที่ดัชนีที่กำหนด ดังนั้นฟังก์ชั่นนี้จะเรียกซ้ำและสร้าง 2 สาขาในแต่ละดัชนี 1 อย่าทำพาร์ติชั่นที่ดัชนีฉัน 2 พาร์ติชั่นที่ดัชนีฉัน

ขึ้นอยู่กับพาร์ติชันที่ฉันกรอกข้อมูลในชุดแล้วส่งคืนขนาดของชุด

def max(a,b):
    if a>b: return a
    return b



def keep(last, current, inp, map):
    # print last
    # print current
    # print map

    if len(inp) == 2 :
        if inp[0]==inp[1]: return 1
        return 2

    if current >= len(inp):
        return len(map)
    // This is when we are at the start of the string. 
    // In this case we can only do one thing not partition and thus take the entire string as a possible string.

    if current == last :
        map11 = map.copy()
        map11.add(inp[current:])
        return keep(last, current + 1, inp, map11)

    map1 = map.copy();
    if current != (len(inp)-1):
        map1.add(inp[last:current])

    map2 = map.copy()

    return max(keep(last,current+1,inp, map2), keep(current, current+1, inp, map1))

print keep(0,0,"121", set([]))
print keep(0,0,"aaaaaaa", set([]))
print keep(0,0,"aba", set([]))
print keep(0,0,"aababaa", set([]))
print keep(0,0,"21", set([]))
print keep(0,0,"22", set([]))

https://onlinegdb.com/HJynWw-iH


ขอบคุณสำหรับการแก้ปัญหาของคุณ! โซลูชัน DFS นี้ชัดเจนมาก ฉันมีข้อเสนอแนะเล็กน้อยสามารถเร่งkeepฟังก์ชั่นได้เนื่องจากset.copy()ฟังก์ชั่นใช้เวลานานมาก วิธีการเกี่ยวกับการใช้การย้อนรอยซึ่งเมื่อเสร็จสิ้นฟังก์ชั่นสแต็คนี้ให้ลบผู้สมัครปัจจุบันออกจากชุด?
wqm1800

@ wqm1800 คุณช่วยกรุณาทำอย่างละเอียดฉันขอโทษฉันไม่เข้าใจว่า แม้ว่าเราจะใช้ backtrack เราก็ยังต้องmergeแยกฉากออกจากกันเนื่องจากเราแยกตัวอยู่เสมอ ดังนั้นทั้งการรวมหรือคัดลอก คุณสามารถทำอย่างละเอียด?
Ravi Chandak

1
นี่คือย้อนรอยของฉันวิธีการแก้ปัญหา สิ่งนี้สามารถใช้งานได้เนื่องจากฟังก์ชันสแต็กดำเนินการเป็นวิธี DFS ดังนั้นเมื่อฟังก์ชั่นเสร็จสิ้นก็หมายความว่ามันได้เสร็จสิ้นการค้นหาย่อยทั้งหมดของมัน
wqm1800

3

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

def max_unique_substrings(s, seen=()):
    maximum = 0
    for i in range(1, len(s) + 1):
        candidate = s[:i]
        if candidate not in seen:
            maximum = max(maximum, 1 + max_unique_substrings(s[i:], {candidate, *seen}))
    return maximum

การสาธิต: https://repl.it/@blhsing/PriceyScalySphere

ใน Python 3.8 ตรรกะด้านบนยังสามารถเขียนได้ด้วยการเรียกใช้maxฟังก์ชันด้วยนิพจน์ตัวสร้างที่กรองผู้สมัครที่ "เห็น" ด้วยการแสดงออกที่ได้รับมอบหมาย:

def max_unique_substrings(s, seen=()):
    return max((1 + max_unique_substrings(s[i:], {candidate, *seen}) for i in range(1, len(s) + 1) if (candidate := s[:i]) not in seen), default=0)

1

นี่คือคำตอบจากทฤษฎีกราฟ

การสร้างแบบจำลอง
ปัญหานี้สามารถสร้างแบบจำลองเป็นปัญหาชุดอิสระสูงสุดบนกราฟขนาดO(n²)ดังนี้:
อนุญาตw = c_1, ..., c_nเป็นสายป้อนข้อมูล
อนุญาตG = (V,E)เป็นกราฟที่ไม่ได้สร้างขึ้นดังนี้:
V = { (a, b) such that a,b in [1, n], a <= b }. เราจะเห็นได้ว่าขนาดของVมีที่ซึ่งแต่ละจุดสุดยอดเป็นตัวแทนย่อยของn(n-1)/2 แล้วสำหรับคู่ของจุดทุกและเราสร้างขอบIFF (i) ปริภูมิหรือ(ii) เราสร้างขอบระหว่างสองจุดยอดถ้า (i) สตริงย่อยที่พวกเขาแทนทับซ้อนกันหรือ (ii) สตริงย่อยทั้งสองมีค่าเท่ากัน w
(a1, b1)(a2, b2)((a1, b1), (a2, b2))
[a1, b1][a2, b2]
c_a1...c_b1 = c_a2...c_b2
w

แล้วเราสามารถดูว่าทำไมชุดอิสระสูงสุดของการGให้คำตอบในการแก้ไขปัญหาของเรา

ความซับซ้อน
ในกรณีทั่วไปชุดอิสระสูงสุด (MIS) ปัญหา NP-หนักกับความซับซ้อนของเวลาO(1.1996^n)และในพื้นที่พหุนาม[เสี่ยว NamaGoshi (2017)]
ในตอนแรกฉันคิดว่ากราฟที่ได้จะเป็นกราฟที่ไม่มีการเกิดวงจรความยาว> 3 ซึ่งจะดีมากตั้งแต่นั้นปัญหา MIS สามารถแก้ไขได้ในเวลาเชิงเส้นบนกราฟของคลาสนี้
แต่ฉันก็รู้ได้อย่างรวดเร็วว่าไม่ใช่กรณีมันค่อนข้างง่ายที่จะหาตัวอย่างที่มีวงจรความยาว 5 ขึ้นไป
ที่จริงแล้วกราฟผลลัพธ์ไม่ได้แสดงคุณสมบัติ 'ดี' ที่เรามักจะมองหาและช่วยลดความซับซ้อนของปัญหา MIS ให้เป็นพหุนาม
นี่เป็นเพียงขอบเขตบนความซับซ้อนของปัญหาเนื่องจากการลดเวลาของพหุนามไปในทิศทางเดียวเท่านั้น (เราสามารถลดปัญหานี้ให้กับปัญหา MIS แต่ไม่ใช่วิธีอื่น ๆ อย่างน้อยก็ไม่สำคัญ) ในที่สุดเราก็ลงเอยแก้ปัญหานี้O(1.1996^(n(n-1)/2))ในกรณีที่เลวร้ายที่สุด
อนิจจาฉันไม่สามารถพิสูจน์ได้ว่ามันอยู่ใน P หรือว่าเป็น NP-complete หรือ NP-hard สิ่งหนึ่งที่แน่นอนคือปัญหาอยู่ใน NP แต่ฉันเดาว่านี่ไม่ใช่เรื่องแปลกสำหรับทุกคน

การนำไปใช้
ประโยชน์ของการลดปัญหานี้กับปัญหา MIS คือ MIS เป็นปัญหาแบบคลาสสิกซึ่งสามารถพบการใช้งานหลายอย่างและปัญหา MIS นั้นเขียนได้ง่ายเหมือน ILP
นี่เป็นสูตร ILP ของปัญหา MIS:

Objective function 
maximize sum(X[i], i in 1..n)
Constraints:
for all i in 1..n, X[i] in {0, 1}
for all edge (i, j), X[i] + X[j] <= 1

ในความคิดของฉันนั่นควรเป็นวิธีที่มีประสิทธิภาพมากที่สุดในการแก้ปัญหานี้ (โดยใช้แบบจำลองนี้เป็นปัญหา MIS) เนื่องจากตัวแก้ไข ILP มีประสิทธิภาพอย่างไม่น่าเชื่อโดยเฉพาะอย่างยิ่งเมื่อมันมาถึงกรณีใหญ่

นี่คือการนำไปใช้ที่ฉันทำโดยใช้ Python3 และตัวแก้GLPK ในการทดสอบคุณต้องมีเครื่องมือแก้ปัญหา LP ที่เข้ากันได้กับรูปแบบไฟล์ Cplex

from itertools import combinations

def edges_from_string(w):
    # build vertices
    vertices = set((a, b) for b in range(len(w)) for a in range(b+1))
    # build edges
    edges = {(a, b): set() for (a, b) in vertices}
    for (a1, b1), (a2, b2) in combinations(edges, 2):
        # case: substrings overlap
        if a1 <= a2 <= b1:
            edges[(a1, b1)].add((a2, b2))
        if a2 <= a1 <= b2:
            edges[(a2, b2)].add((a1, b1))
        # case: equal substrings
        if w[a1:b1+1] == w[a2:b2+1]:
            if a1 < a2:
                edges[(a1, b1)].add((a2, b2))
            else:
                edges[(a2, b2)].add((a1, b1))
    return edges

def write_LP_from_edges(edges, filename):
    with open(filename, 'w') as LP_file:
        LP_file.write('Maximize Z: ')
        LP_file.write("\n".join([
            "+X%s_%s" % (a, b)
            for (a, b) in edges
        ]) + '\n')
        LP_file.write('\nsubject to \n')
        for (a1, b1) in edges:
            for (a2, b2) in edges[(a1, b1)]:
                LP_file.write(
                    "+X%s_%s + X%s_%s <= 1\n" %
                    (a1, b1, a2, b2)
                )
        LP_file.write('\nbinary\n')
        LP_file.write("\n".join([
            "X%s_%s" % (a, b)
            for (a, b) in edges.keys()
        ]))
        LP_file.write('\nend\n')
write_LP_from_edges(edges_from_string('aababaa'), 'LP_file_1')
write_LP_from_edges(edges_from_string('kzshidfiouzh'), 'LP_file_2')

จากนั้นคุณสามารถแก้ปัญหาด้วยglpsolคำสั่ง:
glpsol --lp LP_file_1
การaababaaแก้ไขอย่างรวดเร็ว (0.02 วินาทีบนแล็ปท็อปของฉัน) แต่ตามที่คาดไว้สิ่งต่าง ๆ จะได้รับมากขึ้นเมื่อขนาดของสตริงเติบโตขึ้น ....
โปรแกรมนี้ให้ค่าตัวเลขเท่านั้น พาร์ติชั่นที่ดีที่สุด), อย่างไรก็ตามพาร์ติชั่นที่เหมาะสมที่สุดและซับสเตรตที่เกี่ยวข้องสามารถพบได้กับการติดตั้งที่คล้ายกัน, โดยใช้ LP solver / python interface เช่นpyomo

เวลาและหน่วยความจำ
aababaa : 0.02 วินาที, 0.4 MB, ค่า: 4
kzshidfiouzh: 1.4 วินาที, 3.8 MB, ค่า: 10
aababababbababab: 60.2 วินาที, 31.5 MB, ค่า: 8
kzshidfiouzhsdjfyu: 207.5 วินาที, 55.7 MB, ค่า: 14
โปรดทราบว่าตัวแก้ LP มี ขอบเขตล่างและบนปัจจุบันของสารละลายดังนั้นสำหรับตัวอย่างสุดท้ายฉันจะได้สารละลายจริงเป็นขอบเขตล่างหลังจากหนึ่งนาที


การสร้างแบบจำลองไม่ใช่การลดหรือพิสูจน์ความซับซ้อนแม้ว่ามันจะมีประโยชน์ในการใช้การแก้ปัญหา ฉันเดิมเขียนแบบจำลองนี้มาก (MIS) เป็นความคิดเห็นภายใต้คำตอบหลักและลบในภายหลัง Markus Schmid หนึ่งในนักทฤษฎีไม่กี่คนที่เขียนบทความในหัวข้อนี้ได้ให้คำตอบอย่างละเอียดในหน้าเว็บนี้แล้ว ระดับความซับซ้อนของปัญหาการตัดสินใจยังคงเปิดอยู่ในวรรณคดี
גלעדברקן

ในกรณีนี้ MIS เป็นสมาคมที่ไม่สำคัญเพราะแน่นอนว่าเรากำลังมองหากลุ่ม "การเชื่อมต่อ (ขอบ) ฟรี" ที่เป็นกลุ่มใหญ่ ด้วยตัวอักษรตัวเดียวตัวอย่างเช่นคำตอบคือพาร์ทิชันตัวเลขซึ่งจะมีวิธีการแก้ปัญหาเวลาพหุนามที่เรียบง่าย อาจมีแง่มุมของปัญหาที่เสนอการเพิ่มประสิทธิภาพที่สามารถหลีกเลี่ยงแผ่นเสียงที่ใช้ O (n ^ 2) เพื่อการวิจัยเพิ่มเติมและจะพลาดโดยหยุดที่มุมมอง MIS แต่มันก็ดูดีสำหรับวิธีแก้ปัญหาการทำงานทั่วไป
גלעדברקן

คุณอ่านคำตอบของฉัน? ฉันเสนอการลดเวลาพหุนามแบบทางเดียวจาก MIS ไปยังปัญหานี้ไม่มีวิธีอื่น ๆ สำหรับตัวอักษรตัวอักษรเดียวปัญหาที่เกิดขึ้นเห็นได้ชัดใน P ด้วยความละเอียดเล็กน้อยโลภ
m.raynal

ดูเหมือนว่าคุณได้ตั้งสมมติฐานเกี่ยวกับระดับความซับซ้อนของมันตาม MIS
גלעדברקן

ดังนั้นอ่านคำตอบ :-) คุณจะเห็นว่าไม่ใช่กรณีนี้ฉันใช้ความซับซ้อน MIS เพื่อให้ขอบเขตบนความซับซ้อนของปัญหาเท่านั้น ไม่มีขอบเขตที่ต่ำกว่า
m.raynal

0

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

ในกระดาษการจับคู่รูปแบบกับตัวแปร: อัลกอริธึมที่รวดเร็วและผลลัพธ์ความแข็งใหม่ (Henning Fernau, Florin Manea, Robert Mercaşและ Markus L. Schmid ในProc. การประชุมวิชาการครั้งที่ 32 ด้านทฤษฎีคอมพิวเตอร์วิทยาการ STACS 2015 เล่มที่ 30 ของ Leibniz การดำเนินการระหว่างประเทศในด้านสารสนเทศ (LIPIcs) , หน้า 302–315, 2015) ผู้เขียนแสดงให้เห็นว่ามันเป็นปัญหาที่สมบูรณ์ในการตัดสินใจสำหรับจำนวนที่กำหนดkและคำwว่าไม่ว่าจะwสามารถแยกเป็นkปัจจัยที่แตกต่างกัน

ถ้าเราพิจารณา templatetypedef ของความคิดเห็นนัยว่าอาจจะมีวิธีการแก้ปัญหาเวลาพหุนามไปไม่ จำกัด factorisation เท่าเทียมกันฟรีที่ใหญ่ที่สุดแล้วแน่นอนเราสามารถใช้วิธีการดังกล่าวจะตอบถ้าเราสามารถแยกสตริงเข้าไปในkปัจจัยที่แตกต่างกัน (สตริง) โดยเพียงแค่สังเกตถ้าkเป็น น้อยกว่าค่าสูงสุดที่เราทราบอยู่แล้ว

อย่างไรก็ตาม Schmid (2016) เขียนว่า "มันยังคงเป็นปัญหาที่เปิดอยู่ว่า MaxEFF-s ยังคงเป็นปัญหาที่สมบูรณ์ถ้าตัวอักษรได้รับการแก้ไข" (การคำนวณแบบสตริงที่ไม่มีความเท่าเทียมกันและการคำนวณซ้ำ, วิทยาศาสตร์คอมพิวเตอร์เชิงทฤษฎีเล่มที่ 618 , 7 มีนาคม 2559, หน้า 42-51)

ขนาดตัวประกอบที่ไร้ความเสมอภาคสูงสุด (MaxEFF-s) ยังคงเป็นพารามิเตอร์แม้ว่าและจะถูกกำหนดเป็น:

เช่น: คำwและตัวเลข,m1 ≤ m ≤ |w|

คำถาม: มีตัวประกอบที่ไม่มีความเสมอภาคของ p wด้วยหรือไม่s(p) ≥ mหรือไม่? ( s(p)เป็นขนาดของตัวประกอบ)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.