एक विभाजन से अनूठे पदार्थों की अधिकतम संख्या


30

मैंने शीर्षक को संशोधित किया ताकि यह अधिक समझने योग्य हो।

यहाँ प्रश्न का एक विस्तृत संस्करण है:

हमारे पास एक स्ट्रिंग है s और इसे सब्सट्रिंग में विभाजित करना चाहते हैं । प्रत्येक स्थानापन्न एक दूसरे से भिन्न होता है। एक कट से हम कितने अनूठे सबस्टिट्यूट बन सकते हैं । दूसरे शब्दों में, अद्वितीय पदार्थ की अधिकतम संख्या क्या है जो बनाने के लिए समवर्ती होती है 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और इसलिए इष्टतम समय जटिलता का अनुमान नहीं लगाया जा सकता है। :(

क्या यह एनपी-कठिन समस्या है? यदि नहीं, तो मैं इसे कुशलता से कैसे हल कर सकता हूं?

मैंने अपने एक दोस्त से यह समस्या सुनी और इसका जवाब नहीं दे सका। मैं इस समस्या को हल करने के लिए एक ट्राई + लालची का उपयोग करने की कोशिश कर रहा हूं। पहला उदाहरण के लिए विधि विफल हो जाती है।

यहाँ त्रि समाधान है कि मैं के साथ आया है:

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 वापस आ जाएगी sमें a|ab|abaa

जोड़ें: सभी के विचार के लिए धन्यवाद, ऐसा लगता है कि यह समस्या एक एनपी समस्या के बहुत करीब है। अभी, मैं इस दिशा से सोचने की कोशिश कर रहा हूं। मान लीजिए कि हमारे पास एक फ़ंक्शन है 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 | a | aab | aab | aabab | aababa | aba | ... में विभाजित किया जा सकता है। आपको सिर्फ 4 कैसे मिले?
सूरज मोतीपट्टी

स्ट्रिंग में केवल aया है b?
फाम

@PTTung नहीं, लेकिन आप यह मान सकते हैं कि इसमें केवल लोअरकेस वर्ण है।
wqm1800

जवाबों:


15

यह टकराव-जागरूक स्ट्रिंग विभाजन समस्या के रूप में जाना जाता है और ऐनी कोंडन, JAN Maňuch और क्रिस थाचुक द्वारा एक पेपर में 3-SAT से कमी के द्वारा एनपी-पूर्ण होना दिखाया गया है - एक टक्कर-जागरूक स्ट्रिंग विभाजन समस्या की जटिलता और इसकी जीन संश्लेषण के लिए ओलिगो डिजाइन के संबंध में ( अंतर्राष्ट्रीय कम्प्यूटिंग और कॉम्बिनेटरिक्स सम्मेलन , 265-275, 2008)।


मैंने उस कागज पर एक सरसरी निगाह डाली, और ऐसा लगता है कि परिणाम से यह साबित होता है कि केवल यह दर्शाता है कि यह समस्या उस स्थिति में एनपी-हार्ड है जहां वर्णों की संख्या की एक ऊपरी सीमा है जो प्रत्येक प्रतिस्थापन में हो सकती है। क्या यह सही है? यदि हां, तो यह इस समस्या से थोड़ा अलग बनाता है। सादृश्य द्वारा तर्क, एक एमएसटी को बहुपद समय में किया जा सकता है, भले ही "पेड़ में नोड्स पर एक डिग्री बाधा के लिए एक एमएसटी खोजने" की समस्या एनपी-हार्ड है।
templatetypedef

1
यह दिखाने के लिए कि यह समस्या एनपी-हार्ड है, हमें इस समस्या के लिए ज्ञात एनपी-हार्ड समस्या (k- विभाजन) को कम करने में सक्षम होने की आवश्यकता है (बिना विभाजन के) इसके बजाय अन्य तरीकों से। के-विभाजन के लिए एक सॉल्वर निश्चित रूप से इस समस्या को हल कर सकता है, लेकिन यह एनपी-कठोरता साबित नहीं होता है।
templatetypedef

मैं यह नहीं देखता कि पेपर समस्या को हल करता है: जैसा कि मैं समझता हूं कि यह पेपर निर्णय-समस्या के बारे में है अगर वहाँ सबसे अधिक लंबाई के विभाजन में मौजूद है। यदि k कुल स्ट्रिंग लंबाई से आधे से अधिक है, तो निर्णय की समस्या काफी हद तक सही है (जैसा कि मैं इसे समझता हूं)।
हंस ओल्सन

नहीं, तथ्य यह है कि समस्या का कश्मीर के लिए एक तुच्छ समाधान है इसका मतलब यह नहीं है कि कश्मीर को छोटा होना होगा और कमी काम करेगी।
templatetypedef

8

(इस चर्चा से मुझे अवगत कराने के लिए गिल्ड बार्कन (דלעב ברק for) को बहुत-बहुत धन्यवाद।)

मुझे इस समस्या के बारे में अपने विचारों को शुद्ध रूप से सैद्धांतिक दृष्टिकोण से साझा करने दें (ध्यान दें कि मैं "सबवेर्ड" के बजाय "कारक" का उपयोग करता हूं)।

मुझे लगता है कि इस समस्या (या समस्याओं) की एक पर्याप्त औपचारिक परिभाषा निम्नलिखित है:

किसी शब्द w को देखते हुए, शब्द 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 चाहते हैं): अधिकतम कश्मीर

न्यूनतमकरण संस्करण (हम छोटा u_i चाहते हैं): अधिकतम घटाएँ {| u_i : 1 <= i <= k}

ये समस्याएं अतिरिक्त रूप से एक बाध्य बी देने से निर्णय की समस्या बन जाती हैं, जिसके अनुसार, हम "कई-कारकों" के बारे में बात कर रहे हैं -variant या "छोटे कारक" -variant, k पर कम बाध्य है (हम कम से कम B चाहते हैं कारकों), या अधिकतम पर एक ऊपरी बाध्य {| u_i | : 1 <= i <= k} (हम सबसे बी में लंबाई के कारक चाहते हैं), क्रमशः। एनपी-कठोरता के बारे में बात करने के लिए, हमें निर्णय समस्याओं के बारे में बात करने की आवश्यकता है।

आइए "छोटे कारकों" के लिए एसएफ शब्द का उपयोग करें-"वेरिएंट" और "एमएफ" के लिए "कई कारक"। विशेष रूप से, और यह वास्तव में एक महत्वपूर्ण बिंदु है, समस्याओं को इस तरह से परिभाषित किया जाता है कि हमें कुछ वर्णमाला पर एक शब्द मिलता है जो किसी भी तरह से प्रतिबंधित नहीं है। समस्या संस्करण था कि हम एक प्राथमिकता जानते हैं कि हमें केवल इनपुट शब्द मिलते हैं, कहते हैं, वर्णमाला {a, b, c, d} एक अलग समस्या है! एनपी कठोरता करता है नहीं स्वचालित रूप से खत्म हो गया "अप्रतिबंधित" से "निर्धारित वर्णमाला" संस्करण (उत्तरार्द्ध सरल हो सकता है) करने के लिए ले।

एसएफ और एमएफ दोनों एनपी-पूर्ण समस्याएं हैं। यह क्रमशः [1, 1 बी] और [2] में दिखाया गया है (जैसा कि गिलाद ने पहले ही बताया है)। अगर मैं इस चर्चा की शुरुआत में (शायद) भी अनौपचारिक समस्या की परिभाषा को सही ढंग से समझता हूं, तो इस चर्चा की समस्या बिल्कुल समस्या एमएफ है। यह शुरू में उल्लेख नहीं किया गया है कि शब्द कुछ निश्चित वर्णमाला से आने के लिए प्रतिबंधित हैं, बाद में यह कहा जाता है कि हम मान सकते हैं कि केवल निचले-मामले वाले अक्षरों का उपयोग किया जाता है। यदि इसका अर्थ है कि हम केवल निश्चित वर्णमाला {a, b, c, ..., z} पर शब्दों पर विचार करते हैं, तो यह वास्तव में NP-कठोरता के संदर्भ में बहुत कुछ बदल देगा।

एक नज़दीकी नज़र से एसएफ और एमएफ की जटिलता में कुछ अंतर का पता चलता है:

  1. कागज [1, 1 बी] से पता चलता है कि अगर हम द्विआधारी एक को वर्णमाला को ठीक करते हैं तो एसएफ एनपी-पूर्ण रहता है (अधिक सटीक रूप से: अक्षर ए और बी और एक बाध्य बी पर एक शब्द डब्ल्यू प्राप्त करना, क्या हम इसे लंबाई के अलग-अलग कारकों में बता सकते हैं। अधिकांश बी;)।
  2. कागज [1, 1 बी] से पता चलता है कि यदि हम बाध्य बी = 2 को ठीक करते हैं तो एसएफ एनपी-पूर्ण रहता है (अधिक सटीक रूप से: एक शब्द डब्ल्यू प्राप्त करना, क्या हम इसे अधिकतम 2 में लंबाई के अलग-अलग कारकों में बदल सकते हैं?)।
  3. कागज [3] से पता चलता है कि यदि वर्णमाला और बाउंड बी दोनों तय हो गए हैं, तो एसएफ को बहुपद-समय में हल किया जा सकता है।
  4. कागज [2] से पता चलता है कि एमएफ एनपी-पूर्ण है, लेकिन केवल अगर वर्णमाला प्रतिबंधित नहीं है या एक प्राथमिकता तय नहीं है ! विशेष रूप से, यह सवाल का जवाब नहीं देता है यदि समस्या एनपी-पूर्ण है अगर हम केवल कुछ निश्चित वर्णमाला पर इनपुट शब्दों पर विचार करते हैं (जैसा कि व्यावहारिक सेटिंग्स में सामान्य रूप से होता है)।
  5. कागज [3] से पता चलता है कि अगर बहुराष्ट्रीय समय में बीएफ को हल किया जा सकता है अगर इनपुट बी को फिर से कुछ स्थिर किया जाता है, यानी, समस्या इनपुट एक शब्द है और {1, 2, ..., के} से एक बाध्य बी है। , जहां K कुछ निश्चित स्थिर है।

इन परिणामों पर कुछ टिप्पणियाँ: Wrt (1) और (2), यह सहज रूप से स्पष्ट है कि यदि वर्णमाला द्विआधारी है, तो, समस्या को SF मुश्किल बनाने के लिए, बाध्य B को भी ठीक नहीं किया जा सकता है। इसके विपरीत, B = 2 को ठीक करने का अर्थ है कि कठिन उदाहरणों को उत्पन्न करने के लिए वर्णमाला का आकार बड़ा होना चाहिए। परिणाम के रूप में, (3) बल्कि तुच्छ है (वास्तव में, [3] थोड़ा और कहते हैं: हम इसे चलाने के समय को न केवल बहुपद में हल कर सकते हैं, बल्कि w | ^ | 2 बार एक कारक है जो केवल वर्णमाला के आकार पर निर्भर करता है। और बाध्य बी)। (५) यह भी मुश्किल नहीं है: यदि हमारा शब्द B की तुलना में लंबा है, तो हम अलग-अलग लंबाई के कारकों में बस ढलकर वांछित कारक प्राप्त कर सकते हैं। यदि नहीं, तो हम सभी संभावनाओं को रोक सकते हैं, जो केवल बी में घातीय है, जो इस मामले में एक स्थिर माना जाता है।

तो हमारे पास जो चित्र है वह निम्न है: एसएफ अधिक कठिन लगता है, क्योंकि हमारे पास निश्चित वर्णमाला के लिए या एक निश्चित बाध्य बी के लिए भी कठोरता है। समस्या एमएफ, दूसरी तरफ, पॉली-टाइम सॉल्व हो जाती है यदि बाउंड तय हो गया है (में) इस संबंध में यह SF की तुलना में आसान है), जबकि संबंधित प्रश्न में वर्णमाला का आकार खुला है। तो MF, SF की तुलना में थोड़ा कम जटिल है, भले ही यह पता चले कि फिक्स्ड अल्फाबेट्स के लिए MF भी NP- पूर्ण है। हालांकि, अगर यह दिखाया जा सकता है कि पॉली-टाइम में निश्चित वर्णमाला के लिए एमएफ को हल किया जा सकता है, तो एमएफ को एसएफ की तुलना में बहुत आसान दिखाया जाता है ... क्योंकि एक मामला जिसके लिए कठिन है वह कुछ हद तक कृत्रिम (अनबाउंड वर्णमाला है!)। ।

मैंने एमएफ के मामले को बाध्य वर्णमाला के साथ हल करने की कोशिश में कुछ प्रयास किया, लेकिन मैं इसे निपटाने में सक्षम नहीं था और इसके बाद से काम करना बंद कर दिया। मुझे विश्वास नहीं है कि अन्य शोधकर्ताओं ने इसे हल करने की बहुत कोशिश की है (इसलिए यह इन बहुत कठिन खुली समस्याओं में से एक नहीं है, कई लोग पहले से ही कोशिश कर चुके हैं और असफल रहे; मैं इसे किसी भी तरह से उचित मानता हूं)। मेरा अनुमान है कि यह निश्चित वर्णमाला के लिए एनपी-हार्ड भी है, लेकिन शायद कमी इतनी जटिल है कि आपको "एमएफ का आकार 35 या उससे अधिक के अक्षर के लिए कठिन है" या ऐसा कुछ मिलेगा, जो सुपर अच्छा भी नहीं होगा ।

आगे के साहित्य के बारे में, मैं कागज [4] को जानता हूं, जो शब्द को अलग-अलग कारकों में विभाजित करने की समस्या पर विचार करता है u_1, u_2, ..., u_k जो सभी पैलिंड्रोम हैं, जो एनपी-पूर्ण भी है।

गिल्ड द्वारा इंगित किए गए कागज [5] पर मेरी त्वरित नज़र थी। यह एक अलग सेटिंग पर विचार करता है, हालांकि। इस पत्र में, लेखकों को इस बात की दिलचस्पी होती है कि किसी दिए गए शब्द में कितने विशिष्ट परिणाम या उपशब्द शामिल हो सकते हैं, लेकिन ये ओवरलैप हो सकते हैं। उदाहरण के लिए, आआबाब में 20 अलग-अलग उप-शब्द होते हैं a, b, aa, ab, ba, bb, aaa, aab, aba, baa, aab, aaba, abab, baab, aaaba, aabaa, abaab, aabaab, aaaba, aaaba (शायद मैं दुस्साहस, लेकिन आप विचार प्राप्त करते हैं)। उनमें से कुछ में केवल एक घटना होती है, जैसे बा, उनमें से कुछ कई, जैसे कि आ। किसी भी मामले में, सवाल यह नहीं है कि हम कई अलग-अलग कारकों को प्राप्त करने के लिए किसी तरह शब्द को कैसे विभाजित कर सकते हैं, क्योंकि इसका मतलब है कि प्रत्येक व्यक्ति का प्रतीक बिल्कुल एक कारक में योगदान देता है।

इस तरह की समस्याओं के व्यावहारिक समाधान के बारे में (ध्यान रखें कि मैं एक सिद्धांतवादी हूं, इसलिए इसे नमक के दाने के साथ लें):

  • मेरी जानकारी के लिए, कोई सैद्धांतिक निचली सीमा (जैसे कि एनपी-कठोरता) नहीं है जो कि बहुपदीय समय में एमएफ को हल करने के लिए इसे नियंत्रित करेगा यदि हम एक निश्चित वर्णमाला पर केवल इनपुट शब्द मानते हैं। एक चेतावनी है, हालांकि: यदि आपको पॉली-टाइम एल्गोरिथ्म मिलता है, तो यह निश्चित वर्णमाला (या किसी फ़ंक्शन में घातीय) से प्रतीकों की संख्या में तेजी से चलना चाहिए! अन्यथा यह अनबाउंड अल्फाबेट्स के मामले के लिए एक बहुपद समय एल्गोरिथ्म भी होगा। इसलिए, एक सिद्धांतवादी होने के नाते, मैं एल्गोरिदमिक कार्यों की तलाश करूंगा जो कि समय के घातांक में गणना की जा सकती हैं यदि केवल प्रतीकों की संख्या और जो किसी तरह से एमएफ के लिए एल्गोरिथम तैयार करने में मदद करते हैं। दूसरी ओर, यह संभावना है कि ऐसा एल्गोरिथ्म मौजूद नहीं है और फिक्स्ड-अल्फाबेट मामले में एमएफ भी एनपी-हार्ड है।

  • यदि आप व्यावहारिक समाधानों में रुचि रखते हैं, तो समाधान का अनुमान लगाने में मददगार हो सकता है। इसलिए फैक्टरिसेशन हो रहा है जो कि केवल आधा होने की गारंटी है क्योंकि सबसे खराब स्थिति में इष्टतम भी खराब नहीं होगा।

  • अनुमान है कि एक स्पष्ट अनुमान अनुपात नहीं देते हैं, लेकिन एक व्यावहारिक सेटिंग में अच्छी तरह से काम भी दिलचस्प होगा, मुझे लगता है।

  • समस्या उदाहरणों को SAT या ILP-instances में बदलना बहुत कठिन नहीं होना चाहिए और तब आप एक SAT या ILP-सॉल्वर भी इष्टतम समाधान प्राप्त करने के लिए चला सकते हैं।

  • मेरी व्यक्तिगत राय है कि भले ही यह ज्ञात नहीं है कि क्या एमएफ का निश्चित-वर्णमाला का मामला एनपी-हार्ड है, पर्याप्त सैद्धांतिक अंतर्दृष्टि है जो सुझाव देती है कि समस्या काफी कठिन है ताकि हेयुरिस्टिक समाधानों की तलाश करना उचित हो। एक व्यावहारिक सेटिंग में अच्छी तरह से काम करते हैं।


ग्रंथ सूची:

[१] ऐनी कोंडन, जान मनुच, क्रिस थचुक: स्ट्रिंग विभाजन की जटिलता। जे। असतत एल्गोरिदम 32: 24-43 (2015)

[१ बी] ऐनी कोंडॉन, जान मनुच, क्रिस थचुक: एक टक्कर की जटिलता-अवेयर स्ट्रिंग स्ट्रिंग पार्टीशन प्रॉब्लम और इसके रिलेशन टू ऑलिगो डिजाइन फॉर जीन सिंथेसिस। COCOON 2008: 265-275

[२] हेनिंग फर्नाउ, फ्लोरिन मैना, रॉबर्ट मर्कस, मार्कस एल। श्मिड: पैटर्न मिलान विथ वैरिएबल्स: फास्ट एलगोरिदम एंड न्यू हार्डनेस परिणाम। STACS 2015: 302-315

[३] मार्कस एल। श्मिट: समानता-मुक्त और दोहराए जाने वाले स्ट्रिंग कारक। या। कंप्यूटर। विज्ञान। 618: 42-51 (2016)

] इंट। जे पाया। कंप्यूटर। विज्ञान। 29 (2): 143-164 (2018)

[५] अब्राहम फ्लैक्समैन, अराम वेट्रॉथ हैरो, ग्रेगरी बी। सोरकिन: स्ट्रिंग्स विद मैक्सिमली कई डिस्टि्रक्ट सब्जेक्ट्स एंड सबस्ट्रिंग्स। Electr। जे कंघी। 11 (1) (2004)


(पोस्ट करने के लिए धन्यवाद, वैसे!) बस स्पष्ट करने के लिए, संदर्भ के बारे में मेरी टिप्पणी [5], वास्तव में एक अलग प्रश्न के बारे में थी - यह मुख्य टिप्पणी अनुभाग में लुक्स्टॉर्म के प्रश्न की प्रतिक्रिया थी , "एन के किसी भी स्ट्रिंग के लिए। P संभव वर्णों की लंबाई, ऐसे तार वाले अद्वितीय उप-तारों की अधिकतम संख्या क्या हो सकती है? "
לעג ברקן

3

यहां एक समाधान है, लेकिन यह वास्तव में तेजी से बढ़ता है और एक कुशल समाधान के पास कहीं भी नहीं है। यह पहली बार ऑर्डर करने के लिए कोई चिंता के साथ अद्वितीय सबस्ट्रिंग की एक सूची में स्ट्रिंग को तोड़ता है, फिर उन सबस्ट्रिंग को पुन: एकत्र करने के लिए पुनरावृति का उपयोग करने का प्रयास करता है मूल स्ट्रिंग से मेल खाता है, यह देखने के लिए कि यह क्रम में है।

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

मैंने इस समस्या को इसके संदर्भ में एक कोशिश और सोचा है या किसी दिए गए सूचकांक में विभाजन बनाने के लिए। इसलिए इस समारोह पुनरावर्ती है और सूचकांक में प्रत्येक सूचकांक 1. न विभाजन पर 2 शाखाओं बनाता है मैं सूचकांक मैं 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


आपके समाधान के लिए धन्यवाद! यह डीएफएस समाधान बहुत स्पष्ट है। मेरे पास एक छोटा सा सुझाव है कि keepफ़ंक्शन में तेजी आ सकती है क्योंकि set.copy()फ़ंक्शन बहुत समय लेने वाला है। बैकट्रैकिंग का उपयोग कैसे करें जो इस फ़ंक्शन स्टैक को पूरा करने के बाद, सेट से वर्तमान उम्मीदवार को हटा दें?
wqm1800

@ wqm1800 आप pls विस्तृत कर सकते हैं, मुझे खेद है कि मैं वास्तव में नहीं समझता। यहां तक ​​कि अगर हम बैकट्रैक का उपयोग करते हैं, तो भी हमें mergeअलग-अलग सेट करना होगा क्योंकि हम हमेशा ब्रांच कर रहे हैं। इसलिए इसकी या तो विलय या नकल। क्या आप विस्तृत कर सकते हैं?
रवि चांडक 3

1
यहाँ मेरे पीछे समाधान है । यह काम कर सकता है क्योंकि फ़ंक्शन स्टैक एक डीएफएस तरीके के रूप में निष्पादित होता है इसलिए जब फ़ंक्शन समाप्त होता है, तो इसका मतलब है कि इसके सभी विकल्प की खोज खत्म हो गई है।
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

पायथन 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²): इस प्रकार
Let 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, जहां प्रत्येक शिखर की सबस्ट्रिंग का प्रतिनिधित्व करता है w
फिर, हर जोड़े के लिए (a1, b1)और (a2, b2), हम किनारे का निर्माण ((a1, b1), (a2, b2))iff
(i) [a1, b1]प्रतिच्छेदन [a2, b2]या
(ii) करते हैं c_a1...c_b1 = c_a2...c_b2
अन्यथा, हम दो कोने के बीच एक धार का निर्माण करते हैं अगर (i) वे सब्सट्रिंग जो वे ओवरलैप का प्रतिनिधित्व करते हैंw या (ii) दोनों सब्सट्रिंग समान हैं।

हम तो देख सकते हैं कि क्यों एक अधिकतम स्वतंत्र सेट की Gहमारी समस्या का जवाब देता है।

जटिलता
सामान्य मामले में, अधिकतम स्वतंत्र सेट (एमआईएस) समस्या एनपी-हार्ड है, O(1.1996^n)और बहुपद स्थान [Xiao, NamaGoshi (2017)] की समय जटिलता के साथ ।
पहले मैंने सोचा था कि परिणामी ग्राफ एक कॉर्डल ग्राफ (लंबाई का कोई प्रेरित चक्र> 3) नहीं होगा, जो तब से बहुत अच्छा रहा होगा क्योंकि एमआइएस समस्या को रेखांकन के इस वर्ग पर रैखिक समय में हल किया जा सकता है।
लेकिन मुझे जल्दी ही एहसास हुआ कि यह मामला नहीं है, ऐसे उदाहरणों को खोजना काफी आसान है जहां लंबाई 5 और अधिक के प्रेरित चक्र हैं।
दरअसल, परिणामी ग्राफ किसी भी 'अच्छी' संपत्ति को प्रदर्शित नहीं करता है जिसे हम आम तौर पर खोजते हैं और जो कि एमआईएस समस्या की जटिलता को एक बहुपद तक कम करने की अनुमति देता है।
यह केवल समस्या की जटिलता पर एक ऊपरी बाध्यता है, क्योंकि बहुपद समय में कमी केवल एक दिशा में जाती है (हम इस समस्या को एमआईएस समस्या में कम कर सकते हैं, लेकिन अन्य तरीके से नहीं, कम से कम तुच्छ नहीं)। तो अंत में हम इस समस्या O(1.1996^(n(n-1)/2))को सबसे खराब स्थिति में हल करते हैं ।
तो, अफसोस, मैं यह साबित नहीं कर सका कि यह पी में है, या यह एनपी-पूर्ण या एनपी-हार्ड है। एक निश्चित बात यह है कि समस्या एनपी में है, लेकिन मुझे लगता है कि यह किसी के लिए आश्चर्य की बात नहीं है।

कार्यान्वयन
MIS समस्या के लिए इस समस्या को कम करने का लाभ MIS एक शास्त्रीय समस्या है, जिसके लिए कई कार्यान्वयन पाए जा सकते हैं, और यह कि MIS समस्या को भी ILP के रूप में आसानी से लिखा जा सकता है।
यहाँ MIS समस्या का ILP सूत्रीकरण है:

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

मेरी राय में, इस समस्या को हल करने का सबसे कुशल तरीका होना चाहिए (इस मॉडलिंग को एमआईएस समस्या के रूप में उपयोग करना), क्योंकि आईएलपी सॉल्वर अविश्वसनीय रूप से कुशल हैं, खासकर जब यह बड़े उदाहरणों की बात आती है।

यह एक कार्यान्वयन है जिसे मैंने पायथन 3 और जीएलपीके सॉल्वर का उपयोग करके किया था । इसका परीक्षण करने के लिए, आपको Cplex फ़ाइल प्रारूप के साथ संगत LP सॉल्वर की आवश्यकता होती है।

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आदेश: जल्दी हल हो जाता है (0.02 अपने लैपटॉप पर सेकंड), लेकिन उम्मीद के रूप में, बातें (बहुत) मुश्किल स्ट्रिंग आकार बढ़ता है के रूप में .... यह कार्यक्रम केवल संख्यात्मक मान और देता है (नहीं इष्टतम विभाजन), फिर भी एक समान कार्यान्वयन के साथ इष्टतम विभाजन और संबंधित सबस्ट्रिंग पाया जा सकता है, एक एलपी सॉल्वर / पायथन इंटरफ़ेस जैसे कि पाइमो का उपयोग करके
glpsol --lp LP_file_1
aababaa

समय और स्मृति
aababaa : 0.02 सेकंड, 0.4 एमबी, मूल्य: 4
kzshidfiouzh: 1.4 सेकंड, 3.8 एमबी, मूल्य: 10
aababababbababab: 60.2 सेकंड, 31.5 एमबी, मूल्य: 8
kzshidfiouzhsdjfyu: 207.5 सेकंड, 55.7 एमबी, मूल्य: 14
ध्यान दें कि एलपी सॉल्वर भी प्रदान करता है समाधान पर वर्तमान निचले और ऊपरी सीमा, इसलिए अंतिम उदाहरण के लिए, मैं एक मिनट के बाद निचले हिस्से के रूप में वास्तविक समाधान प्राप्त कर सकता था।


मॉडलिंग में कमी या जटिलता का प्रमाण नहीं है, हालांकि यह समाधानों को लागू करने में मददगार हो सकता है। मैंने मूल रूप से इस मॉडल (एमआईएस) को मुख्य उत्तर के तहत एक टिप्पणी के रूप में लिखा था और बाद में इसे हटा दिया। मार्कस श्मिड, इस विषय पर लेखक पत्रों के कुछ सिद्धांतकारों में से एक ने पहले ही इस वेबपेज पर एक विस्तृत जवाब दिया। निर्णय समस्या की जटिलता वर्ग साहित्य में खुला रहता है।
לעג ברקן

इस मामले में, एमआईएस एक तुच्छ एसोसिएशन की तरह है क्योंकि निश्चित रूप से हम "कनेक्शन (एज) मुक्त" चीजों के एक बड़े समूह की तलाश कर रहे हैं। एक वर्ण वर्णमाला के साथ, उदाहरण के लिए, उत्तर एक संख्या विभाजन है जिसके लिए एक सरल बहुपद समय समाधान होगा। समस्या के ऐसे पहलू हो सकते हैं जो अनुकूलन प्रदान करते हैं जो एक ओ (एन ^ 2) को दरकिनार कर सकते हैं-आधारित एलपी को अधिक शोध दिया गया था, और एमआईएस दृश्य पर रोक लगाने से चूक जाएगा। लेकिन यह एक सामान्य कार्य समाधान के लिए बहुत अच्छा लगता है।
לעג ברקן

क्या आपने मेरा जवाब पढ़ा? मैं एमआईएस से इस समस्या के लिए एक तरफ़ा एक-तरफा बहुपद समय की कमी की पेशकश करता हूं, कोई दूसरा रास्ता नहीं है। एकल वर्ण वर्णमाला के लिए, समस्या स्पष्ट रूप से पी में है, एक लालची तुच्छ संकल्प के साथ।
m.raynal

ऐसा लग रहा था कि आपने एमआईएस पर आधारित इसकी जटिलता वर्ग के बारे में धारणा बना ली है।
לעג ברקן

तो जवाब पढ़ें :-) आप देखेंगे कि यह मामला नहीं है, मैं केवल एमआईएस जटिलता का उपयोग समस्या की जटिलता पर एक ऊपरी बाध्यता देता हूं। एक निचली सीमा नहीं।
m.raynal

0

मेरा अन्य उत्तर बारीकी से संबंधित था, लेकिन इस समस्या के बिल्कुल अनुरूप नहीं था, अस्पष्ट छोड़ते हुए कि क्या सबसे बड़ी समानता-मुक्त स्ट्रिंग कारक का पता लगाना एक अलग जटिलता वर्ग का हो सकता है, चाहे बाध्य कारक लंबाई (उत्तरार्द्ध) के साथ कोई समानता-मुक्त कारक मौजूद हो। उद्धृत कागज द्वारा संबोधित किया जा रहा है)।

पेपर में, पैटर्न का मिलान चर के साथ: फास्ट एल्गोरिदम और नई कठोरता के परिणाम (हेनिंग फर्नाउ, फ्लोरिन मैना, रॉबर्ट मर्कस, और मार्कस एल। श्मिट, प्रोसी । 32 वें संगोष्ठी में कंप्यूटर विज्ञान के एसटीएसीएस 2015, एसटीबीएएस 2015 के खंड 30, लाइबनिज़ के वॉल्यूम 30 के रूप में। इंटरनेशनल प्रोसीडिंग्स इन इंफॉर्मेटिक्स (LIPIcs) , पेज 302–315, 2015), लेखक बताते हैं कि किसी दिए गए नंबर kऔर एक शब्द के लिए यह तय करना एनपी-पूर्ण है कि wक्या अलग कारकों wमें kकारक हो सकते हैं।

यदि हम टेम्प्लेटेटिपेड की टिप्पणी पर विचार करते हैं , तो इसका अर्थ यह है कि अप्रतिबंधित, सबसे बड़ी समानता-मुक्त कारक के लिए एक बहुपद समय समाधान हो सकता है, तो निश्चित रूप से हम इस तरह के एल्गोरिथ्म का उपयोग कर सकते हैं जवाब देने के लिए कि क्या हम स्ट्रिंग को kअलग-अलग कारकों (सब्सट्रिंग्स) में विभाजित करके देख सकते हैं कि kक्या केवल कम से कम हम पहले से ही जानते हैं।

श्मिट (2016), हालांकि, लिखते हैं कि "यह अभी भी एक खुली समस्या है कि क्या MaxEFF-s एनपी-पूर्ण रहता है यदि वर्णमाला तय हो गई है।" (समानता-मुक्त और दोहराए जाने वाले स्ट्रिंग कारक, सैद्धांतिक कंप्यूटर विज्ञान वॉल्यूम 618 , 7 मार्च 2016, पृष्ठ 42-51 का कम्प्यूटिंग )

अधिकतम समानता-मुक्त फैक्टराइजेशन साइज़ (MaxEFF-s) को अभी भी मानकीकृत किया गया है, हालाँकि, और इसे इस प्रकार परिभाषित किया गया है:

उदाहरण: एक शब्द wऔर एक नंबर m, 1 ≤ m ≤ |w|

प्रश्न: क्या कोई समानता-मुक्त कारक के wसाथ मौजूद है s(p) ≥ m? ( s(p)कारक का आकार होने के नाते।)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.