2011-01-10 13 views
7

के साथ कुछ क्रमबद्ध सूचियों को विलय करना मेरे पास तत्वों की चर संख्या के साथ कुछ सूचियां हैं। प्रत्येक सूची को क्रमबद्ध किया जाता है, लेकिन सॉर्टिंग एल्गोरिदम ज्ञात नहीं है। मैं सूचियों को एक बड़ी सूची में मर्ज करना चाहता हूं जिसमें डुप्लीकेट के बिना, समान क्रम में सभी सूचियां शामिल हों।अज्ञात क्रम अनुक्रम

उदाहरण इनपुट:

  1. XS, एम, एल, एक्स्ट्रा लार्ज
  2. S, M, XXL
  3. XXS, XS, एस, एल

अपेक्षित परिणाम:

  • एक्सएक्सएस, एक्सएस, एस, एम, एल, एक्सएल, एक्सएक्सएल

अपेक्षित परिणाम के लिए एक मर्ज किया गया परिणाम है कि सही क्रम में प्रत्येक इनपुट अनुक्रम के तत्वों, इस तरह होता है प्राप्त करने के लिए इनपुट दृश्यों का मिलान करते हुए प्राप्त किया जाता है:

XS M L XL 
     S M  XXL 
XXS XS S L 
------------------- 
XXS XS S M L XL XXL 

समारोह को सूचित करना चाहिए, यदि ऐसे तत्व हैं जिनके पास संदिग्ध पद हैं। यहां, यह एक्सएक्सएल होगा (यह एम, एल या एक्सएल के बाद रह सकता है) और मुझे एक्सएल के बाद मैन्युअल रूप से अपनी स्थिति निर्दिष्ट करने की आवश्यकता है (क्योंकि यहां मैं सॉर्टिंग एल्गोरिदम जानता हूं और मदद कर सकता हूं)। मैंने प्रत्येक दो तत्वों के जोड़े को परिभाषित करने के बारे में सोचा, प्रत्येक जोड़ी मूल सूची में क्रमशः। इससे एक पूरी सूची बना सकता है।

+0

मुझे समझ में नहीं आता कि प्राथमिकता नियम अज्ञात हैं तो आप सूचियों को कैसे विलय कर सकते हैं। –

+0

@ टायलर डर्डन मैंने आशा व्यक्त करने के लिए प्रश्न को संपादित किया है कि यह थोड़ा स्पष्ट हो। क्या उससे मदद हुई? – jcsanyi

+0

नहीं, यह कैसे तय किया जाता है कि आप एक्सएक्सएल एल और एक्सएल के सापेक्ष कहां हैं? –

उत्तर

3

यहाँ मैं क्या कर सकता है:

  1. preprocess सूचियों: /: पता लगाना है कि XXS से छोटी XS एस से छोटी है है से छोटी ... XXL है एक [बाधा संतुष्टि समस्या] (http है /en.wikipedia.org/wiki/Constraint_satisfaction_problem)। इस प्रकार की समस्या में मूल सूचियों में परिभाषित बाधाओं को देखते हुए सभी तत्वों के बीच सही क्रम की खोज करना शामिल है।
  2. चरण {1, ..., XXL} से सेट {1, ..., 6} पर एक बिडरेक्शनल मैपिंग बनाएं, चरण 1 के बाद सेट करें।
  3. प्रत्येक सूची के लिए, एक और सूची बनाएं 2.
  4. में परिभाषित मैपिंग का उपयोग करके दो सूचियों को गठबंधन करने के लिए एक संशोधित [मर्ज सॉर्ट] (http://en.wikipedia.org/wiki/Merge_sort) का उपयोग करें। विलय एल्गोरिदम को संशोधित करें ताकि यह रिपोर्ट करे कि दो वस्तुओं की तुलना की जा रही है (और मर्ज किए जा रहे आइटमों में से एक को नजरअंदाज कर दिया जाता है)।
  5. सूची की प्रत्येक जोड़ी के लिए चरण 4 करें जब तक कोई सूची न हो।
  6. 2 में परिभाषित मैपिंग का उपयोग करके, सूची का टेक्स्ट-संस्करण बनाएं।
+0

मुझे लगता है कि आप तत्वों के क्रम (1. में) मानते हैं, लेकिन यह ज्ञात नहीं है। पहली सूची से मैं केवल एक्सएस, एम, एल और एक्सएल का आदेश जानता हूं। दूसरी सूची से एस <एम होना चाहिए, लेकिन XS से पहले या उसके बाद एस रहता है? अगर हम यहां रुकते हैं, तो हम उसे नहीं जानते हैं और इसे मैन्युअल रूप से सेट करना होगा। – Gabriel

+0

मैं क्षमा चाहता हूं, मुझे गलत समझा जाना चाहिए। आपकी पहली वाक्य ने कहा कि सूचियों को क्रमबद्ध किया गया था, जिससे मुझे लगता है कि आप जानते हैं कि सूचियां क्या हैं (और इसलिए सभी तत्वों को जानते हैं)। यह कहने के लिए पहली वाक्य को पुन: प्रस्तुत करना अच्छा हो सकता है: "मैंने सूचियों को क्रमबद्ध किया है जिनकी सामग्री मुझे नहीं पता।" – Davidann

+0

इसके अलावा, मैंने गलतफहमी के लिए मेरा जवाब अपडेट किया। – Davidann

14

इसे Topological Sort एल्गोरिदम के साथ हल किया जा सकता है।

यदि आप अपने प्रत्येक इनपुट अनुक्रमों को निर्देशित ग्राफ के माध्यम से पथ मानते हैं, तो एक स्थलीय प्रकार आपके नोड्स के सेट को बाएं से दाएं से क्रमबद्ध करेगा ताकि प्रत्येक निर्देशित किनारे दाईं ओर इंगित हो। Diagram of a directed graph after topological sorting

Topological Sorting पर विकिपीडिया पृष्ठ इस एल्गोरिथ्म, पहले 1962 में आर्थर क्हान द्वारा वर्णित शामिल हैं:

L ← Empty list that will contain the sorted elements 
S ← Set of all nodes with no incoming edges 
while S is non-empty do 
    remove a node n from S 
    insert n into L 
    for each node m with an edge e from n to m do 
     remove edge e from the graph 
     if m has no other incoming edges then 
      insert m into S 
if graph has edges then 
    return error (graph has at least one cycle) 
else 
    return L (a topologically sorted order) 

इस एल्गोरिथ्म, लिखित रूप में, वास्तव में अगर यह अस्पष्ट दृश्यों पाता असफल नहीं है, लेकिन इतना आसान है इस तरह, पाश की शुरुआत में एक चेक डालने से जोड़ने के लिए:

... 
while S is non-empty do 
    if S contains more than 1 item 
     return error (inputs are ambiguous) 
    remove a node n from S 
    ... 

मैं आप किस भाषा में काम कर रहे हैं पता नहीं है, लेकिन मैं एक साथ एक सबूत के रूप में इस पीएचपी कार्यान्वयन फेंक दिया गया है अवधारणा के:

function mergeSequences($sequences, $detectAmbiguity = false) { 

    // build a list of nodes, with each node recording a list of all incoming edges 
    $nodes = array(); 
    foreach ($sequences as $seq) { 
     foreach ($seq as $i => $item) { 
      if (!isset($nodes[$item])) $nodes[$item] = array(); 
      if ($i !== 0) { 
       $nodes[$item][] = $seq[$i-1]; 
      } 
     } 
    } 

    // build a list of all nodes with no incoming edges 
    $avail = array(); 
    foreach ($nodes as $item => $edges) { 
     if (count($edges) == 0) { 
      $avail[] = $item; 
      unset($nodes[$item]); 
     } 
    } 

    $sorted = array(); 
    $curr = '(start)'; 
    while (count($avail) > 0) { 

     // optional: check for ambiguous sequence 
     if ($detectAmbiguity && count($avail) > 1) { 
      throw new Exception("Ambiguous sequence: {$curr} can be followed by " . join(' or ', $avail)); 
     } 

     // get the next item and add it to the sorted list 
     $curr = array_pop($avail); 
     $sorted[] = $curr; 

     // remove all edges from the currently selected items to all others 
     foreach ($nodes as $item => $edges) { 
      $nodes[$item] = array_diff($edges, array($curr));     
      if (count($nodes[$item]) == 0) { 
       $avail[] = $item; 
       unset($nodes[$item]); 
      } 
     } 

    } 

    if (count($nodes) > 0) { 
     throw new Exception('Sequences contain conflicting information. Cannot continue after: ' . join(', ', $sorted)); 
    } 

    return $sorted; 
} 

आप इस तरह फ़ंक्शन को कॉल कर सकते हैं:

$input = array(
    array('XS', 'M', 'L', 'XL'), 
    array('S', 'M', 'XXL'), 
    array('XXS', 'XS', 'S', 'L'), 
); 
echo(join(', ', mergeSequences($input))); 
echo(join(', ', mergeSequences($input, true))); 

निम्नलिखित उत्पादन प्राप्त करने के लिए:

XXS, XS, S, M, XXL, L, XL 
Uncaught exception 'Exception' with message 'Ambiguous sequence: M can be followed by L or XXL' 
+1

टीओओसीपी वॉल्यूम 1 में टोपोलॉजिकल सॉर्टिंग का भी वर्णन किया गया है। –

6

आप partially ordered sets, या posets मर्ज करने के लिए कोशिश कर रहे हैं। विलय के अस्पष्ट भागों को antichains कहा जाता है। तो, आप एक एल्गोरिदम चाहते हैं जो पॉजिट्स को विलीन करता है और आपको बताता है कि एंटीचैन क्या हैं।

Here is a paper describing an algorithm for merging posets and detecting antichains, साथ ही साथ link to the first author's homepage यदि आप उससे संपर्क करना चाहते हैं तो यह देखने के लिए कि कोई स्रोत कोड उपलब्ध है या नहीं।

+0

धन्यवाद। समाधान खोजने के बारे में अक्सर सबसे कठिन हिस्सा खोज करने के लिए सही शब्द जानना है। – jcsanyi

-1

भाग को सॉर्ट करने के लिए, मुझे लगता है कि मर्ज सॉर्ट आपके विवरण के अनुसार पर्याप्त है। संशोधित करने की आवश्यकता है विलय के दौरान, हमें इनपुट सरणी पर तत्वों को छोड़ना चाहिए यदि इनपुट सरणी का पहला तत्व परिणाम सरणी के समान है।

यदि मैं सही ढंग से समझता हूं, तो आप पूरे संभावित इनपुट तत्वों का कुल क्रम बनाना चाहते हैं। कुछ आंशिक क्रम पहले ही इनपुट arraies में परिभाषित किया गया है (क्योंकि वे पहले ही सॉर्ट किए गए हैं), जबकि अन्य उपयोगकर्ताओं द्वारा निर्दिष्ट करने की आवश्यकता है। सवाल में उदाहरण के लिए, आदेश के लिए

'एस' < 'एम' < 'XXL'

'XS' < 'एम' < 'एल' < 'एक्स्ट्रा लार्ज'

'XXS' < ' एक्सएस '<' एस '<' एल '

अच्छी तरह से परिभाषित किया गया है। लेकिन एल्गोरिदम अभी भी नहीं जानता है कि 'एक्सएक्सएल' 'एक्सएल', 'एल' से बड़ा या छोटा है या नहीं।
ठीक है क्योंकि तीन इनपुट arraies क्रमबद्ध है, इनपुट तत्वों का कुल क्रम मौजूद होना चाहिए। तो मेरा सुझाव है कि आप अपने डेटा प्रदाता से सभी संभावित डेटा तत्वों की ऑर्डर सूची के लिए पूछें। बेवकूफ लगता है, लेकिन यह एक आसान तरीका है।

यदि यह सूची उपलब्ध नहीं है, तो सौदा करने का एक आसान तरीका उपयोगकर्ता के लिए एक जोड़ी सॉर्ट के लिए संकेत देना है, फिर जांचें कि मौजूदा इनपुट अनुक्रम के साथ यह संघर्ष है या याद रखें, जब एल्गोरिदम एक संदिग्ध जोड़ी में आ जाता है। मुझे लगता है कि टोपोलॉजी सॉर्टिंग इस एप्लिकेशन की तुलना में अधिक शक्तिशाली है। चूंकि हम एकल डेटा तत्वों से निपटते हैं, इसलिए कुल आदेश से बाहर निकलना होगा। जबकि टोपोलॉजी सॉर्टिंग आंशिक क्रम से निपटने के लिए है।

संबंधित मुद्दे