2010-02-07 8 views
5

संपादित करें: मुझे यकीन नहीं है कि मेरा मूल प्रश्न पर्याप्त स्पष्ट है। मुझे एक एल्गोरिदम की आवश्यकता है जो एक सरणी को एक ऑर्डर से दूसरे में पुनर्व्यवस्थित करने के लिए चाल के न्यूनतम अनुक्रम की गणना करेगा। यह ज्ञात है कि दोनों सरणी में एक ही तत्व (कोई डुप्लिकेट नहीं) होगा और समान लंबाई होगी। उदाहरण के लिए:एल्गोरिदम: एक आदेश से दूसरे क्रम में एक सूची को पुनर्व्यवस्थित करने का इष्टतम तरीका?

reorder(
    ['d', 'a', 'c', 'b', 'e'], 
    ['a', 'b', 'c', 'd', 'e'] 
) 

की तरह कुछ लौट जाना चाहिए:

[ 
    {move:'d', after:'b'}, 
    {move:'c', after:'b'} 
] 

जो इंगित करता है कि मैं पहली बार के बाद 'बी' के तत्व 'प' बढ़ना चाहिए, तो के बाद 'बी' में ले जाएँ 'सी' और सरणी वांछित क्रम में होगा।


पृष्ठभूमि: मैं (, क्लाइंट साइड करने के लिए rtgui में कार्यक्षमता के सबसे चलती वास्तव में) एक परियोजना पर काम कर रहा हूँ। अभी मैं सॉर्टिंग पर काम कर रहा हूं। असल में मेरे पास divs की एक सूची है जिसे मैं कुछ मनमाने ढंग से क्रमबद्ध करना चाहता हूं। मैं वांछित क्रम इस प्रकार प्राप्त कर सकते हैं:

var hashes = { 
    before: [], 
    after: [], 
}; 
var els = $('div.interesting-class').toArray(); 
var len = els.length; 

for(var i = 0; i < len; i++) hashes.before.push(els[i].id); 
els.sort(getSortComparator()); 
for(var i = 0; i < len; i++) hashes.after.push(els[i].id); 

अब hashes.before और hashes.after अव्यवस्थित होते हैं और आदेश दिया तत्व आईडी की सूची। सूची को पुन: व्यवस्थित करते समय, सबसे महंगी ऑपरेशन, वास्तव में, वास्तव में डीओएम तत्वों को चारों ओर ले जा रहा है। इस प्रकार मैं यह कर दिया गया था:

var c = $('#container-id'); 
$(els).each(function() { 
    c.append(this); 
}); 

यह काम करता है, लेकिन, आवश्यक की तुलना में धीमी औसतन के बाद से, केवल 2 या 3 तत्वों वास्तव में स्थानांतरित करने की जरूरत है। इसलिए, मुझे एक एल्गोरिदम की आवश्यकता है जो एक क्रम से दूसरे क्रम में एक सरणी को पुन: व्यवस्थित करने के लिए चाल के न्यूनतम अनुक्रम की गणना करेगा (इस मामले में, hashes.before और hashes.after पर चल रहा है)। क्या कोई सुझाव दे सकता है या कोई विचार दे सकता है?

मैंने अब तक कई सामान्य उद्देश्य "diff" एल्गोरिदम की कोशिश की है, लेकिन उन्होंने वास्तव में मुझे वह नहीं दिया जो मैं चाहता था। मुझे लगता है कि मुझे इसकी जरूरत है, लेकिन अधिक विशिष्ट है।

उत्तर

6

http://en.wikipedia.org/wiki/Longest_increasing_subsequence

(नई सॉर्ट क्रम के अनुसार) सबसे लंबे समय तक वृद्धिमान परिणाम का पता लगाएं। फिर अनुक्रम में पहले से मौजूद तत्वों के सापेक्ष इसके स्थान पर, प्रत्येक अनुक्रम में उस तत्व को स्थानांतरित करें।

आपके उदाहरण में, 'ए, बी, ई' और 'ए, सी, ई' सबसे लंबे समय तक बढ़ने के लिए बंधे हैं। सबसे अच्छा आप कर सकते हैं उनमें से एक का चयन करें, और बस अन्य तत्वों को ले जाएं।

+0

हां, मैं देख सकता हूं कि यह वही करेगा जो मैं चाहता हूं। ऐसा लगता है कि मैं इस तरह के लिए धैर्य छंटनी का उपयोग करने के लिए भी आगे बढ़ सकता हूं, क्योंकि इससे सूची क्रमबद्ध हो जाएगी और बाद में एक ही समय में मिल जाएगा। धन्यवाद! – jnylen

0

मेरा पहला विचार यह है कि आपको अंतर्निहित सॉर्ट विधि के बजाय Selection sort का उपयोग करना चाहिए, क्योंकि यह आवश्यक स्वैप की सबसे कम मात्रा बनाता है। इस तरह आप सूची में आईडी को स्थानांतरित करते समय बस DOM तत्व को स्थानांतरित कर सकते हैं।

+0

अगर मैं गलत हूं तो मुझे सही करें, लेकिन ऐसा लगता है कि एक चयन प्रकार हमेशा ओ (एन) स्वैप करेगा। साथ ही, उस मामले पर विचार करें जहां सूची पूरी तरह से हल की जाती है सिवाय इसके कि पहला तत्व अंतिम होना चाहिए। मैं जिस एल्गोरिदम की तलाश में हूं वह उस तत्व को अंत में ले जायेगा। – jnylen

+0

आप पूरी तरह से सही हैं। मैंने इसके बारे में सोचा नहीं था। – Juan

1

कुंजी और सरणी अनुक्रमणिका को ऑब्जेक्ट्स {कुंजी, अनुक्रमणिका} की एक अलग सरणी में विभाजित करें। उस सरणी को सॉर्ट करें (निश्चित रूप से आप सबसे अच्छे प्रकार का उपयोग कर सकते हैं; या तो तुलनात्मक रूप से महंगे होते हैं, या अगर वे सस्ते होते हैं तो क्विकॉर्ट)। अब आप वास्तविक इंडेक्स से क्रमबद्ध सरणी में और प्रत्येक तत्व में संग्रहीत इंडेक्स मान, मूल सरणी को पुनर्व्यवस्थित करने के तरीके के बारे में जानते हैं।

एक बार जब आप चाबियाँ हल कर लेंगे, तो "इष्टतम" चाल मूल सरणी के ओ (एन) होगी। यदि आप मूल सरणी को जगह में पुनर्व्यवस्थित करना चाहते हैं, तो आप इंडेक्स की अपनी क्रमबद्ध सूची से इंटरचेंज प्राप्त कर सकते हैं।

0

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

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