पैथोलॉजिकल सॉर्टिंग


15

पैथोलॉजिकल सॉर्टिंग

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

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

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

उदाहरण के लिए, कोई एक प्रविष्टि सॉर्ट एल्गोरिथ्म सबमिट कर सकता है, जिसमें अच्छा डेटा डेटा है जो पहले से ही लगभग सॉर्ट किया गया है, और खराब डेटा पूरी तरह से यादृच्छिक डेटा है, क्योंकि प्रविष्टि सॉर्ट लगभग-सॉर्ट किए गए डेटा पर O (n) से संपर्क करता है। हालाँकि, यह बहुत अच्छा नहीं है, क्योंकि मेरे बॉस शायद यह नोटिस करेंगे कि परीक्षण के सभी डेटा को लगभग शुरू करने के लिए क्रमबद्ध किया गया है।

यह एक , इसलिए 7 दिन (21 मई) के बाद सबसे अधिक वोटों के साथ जवाब मिला।

अगर कोई मुझे नहीं मारता है, तो मैं एक समुदाय विकी उत्तर प्रस्तुत करना चाहता हूं जो समान रूप से वितरित डेटा सेट का लाभ उठाता है।


इस प्रश्न के करीब आने वालों के लिए संभवतः उपयोगी / दिलचस्प संसाधन: "साइकिक सॉर्टिंग एल्गोरिदम" (अस्वीकरण: उस लेख के लेखक और मैं बहुत करीब हैं ।:-P)
HostileFork का कहना है कि SE पर भरोसा मत करो

जवाबों:


9

यह एक बहुत लंबा समय रहा है, लेकिन मुझे याद है कि एल्गोरिथम 101 में हमें कुछ सॉर्टिंग एल्गोरिदम सिखाया गया था जो यादृच्छिककरण का उपयोग करता था। मैं बहुत अच्छा छात्र नहीं था, इसलिए मुझे वास्तव में याद नहीं है कि यह कैसे चला गया या इसने औसतन जल्दी काम क्यों किया।

फिर भी, मैंने फैसला किया है कि यह समस्या एक समाधान के लिए कॉल करती है जो यादृच्छिककरण का उपयोग करती है, जो औसत रूप से मेरे पक्ष में काम करेगी।

import random

def arrayIsSorted (arr) :
    for i in range(len(arr)-1) :
        if arr[i]>arr[i+1] : return False
    return True

def rSort (arr) :
    random.seed (42)
    counter = 0
    while not arrayIsSorted(arr) :
        random.shuffle (arr)
        counter+=1
    print ("Sorted in %d iterations." % counter)
    return arr

चूंकि सही यादृच्छिकरण महत्वपूर्ण है, मैं जीवन, ब्रह्मांड और सब कुछ के जवाब के साथ आरएनजी को बीज बनाना सुनिश्चित करता हूं। थोड़ा परीक्षण करने के बाद यह पता चला कि यह एक चतुर चाल थी! देखें कि कितनी तेजी से इन 2 पूरी तरह से मनमानी सूचियों को क्रमबद्ध किया जाता है:

rSort ([6,1,4,2,3,7,5])
rSort ([8,9,6,1,4,7,2,3,5])

इन दोनों को केवल 1 पुनरावृत्ति में क्रमबद्ध किया जाता है - आप संभवतः इससे तेज कार्य के लिए नहीं पूछ सकते हैं!

अब, माना जाता है कि, कुछ अन्य सूचियाँ थोड़ा खराब परिणाम देती हैं ...

rSort ([5,1,4,2,3,7,6])
rSort ([8,9,6,1,4,7,2,5,3])

ये क्रमशः 4,176 और 94,523 पुनरावृत्तियों में क्रमबद्ध हो जाते हैं, जो वास्तव में एक सेकंड से अधिक समय लेता है ... लेकिन चलो बस इस तथ्य को अपने आप तक रखें ताकि किसी को भी इस एल्गोरिदम से कितना विचलित न हो!

संपादित करें:

मुझे 100 वस्तुओं की सूची में अपने एल्गोरिथ्म की दक्षता साबित करने के लिए कहा गया है, इसलिए यहां आप जाएं:

rSort ([70, 6, 52, 97, 85, 61, 62, 48, 30, 3, 11, 88, 39, 91, 98, 8, 54, 92, 44, 65, 69, 21, 58, 41, 60, 76, 27, 82, 93, 81, 20, 94, 22, 29, 49, 95, 40, 19, 55, 42, 43, 1, 0, 67, 35, 15, 51, 31, 16, 25, 5, 53, 37, 74, 86, 12, 13, 72, 56, 32, 47, 46, 59, 33, 80, 4, 45, 63, 57, 89, 7, 77, 14, 10, 34, 87, 18, 79, 9, 66, 24, 99, 64, 26, 78, 38, 90, 28, 83, 75, 68, 2, 17, 73, 96, 71, 23, 84, 36, 50])

यहां तक ​​कि यह लंबी और पूरी तरह से मनमानी सूची तुरंत हल हो जाती है! सच में मैं दुनिया में सबसे अच्छा छँटाई एल्गोरिथ्म पर ठोकर खाई होगी!


3
क्या हम थोड़े बड़े डेटासेट पर कुछ परीक्षा परिणाम प्राप्त कर सकते हैं? शायद 100 तत्वों के साथ एक? ;)
ज्योबिट्स

@Geobits कोई समस्या नहीं, यहाँ यह है :)
Tal

1
@Geobits हाँ यह करता है। अंततः।
ताल

3
यह एक खिंचाव है, लेकिन यह तर्क दिया जा सकता है कि यह बोगोसॉर्ट का उपयोग करता है, जो अंततः सरणी को छाँटेगा, पर्याप्त समय दिया जाएगा। मैं शर्त लगाने के लिए तैयार हूँ कि 'फेरबदल और दोहराना' उकसाने के योग्य है, भले ही अच्छी छँटाई न हो।
मिलिन

1
अगर यह सच यादृच्छिक फेरबदल था, हो सकता है। PRNGs का एक चक्र होता है, इसलिए मैं यह नहीं देख सकता कि आप कैसे सभी परमिट की गारंटी दे सकते हैं।
जियोबिट्स

2

यदि आप अपना स्वयं का डेटा बना सकते हैं, तो यह बहुत सीधा है - ऐसा डेटा प्राप्त करें जो यादृच्छिक दिखता है, लेकिन इसमें तेजी से छंटनी की कुंजी भी शामिल है। अन्य सभी डेटा मूल छँटाई विधि का उपयोग करते हैं, इसलिए औसत समय बेहतर होता है।

एक आसान तरीका यह सुनिश्चित करना है कि प्रत्येक डेटा आइटम में एक अद्वितीय कुंजी है, और फिर बस हैश कीज़ है। उदाहरण के लिए एक सूची को १,१०,००० से संख्याओं के साथ लीजिए, १६ से गुणा करके, और ०-१५ में से एक यादृच्छिक संख्या के साथ इसे जोड़ा गया (देखें fillArray () नीचे देखें)। वे यादृच्छिक दिखेंगे, लेकिन प्रत्येक के पास एक अद्वितीय अनुक्रमिक कुंजी है। छंटाई के लिए, 16 से विभाजित करें (सी में >> 4 बहुत तेज है) और फिर बस इंडेक्स के रूप में परिणामी कुंजी का उपयोग करके एक सरणी में संख्या को रखें। एक पास और आप कर रहे हैं। परीक्षण में, मैंने पाया कि दस लाख नंबरों पर एस्कॉर्ट 30 गुना धीमा था।

void fillArray(int *a,int len)
{
  for (int i=0;i<len;++i)
    a[i]=(i<<4)|(rand()&0xF);
  // shuffle later
}
void sortArray(int *a,int len)
{
  int key=0;
  int *r=new int[len];
  for (int i=0;i<len;++i)
  {
    key=a[i]>>4;
    r[key]=a[i];
  }
  memcpy(a,r,len*sizeof(int));
  delete[] r;
}
void shuffleArray(int *a,int len)
{
  int swap=0, k=0;
  for (int i=0;i<len;++i)
  {
    k=rand()%len;
    swap=a[k];
    a[k]=a[i];
    a[i]=swap;
  }
}
int qCompare(const void*a,const void*b)
{
  int result=*((int*)a)-*((int*)b);
  return result;
}
void main()
{
  int aLen=10000;
  int *a=new int[aLen];
  srand (time(NULL));
  fillArray(a,aLen);
  // time them
  long t0=0, d0=0, d1=0;
  // qsort
  shuffleArray(a,aLen);
  t0=::GetTickCount();
  qsort(a,aLen,sizeof(int),&qCompare);
  d0=::GetTickCount()-t0;
  // oursort
  shuffleArray(a,aLen);
  t0=::GetTickCount();
  sortArray(a,aLen);
  d1=::GetTickCount()-t0;
  delete[] a;
}

कोई भी चीज़ जिसके पास एक अद्वितीय कुंजी है, उसे इस तरह से सॉर्ट किया जा सकता है - यदि आपके पास इसे स्टोर करने की मेमोरी है, तो निश्चित रूप से। उदाहरण के लिए, कई डेटाबेस एक विशिष्ट संख्यात्मक ग्राहक आईडी का उपयोग करते हैं - यदि सूची छोटी / अनुक्रमिक रूप से पर्याप्त है तो इसे मेमोरी में रखा जा सकता है। या किसी अनूठे नंबर में रिकॉर्ड का अनुवाद करने का कोई और तरीका। अधिक जानकारी के लिए, हैश सोर्ट्स पर शोध करें, क्योंकि यही है ...

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