"समान रूप से" आइटम वितरित करने के लिए एल्गोरिथम


25

मैं एक सूची से मूल्यों को वितरित करने के लिए एक एल्गोरिथ्म की खोज कर रहा हूं ताकि परिणामस्वरूप सूची "संतुलित" या "समान रूप से वितरित" हो सके (उद्धरणों में क्योंकि मुझे यकीन नहीं है कि ये वर्णन करने के लिए ये सबसे अच्छे तरीके हैं ... बाद में मैं यह मापने का एक तरीका प्रदान करूँगा कि क्या परिणाम अन्य की तुलना में बेहतर है)।

तो, सूची के लिए:

[1, 1, 2, 2, 3, 3]

मूल्यों को फिर से वितरित करने के बाद सबसे अच्छे परिणामों में से एक है:

[1, 2, 3, 1, 2, 3]

इस एक के रूप में अच्छे के रूप में अन्य परिणाम हो सकते हैं, और निश्चित रूप से यह मूल्यों के कम समान सेट के साथ अधिक जटिल हो जाता है।

यदि कोई परिणाम अन्य की तुलना में बेहतर है तो इसे कैसे मापा जाए:

  1. प्रत्येक आइटम और अगले आइटम के बीच की दूरी को समान मान से गिनें।

  2. दूरी के उस सेट के लिए मानक विचलन की गणना करें। एक कम फैलाव का मतलब बेहतर परिणाम है।

टिप्पणियों:

  • जब एक दूरी की गणना और सूची का अंत समान मूल्य के साथ एक आइटम को खोजने के बिना पहुंच जाता है, तो हम सूची की शुरुआत में वापस जाते हैं। तो, अधिकतम, एक ही आइटम मिलेगा और उस आइटम की दूरी सूची की लंबाई होगी। इसका मतलब है कि सूची चक्रीय है ;
  • एक विशिष्ट सूची में ~ 15 अलग-अलग मात्राओं में 15 अलग-अलग मूल्यों के साथ 50 आइटम हैं।

इसलिए:

  • परिणाम के लिए [1, 2, 3, 1, 2, 3], दूरी हैं [3, 3, 3, 3, 3, 3], और मानक विचलन है 0;
  • परिणाम के लिए [1, 1, 2, 2, 3, 3], दूरी हैं [1, 5, 1, 5, 1, 5], और मानक विचलन है 2;
  • जो पहले परिणाम को दूसरे से बेहतर बनाता है (कम विचलन बेहतर है)।

इन परिभाषाओं को देखते हुए, मैं एक एल्गोरिथ्म के बारे में पूछता हूं कि मुझे किस एल्गोरिदम या रणनीतियों की खोज करनी चाहिए।


ऐसा लगता है जैसे आप कम से कम अनुमानित रूप से विभाजन समस्या का (अनुकूलन संस्करण) हल करना चाहते हैं । उस एक के लिए शायद कई एल्गोरिदम हैं!
राफेल

इसे फिर से पढ़ना, क्यों सभी मूल्यों की घटनाओं की गणना करता है और फिर चक्रवात मानों को हमेशा इष्टतम समाधान नहीं देता है?
राफेल

जवाबों:


8

मैं इसी तरह की समस्या पर शोध करते हुए इस सवाल पर भागा: स्तरीकरण को कम करने के लिए तरल पदार्थों का इष्टतम जोड़। ऐसा लगता है कि मेरा समाधान आपकी स्थिति पर भी लागू होगा।

यदि आप 30,20,10 के अनुपात में तरल पदार्थ A, B, और C को मिलाना चाहते हैं (अर्थात A की 30 इकाइयाँ, B की 20 इकाइयाँ और C की 10 इकाइयाँ), तो आप स्तरीकरण के साथ समाप्त हो जाते हैं यदि आप सभी को जोड़ते हैं ए, फिर सभी बी, और फिर सभी सी। आप छोटी इकाइयों को मिलाकर बेहतर हैं। उदाहरण के लिए, [A, B, A, C, B, A] अनुक्रम में एकल-इकाई जोड़ करें। यह स्तरीकरण को पूरी तरह से रोक देगा।

जिस तरह से मैंने ऐसा किया है वह एक प्राथमिकता मर्ज का उपयोग करके इसे एक प्रकार का मर्ज के रूप में माना जाता है। यदि मैं परिवर्धन का वर्णन करने के लिए एक संरचना बनाता हूं:

MergeItem
    Item, Count, Frequency, Priority

फ़्रिक्वेंसी को "हर एन" के रूप में व्यक्त किया जाता है। तो A, जिसे छह में से तीन बार जोड़ा गया है, की आवृत्ति 2 (6/3) है।

और एक ढेर को शुरू करें जिसमें शुरू में शामिल हो:

(A, 3, 2, 2)
(B, 2, 3, 3)
(C, 1, 6, 6)

अब, मैं पहले आइटम को ढेर से हटाता हूं और इसे आउटपुट करता हूं। फिर इसकी गिनती 1 से कम करें और फ़्रीक्वेंसी द्वारा प्राथमिकता बढ़ाएं और इसे वापस ढेर में जोड़ें। परिणामी हीप है:

(B, 2, 3, 0)
(A, 2, 2, 4)
(C, 1, 6, 6)

अगला, बी को ढेर से हटा दें, आउटपुट करें और इसे अपडेट करें, फिर वापस हीप में जोड़ें:

(A, 2, 2, 4)
(C, 1, 6, 6)
(B, 1, 3, 6)

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

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

टिप्पणियों के बाद अपडेट करें

मुझे लगता है कि मेरी समस्या ओपी की समस्या के समान है, और इसलिए मेरा समाधान संभावित रूप से उपयोगी है। मैं ओपी के प्रश्न के संदर्भ में अपने उत्तर को अधिक नहीं बताने के लिए माफी चाहता हूं।

पहली आपत्ति, कि मेरा समाधान 0, 1, और 2 के बजाय A, B, और C का उपयोग कर रहा है, आसानी से छूट जाता है। यह केवल नामकरण की बात है। मुझे यह सोचने में आसान और कम भ्रमित लगता है और "दो 1" के बजाय "दो ए" कहा जाता है। लेकिन इस चर्चा के प्रयोजनों के लिए मैंने ओपी के नामकरण का उपयोग करने के लिए अपने आउटपुट को नीचे संशोधित किया है।

बेशक मेरी समस्या दूरी की अवधारणा से संबंधित है। यदि आप "चीजों को समान रूप से फैलाना चाहते हैं," दूरी निहित है। लेकिन, फिर से, यह पर्याप्त रूप से यह दिखाने में विफल रहा कि मेरी समस्या ओपी की समस्या के समान कैसे है।

मैंने ओपी द्वारा प्रदान किए गए दो उदाहरणों के साथ कुछ परीक्षण किए। अर्थात्:

[1,1,2,2,3,3]  // which I converted to [0,0,1,1,2,2]
[0,0,0,0,1,1,1,2,2,3]

मेरे नामकरण में वे क्रमशः [२,२,२] और [४,३,२,१] के रूप में व्यक्त किए जाते हैं। अर्थात्, अंतिम उदाहरण में, "टाइप 0 के 4 आइटम, टाइप 1 के 3 आइटम, टाइप 2 के 2 आइटम, और टाइप 3 के 1 आइटम।"

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

मैं कह सकता हूं, हालांकि, एल्गोरिथ्म तरल पदार्थ को मिलाते समय स्तरीकरण को खत्म करने की मेरी समस्या का एक अच्छा समाधान प्रदान करता है । और ऐसा लगता है कि यह ओपी की समस्या का उचित समाधान प्रदान करता है।

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

private class HeapItem : IComparable<HeapItem>
{
    public int ItemIndex { get; private set; }
    public int Count { get; set; }
    public double Frequency { get; private set; }
    public double Priority { get; set; }

    public HeapItem(int itemIndex, int count, int totalItems)
    {
        ItemIndex = itemIndex;
        Count = count;
        Frequency = (double)totalItems / Count;
        // ** Modified the initial priority setting.
        Priority = Frequency/2;
    }

    public int CompareTo(HeapItem other)
    {
        if (other == null) return 1;
        var rslt = Priority.CompareTo(other.Priority);
        if (rslt == 0)
        {
            // ** Modified to favor the more frequent item.
            rslt = Frequency.CompareTo(other.Frequency);
        }
        return rslt;
    }
}

ओपी के पहले उदाहरण के साथ अपने परीक्षण कार्यक्रम को चला रहा हूं, मुझे मिलता है:

Counts: 2,2,2
Sequence: 1,0,2,1,0,2
Distances for item type 0: 3,3
Stddev = 0
Distances for item type 1: 3,3
Stddev = 0
Distances for item type 2: 3,3
Stddev = 0

इसलिए मेरा एल्गोरिथ्म सभी काउंट्स की तुच्छ समस्या के लिए समान रूप से काम करता है।

दूसरी समस्या के लिए जो ओपी ने पोस्ट किया, मुझे मिला:

Counts: 4,3,2,1
Sequence: 0,1,2,0,1,3,0,2,1,0
Distances for item type 0: 3,3,3,1
Stddev = 0.866025403784439
Distances for item type 1: 3,4,3
Stddev = 0.471404520791032
Distances for item type 2: 5,5
Stddev = 0
Distances for item type 3: 10
Stddev = 0
Standard dev: 0.866025403784439,0.471404520791032,0,0

मुझे उस पर सुधार करने का कोई स्पष्ट तरीका नहीं दिख रहा है। इसे आइटम 0 [2,3,2,3] या 2 और 3 की कुछ अन्य व्यवस्था के लिए दूरी बनाने के लिए फिर से व्यवस्थित किया जा सकता है, लेकिन यह आइटम 1 और / या 2 के लिए विचलन को बदल देगा। मुझे वास्तव में नहीं पता कि क्या "इष्टतम" इस स्थिति में है। क्या अधिक बार या कम लगातार वस्तुओं पर एक बड़ा विचलन होना बेहतर है?

ओपी से अन्य समस्याओं को कम करते हुए, मैंने अपने स्वयं के कुछ बनाने के लिए उनके विवरण का उपयोग किया। उन्होंने अपने पोस्ट में कहा:

एक विशिष्ट सूची में ~ 15 अलग-अलग मात्राओं में 15 अलग-अलग मूल्यों के साथ 50 आइटम हैं।

तो मेरे दो परीक्षण थे:

[8,7,6,5,5,4,3,3,2,2,2,1,1,1,1]  // 51 items, 15 types
[12,6,5,4,4,3,3,3,2,2,2,1,1]     // 48 items, 13 types

और मेरे परिणाम:

Counts: 8,7,6,5,5,4,3,3,2,2,2,1,1,1,1
Sequence: 0,1,2,3,4,5,7,6,0,1,2,8,9,10,4,3,0,1,5,2,0,1,3,4,6,7,14,11,13,12,0,2,5,1,0,3,4,2,8,10,9,1,0,7,6,5,3,4,2,1,0
Distances for item type 0: 8,8,4,10,4,8,8,1
Stddev = 2.82566363886433
Distances for item type 1: 8,8,4,12,8,8,3
Stddev = 2.76272565797339
Distances for item type 2: 8,9,12,6,11,5
Stddev = 2.5
Distances for item type 3: 12,7,13,11,8
Stddev = 2.31516738055804
Distances for item type 4: 10,9,13,11,8
Stddev = 1.72046505340853
Distances for item type 5: 13,14,13,11
Stddev = 1.08972473588517
Distances for item type 6: 17,20,14
Stddev = 2.44948974278318
Distances for item type 7: 19,18,14
Stddev = 2.16024689946929
Distances for item type 8: 27,24
Stddev = 1.5
Distances for item type 9: 28,23
Stddev = 2.5
Distances for item type 10: 26,25
Stddev = 0.5
Distances for item type 11: 51
Stddev = 0
Distances for item type 12: 51
Stddev = 0
Distances for item type 13: 51
Stddev = 0
Distances for item type 14: 51
Stddev = 0

और दूसरे उदाहरण के लिए:

Counts: 12,6,5,4,4,3,3,3,2,2,2,1,1
Sequence: 0,1,2,0,3,4,7,5,6,0,1,8,9,10,0,2,0,3,4,1,0,2,6,7,5,12,11,0,1,0,3,4,2,0,1,10,8,9,0,7,5,6,0,
4,3,2,1,0
Distances for item type 0: 3,6,5,2,4,7,2,4,5,4,5,1
Stddev = 1.68325082306035
Distances for item type 1: 9,9,9,6,12,3
Stddev = 2.82842712474619
Distances for item type 2: 13,6,11,13,5
Stddev = 3.44093010681705
Distances for item type 3: 13,13,14,8
Stddev = 2.34520787991171
Distances for item type 4: 13,13,12,10
Stddev = 1.22474487139159
Distances for item type 5: 17,16,15
Stddev = 0.816496580927726
Distances for item type 6: 14,19,15
Stddev = 2.16024689946929
Distances for item type 7: 17,16,15
Stddev = 0.816496580927726
Distances for item type 8: 25,23
Stddev = 1
Distances for item type 9: 25,23
Stddev = 1
Distances for item type 10: 22,26
Stddev = 2
Distances for item type 11: 48
Stddev = 0
Distances for item type 12: 48
Stddev = 0

@DW कृपया मेरा अपडेट देखें। मुझे विश्वास है कि मैं दिखाता हूं कि मेरी समस्या ओपी की समस्या के समान है, और मेरा एल्गोरिथ्म ओपी की समस्या का समाधान कैसे प्रदान करता है।
जिम मेंथेल

अच्छी चीज़! उत्कृष्ट अद्यतन के लिए धन्यवाद। Upvoted।
DW

जैसा कि मैंने पहले कहा, काफी दिलचस्प है। विचार की सरलता आकर्षक है। मेरे पास यह सब ध्यान से पढ़ने का समय नहीं था। क्या आपका समाधान वास्तव में मूल प्रश्न की चक्रीयता को ध्यान में रखता है? इस उद्देश्य के लिए इसे अनुकूलित करने का एक तरीका हो सकता है, लेकिन मैं पूरी तरह से निश्चित नहीं हूं।
Babou

@ बाबू: मेरी दूरी की गणनाएं चारों ओर से लपेटती हैं, जैसा कि आप परिणामों में देख सकते हैं, लेकिन एल्गोरिथ्म स्वयं ओपी की समस्या के चक्रीय प्रकृति के लिए कोई विशिष्ट भत्ता नहीं देता है। न ही मुझे ऐसा कोई तरीका दिखाई दे रहा है जिससे मैं ऐसा करने के लिए एल्गोरिथ्म को अपना सकूं। या, उस मामले के लिए, चक्रीय प्रकृति को कैसे ध्यान में रखते हुए परिणामों को बेहतर किया जाएगा। हालाँकि सभी गणनाओं को दोगुना करना (यानी [3,2,1] को बदलकर [6,4,2]) करने पर विचार करना दिलचस्प है, जो प्रभावी रूप से एक ही बात होगी। मेरा संदेह यह है कि एल्गोरिथ्म समान परिणाम उत्पन्न करेगा।
जिम मिसथेल

6

यह "बदबू आ रही है" जैसे यह एनपी-हार्ड हो सकता है। तो, जब आपके पास एनपी-हार्ड समस्या है तो आप क्या करते हैं? इस पर एक अनुमानी, या एक अनुमान एल्गोरिथ्म फेंक दें, या एक सैट सॉल्वर का उपयोग करें।

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

यदि वह इतनी अच्छी तरह से काम नहीं करता है, तो मेरा दूसरा सुझाव यह होगा कि इसे एक सैट सॉल्वर में फेंक दिया जाए । आपकी समस्या का आकार इतना छोटा है कि यह सिर्फ काम कर सकता है। अपने ऑप्टिमाइज़ेशन फंक्शन से जुड़े निर्णय की समस्या से शुरू करें: , क्या कोई ऐसा समाधान है जिसका मानक विचलन (यानी, जहां विचरण )? इसे SAT उदाहरण के रूप में व्यक्त किया जा सकता है। इसे SAT के रूप में व्यक्त करना गड़बड़ होगा, लेकिन यदि आप STP जैसे फ्रंट-एंड का उपयोग करते हैं, तो यह थोड़ा आसान हो जाएगा, क्योंकि STP में पूर्णांक अंकगणित का समर्थन है। तो, आपके पास बूलियन अज्ञात हो सकता है , जहां सही है यदि सरणी का th तत्व मान रखता हैटी टी 2 एक्स मैं , जे x मैं , जे मैं j टी 2ttt2xi,jxi,jij। अब आप कुछ अड़चनों को व्यक्त कर सकते हैं कि यह मूल इनपुट का वैध क्रमांकन है। आप कुछ और पूर्णांक अज्ञात भी बना सकते हैं और बाधाओं को जोड़कर उन्हें तत्वों के बीच की दूरी के बराबर होने के लिए बाध्य कर सकते हैं, और फिर उन दूरियों के विचरण की गणना कर सकते हैं और यह कहते हुए बाधा डाल सकते हैं कि यह होना चाहिए । बेशक, सैट सॉल्वरों का सबसे खराब समय चल रहा है, इसलिए यह संभव है, इसलिए यह संभव है कि सैट सॉल्वर इस समस्या से उबरें ... लेकिन यह भी संभव है कि वे इस समस्या को संभालने में सक्षम हों। यह एक और तकनीक है जिसे आप आजमा सकते हैं।t2

लेकिन मेरा सुझाव है कि आप नकली एनालिंग के साथ शुरुआत करें। यह पहली बात है कि मैं कोशिश करूंगा, क्योंकि मुझे लगता है कि यह सिर्फ काम कर सकता है।


क्या आपके सुझाव इस प्रकार की शेड्यूलिंग समस्याओं के समाधान का मानक तरीका है। मुझे लगता है कि इसके लिए आसपास कुछ व्यावसायिक सॉफ्टवेयर है। वे इसे कैसे संभालते हैं?
बाबौ

@ बबौ, महान प्रश्न - मुझे कोई पता नहीं है!
डीडब्ल्यू

मैंने अपने एल्गोरिथ्म के विवरण को और विकसित किया, लेकिन मुझे संदेह है कि बहुत मौजूदा एप्लिकेशन इसका उपयोग करेंगे। वास्तव में, मुझे आश्चर्य है कि क्या शेड्यूलिंग एप्लिकेशन इस तरह की समस्या से निपटते हैं। मैं SE.softwarerecs के बारे में जानकारी के लिए पूछ रहा हूं, क्योंकि मैं यह नहीं देखता कि मैं यहां कैसे सवाल पूछूं, एक टिप्पणी के रूप में अन्य के रूप में जैसा मैंने अभी किया था।
बबौ

इष्टतम समाधान एनपी कठिन हो सकता है। लेकिन एक काफी व्यावहारिक समाधान ओ (एन लॉग के) है, जहां एन वस्तुओं की कुल संख्या है और कश्मीर आइटम प्रकारों की संख्या है। मेरा उत्तर, और मेरी लिंक की गई ब्लॉग पोस्ट देखें।
जिम मेंथेल

2

एक हेरास्टिक एल्गोरिथ्म का स्केच

मेरे पास इस समस्या का कोई सटीक हल नहीं है। लेकिन चूंकि राफेल की टिप्पणी यह विभाजन की समस्या की तरह दिखती है, जिसके लिए हेयोरिस्टिक एल्गोरिदम विकसित किया गया है, मैं एक हेमिस्टवादी दृष्टिकोण की कोशिश करूंगा। यह एक मात्रिक एल्गोरिथ्म का केवल एक स्केच है।

मान लें कि मानों की संख्या है, और सूची में तत्वों की संख्या है। हम सामान्यता की हानि के बिना मान हैं कि मान संख्या । प्रत्येक मान के लिए हम ध्यान दें सूची में घटनाओं की संख्या।n [ 1 .. n ] i n ivn[1..n]ini

हम पहले ध्यान दें कि एक मूल्य के सभी घटनाओं के लिए दूरी का योग । तो सूची के सभी तत्वों के लिए सभी दूरी का योग । इसलिए, सूची के सभी तत्वों के लिए औसत दूरी , अर्थात, ।v n / n vnvnvn/nv

हमारा उद्देश्य दूरी पर मानक विचलन को कम करना है, जो दूरी विचलन के वर्गों के योग को कम करता है, अर्थात और प्रत्येक दूरी के बीच अंतर ।v

जब एक मूल्य की घटनाओं को रखते हुए, हम पूर्णांक बाधाओं (और कुछ बिंदु पर स्लॉट्स पर कब्जा किया जा सकता है) तक की दूरी को बराबर करने का प्रयास करते हैं। इस तरह वे मानक विचलन में कम से कम योगदान करते हैं। यदि हम एक दूरी बढ़ाने के लिए मजबूर हैं, तो हमेशा एक को बढ़ाने के लिए बेहतर है कि कम से कम विचलन हो। एक मूल्य के लिए इष्टतम दूरी है । पूर्णांक अवरोधों को ध्यान में रखते हुए, आवृत्तियों को पूर्णांक मान का उपयोग ऊपर करना चाहिए , और अन्य बस नीचे।n / n iin/ni n / n inmodnin/ni

यह हमारे एल्गोरिथ्म का मार्गदर्शन करेगा।

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

फिर, के बाद से उन दूरी है कि सबसे अधिक विचलित होना है सबसे सटीक वर्गों का योग करने के लिए कम योगदान करने के लिए, हम जगह पर पहले मूल्यों जरूरी है कि विचलित सबसे, कोशिश यानी मूल्यों ऐसा है कि सबसे बड़ा है।| n / n i - v |i|n/niv|

यह पहली बार में बहुत कम घटनाओं के साथ एक मूल्य हो सकता है। मुझे लगता है कि इससे वास्तव में कोई फर्क नहीं पड़ता है, क्योंकि स्लॉट्स पर कब्जा करके बनाई गई बाधाएं अच्छी तरह से रखे गए मूल्यों की संख्या के अनुपात में हैं (?)।

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

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

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

फिर आप अगले शेष मान लिए दोहराएं जैसे किसबसे बड़ा है, जब तक कि सभी गैर सिंगलटन मूल्यों को रखा जाए।| n / n j - v |j|n/njv|

फिर आप शेष स्लॉट में सिंगलटन मान डालें।

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


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

@moraes मान से दूरी के औसत विचलन को घटाकर उन्हें आदेश देना क्या मायने रखता है । यह सामान्य रूप से कम से कम और सबसे आम लोगों को वैकल्पिक करेगा, इस प्रकार दोनों छोर से शुरू होता है मध्य की ओर (घटनाओं की संख्या करीब है , क्योंकि का मतलब दूरी है)। सिवाय एकल के, बिल्कुल। n / v Vvn/vV
बबौ

क्या आपका मतलब है कि, 10 मान [0, 0, 0, 0, 1, 1, 1, 2, 2, 3]और v की सूची के लिए 4, हम पहले मान 1( 10/3 = 3.33, निकटतम v से) रखेंगे , फिर 2( 10/2 = 5, अगले निकटतम), फिर 0( 10/4 = 2.5)? या: क्या आप "मूल्य v से दूरी के घटते औसत विचलन" का उदाहरण दे सकते हैं?
मोरास

1
नहीं, मैं इसके विपरीत करता हूं। आपके उदाहरण को लेते हुए, पोजिशनिंग का क्रम पहले O है क्योंकि इसका माध्य दूरी 2,5 विचलन से सबसे अधिक v = 4 है, फिर 2, फिर 1, और सिंगलटन 3. - - - ypu सुझाव दे रहा है कि मुझे और स्पष्ट रूप से लिखना चाहिए इस रणनीति के लिए मेरे स्पष्टीकरण का हिस्सा?
बाबू

नहीं यह ठीक है। मैं इस विचार के साथ कुछ कोशिश करूँगा और वापस रिपोर्ट करूँगा।
मोरास

1

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

def generate(item_counts):
'''item_counts is a list of counts of "types" of items. E.g., [3, 1, 0, 2] represents
   a list containing [1, 1, 1, 2, 4, 4] (3 types of items/distinct values). Generate
   a new list with evenly spaced values.'''
# Sort number of occurrences by decreasing value.
item_counts.sort(reverse=True)
# Count the total elements in the final list.
unplaced = sum(item_counts)
# Create the final list.
placements = [None] * unplaced

# For each type of item, place it into the list item_count times.
for item_type, item_count in enumerate(item_counts):
    # The number of times the item has already been placed
    instance = 0
    # Evenly divide the item amongst the remaining unused spaces, starting with
    # the first unused space encountered.
    # blank_count is the number of unused spaces seen so far and is reset for each
    # item type.
    blank_count = -1
    for position in range(len(placements)):
        if placements[position] is None:
            blank_count += 1
            # Use an anti-aliasing technique to prevent bunching of values.
            if blank_count * item_count // unplaced == instance:
                placements[position] = item_type
                instance += 1
    # Update the count of number of unplaced items.
    unplaced -= item_count

return placements

का परिणाम

Input counts: 8,7,6,5,5,4,3,3,2,2,2,1,1,1,1
Sum of stddev: 16.8 (vs. 22.3 via Jim Mischel)

Input of counts: 12,6,5,4,4,3,3,3,2,2,2,1,1
Sum of stddev: 18.0 (vs. 19.3 via Jim Mischel)

यदि @moraes द्वारा निर्दिष्ट फ़ॉर्म के इनपुट दिए गए हैं, तो कोई इसे बड़े ओमेगा (n * लॉग (n)) मेमोरी के बिट्स का उपयोग करके चरणों में प्रयोग करने योग्य रूप में परिवर्तित कर सकता है, जहाँ n वस्तुओं की संख्या है ( 255 तत्वों के साथ एक सूची में, आपको दोहराव की गणना के साथ समानांतर सरणी रखकर 255 अतिरिक्त बाइट्स की आवश्यकता नहीं होगी। वैकल्पिक रूप से, कोई O (1) अतिरिक्त मेमोरी के साथ इन-प्लेस सॉर्ट कर सकता है।

पुनश्च

import numpy
import collections

def evaluate(l):
    '''Given a distribution solution, print the sum of stddevs for each type in the solution.'''
    l2 = l * 2
    distances = [None] * len(l)
    distance_dict = collections.defaultdict(list)
    for i in range(len(l)):
        distances[i] = l2.index(l[i], i + 1) - i
        distance_dict[l[i]].append(l2.index(l[i], i + 1) - i)

    keys = list(distance_dict.keys())
    keys.sort()
    score = 0
    # Calculate standard deviations for individual types.
    for key in keys:
        sc = numpy.std(distance_dict[key])
        score += sc
    print('Stddev sum: ', score)

संपादित करें: मुझे पता है कि यह समाधान काउंटरएक्सप्लिमेंट द्वारा इष्टतम उत्पादन नहीं करता है। [6, 2, 1]उत्पादन का एक इनपुट [0, 1, 0, 0, 2, 0, 0, 1, 0]; एक बेहतर उपाय है [0, 0, 1, 0, 2, 0, 0, 1, 0]


मुझे विश्वास है कि मैंने अपने एल्गोरिथ्म को कोड टिप्पणियों में और प्रस्तावना में एल्गोरिथ्म का आधार समझाया।
लंगज

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

0

यह एल्गोरिदम पूर्णांक के एक सरणी के साथ काम करता है, जहां प्रत्येक पूर्णांक एक अलग श्रेणी का प्रतिनिधित्व करता है। यह प्रत्येक श्रेणी के लिए अलग-अलग सरणियाँ बनाता है। उदाहरण के लिए, यदि शुरुआती सरणी [1, 1, 1, 2, 2, 3] है, तो यह तीन सरणियाँ बनाएगी, [3], [2, 2], [1, 1, 1]।

वहाँ से यह दो छोटी से छोटी सरणियों (इस उदाहरण में, [3], और [2,2]) को जोड़ता है और छोटे सरणी के तत्वों के स्थान को दूसरे सबसे छोटे सरणी में स्थान देता है जो अधिकतर संख्या के अनुपात के आधार पर होता है। बड़े बनाम छोटी श्रेणियों की घटनाओं का। इस उदाहरण में, हम [2,3,2] के साथ आगे बढ़ेंगे। तब यह इस सरणी का उपयोग छोटे सरणी के रूप में करेगा जिसे अगले बड़े सरणी में जोड़ा जाएगा, जब तक कि केवल एक सरणी शेष न हो।

<?php
/**
 *This will separete the source array into separate arrays for each category
 */
function splitArrayByCategory($source) {

    //  index is the category, value is the tally
    $categoryCounts  = array_count_values($source);

    // Sort that list, keep index associations
    asort($categoryCounts);

    // build separate arrays for each category
    // index = order, smaller index = smaller category count
    // value = array of each category
    $separated = array();
    foreach ($categoryCounts as $category => $tally)
        $separated[] = array_fill(0, $tally, $category);

    return $separated;
}

/**
 * Will take the array of arrays generated by splitArrayByCategory, and merge
 * them together so categories are evenly distributed
 */
function mergeCategoryArrays($categoryArray) {

    // How many entries are there, for the smallest & second smallest categories
    $smallerCount = count($categoryArray[0]);
    $largerCount  = count($categoryArray[1]);

    // Used to determine how much space there should be between these two categories
    $space = $largerCount/$smallerCount;

    // Merge the array of the smallest category into the array of the second smallest
    foreach ($categoryArray[0] as $domIndex => $domain) {
        // Where should we splice the value into the second array?
        $location = floor($domIndex*$space+$domIndex+($space/2));
        // actually perform the splice
        array_splice($categoryArray[1], $location, 0, $domain);
    }

    // remove the smallest domain we just spliced into the second smallest
    unset($categoryArray[0]);

    // reset the indexes
    $categoryArray = array_values($categoryArray);

    // If we have more than one index left in the categoryArray (i.e. some things
    // still need to get merged), let's re-run this function,
    if (count($categoryArray)>1)
        $categoryArray = mergeCategoryArrays($categoryArray);

    return $categoryArray;
}

// The sample list we're working with.
// each integer represents a different category
$listSample = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,6,6,7,7,7,7];

// Split the sample list into separate arrays for each category
$listSplitByCategory = splitArrayByCategory($listSample);

// If there are not at least two categories, what's the point?
if (count($listSplitByCategory) < 2) throw new Exception("You need at least two categories");

// perform the actual distribution of categories.
$listEvenlyDistributed = mergeCategoryArrays($listSplitByCategory)[0];

// Display the array before and after the categories are evenly distributed
for ($i=0; $i<count($listSample); $i++) {
    print $listSample[$i].",";
    print $listEvenlyDistributed[$i]."\n";
}

2
यह एक कोडिंग साइट नहीं है। कृपया कोड-केवल उत्तर पोस्ट न करें। इसके बजाय, हम चाहते हैं कि आप अपने उत्तर के पीछे के विचारों की व्याख्या करें, और अपने एल्गोरिथ्म के लिए एक संक्षिप्त छद्म कोड प्रदान करें।
DW

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

स्पष्टीकरण वहाँ है। टिप्पणी प्रदर्शन कोड में; जो एपीएल जैसे कुछ पुरातन वाक्यविन्यास में नहीं है, लेकिन सिंटेक्स को समझने के लिए एक आसान छद्म कोड के लिए पर्याप्त है। अगर मेरी व्याख्या मोनोपेस फॉन्ट में नहीं होती तो क्या यह मदद करता?
vtim

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

-1

एएनएसआई सी कोड

यह कोड दिशात्मक वेक्टर (v1, v2, ..., vi, ... vn) के साथ मूल के माध्यम से गुजर रहा है जहां आयामी अंतरिक्ष (जहां n श्रेणियों की संख्या है) में एक सीधी रेखा की कल्पना करके काम करता है जहां vi की संख्या है श्रेणी I में आइटम। मूल से शुरू करने का उद्देश्य लाइन के अगले निकटतम बिंदु को खोजना है। उदाहरण का उपयोग करते हुए [0 0 0 0 1 1 1 2 2 2 3] यह परिणाम पैदा करता है [0 1 2 0 3 1 0 2 0 1 2 2]। लुंगज के उदाहरण का उपयोग करते हुए [0 0 0 0 0 1 1 2 2] हमें [0 1 0 0 2 0 0 1 1 0] मिलता है, जो बिल्कुल लुंगज के परिणाम के समान है।

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

#define MAXCATEGORIES 100

int main () {int i = 0; int j = 0; int catize = 0; int वेक्टर [MAXCATEGORIES]; int बिंदु [MAXCATEGORIES]; int श्रेणियां = 0; int Totalitems = 0; int best = 0; लंबी d2 = 0L; लंबी वीपी = 0 एल; लंबी v2 = 0L; लंबा डेल्टा = 0 एल; लंबा बीटा = 0 एल;

printf("Enter the size of each category (enter 0 to finish):\r\n");
do
{
    catsize = 0;
    #ifdef _MSVC_LANG
            scanf_s("%d", &catsize);
    #else
            scanf("%d", &catsize)
    #endif
    if (catsize > 0)
    {
        vector[categories] = catsize;
        totalitems += catsize;
        categories++;
    }
} while (catsize > 0);

for (i = 0; i < categories; i++)
{
    v2 += vector[i] * vector[i];
    point[i] = 0;
}

for (i = 0; i < totalitems; i++)
{
    for (j = 0; j < categories; j++)
    {
        delta = (2 * point[j] + 1)*v2 - (2 * vp + vector[j])*vector[j];
        if (j == 0 || delta < beta)
        {
            best = j;
            beta = delta;
        }
    }
    point[best]++;
    vp += vector[best];
    printf("%c ", best + '0');  // Change '0' to 'A' if you like letters instead
}
return 0;

}


1
साइट पर आपका स्वागत है! फ़ॉर्मेटिंग-वार, आपको अपने कोड की प्रत्येक पंक्ति को चार स्थानों के साथ इंडेंट करने की आवश्यकता है ताकि सिस्टम को मार्क-अप सही मिले। सामान्य तौर पर, हम प्रश्नों के उत्तर के रूप में कोड के बड़े ब्लॉकों की तलाश नहीं करते हैं और विशेष रूप से, आपके डेटा प्रविष्टि रूटीन यहां कुछ भी नहीं जोड़ रहे हैं। आपके पास अपने पोस्ट के शीर्ष पर कुछ स्पष्टीकरण है, लेकिन उस पर विस्तार करना और कोड में कटौती करना बेहतर होगा।
डेविड रिचेर्बी

यह एक कोडिंग साइट नहीं है। कृपया कोड-केवल उत्तर पोस्ट न करें। इसके बजाय, हम चाहते हैं कि आप अपने उत्तर के पीछे के विचारों की व्याख्या करें, और अपने एल्गोरिथ्म के लिए एक संक्षिप्त छद्म कोड प्रदान करें।
DW

-1

मेरा समाधान:

    vc = train['classes'].value_counts()
    vc = dict(sorted(vc.items()))
    df = pd.DataFrame()
    train['col_for_sort'] = 0.0

    i=1
    for k,v in vc.items():
        step = train.shape[0]/v
        indent = train.shape[0]/(v+1)
        df2 = train[train['classes'] == k].reset_index(drop=True)
        for j in range(0, v):
        df2.at[j, 'col_for_sort'] = indent + j*step + 0.0001*i   
    df= pd.concat([df2,df])
    i+=1

    train = df.sort_values('col_for_sort', ascending=False).reset_index(drop=True)
    del train['col_for_sort']

कृपया अपने एल्गोरिथ्म का वर्णन करने के लिए छद्मकोड (कुछ आवश्यक टिप्पणियों के साथ) का उपयोग करें।
xskxzr

यह एक कोडिंग साइट नहीं है। कृपया कोड-केवल उत्तर पोस्ट न करें। इसके बजाय, हम चाहते हैं कि आप अपने उत्तर के पीछे के विचारों की व्याख्या करें, और अपने एल्गोरिथ्म के लिए एक संक्षिप्त छद्म कोड प्रदान करें।
DW
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.