कुल संख्या को जाने बिना प्रतिशत के लिए एल्गोरिदम


17

मान लीजिए कि nएक हॉटलाइन के लिए लाइनें हैं ।

जब भी कोई ग्राहक हॉटलाइन पर कॉल करता है, तो कॉल को एक nपंक्ति में भेज दिया जाता है । और मैं प्रत्येक n लाइनों को कॉलिंग का प्रतिशत असाइन करना चाहता हूं। मान लीजिए कि दो लाइनें हैं और एक लाइन 60% दी गई है और अन्य 40% है, कुल कॉल की संख्या 10 है, इसलिए पहली पंक्ति में 6 कॉल प्राप्त होंगी और दूसरी में 4 कॉल प्राप्त होंगी।

मैं प्रत्येक पंक्ति को कॉल करने का प्रतिशत पहले से जानता हूं लेकिन समस्या यह है कि मुझे एक दिन में प्राप्त होने वाली कॉल की संख्या नहीं पता है।

मैं कुल कॉल को जाने बिना कॉल की संख्या कैसे वितरित कर सकता हूं?


2
लाइन 1 के बाद 6 कॉल मिलती हैं, लाइन 2 4 कॉल दें। यही है, वास्तविक कुल गणना के बारे में परवाह नहीं है, "अवधि" (10, इस मामले में) के वितरण के बारे में परवाह है जिसे आप जानते हैं। जाहिर है आप अंतिम मूल्य को छोड़कर वैकल्पिक लाइनों की तरह सामान कर सकते हैं, इसलिए कोई सख्त प्रतीक्षा आवश्यक नहीं है। यदि किसी प्रकार की कतार है, तो कतार में वर्तमान पंक्तियों के आधार पर प्रतिशत करें।
क्लॉकवर्क-म्यूजर्स

"Asterisk" और "DID" क्या है?
गन्नत

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

जवाबों:


26

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

उदाहरण के लिए: पहली कॉल को पंक्ति 1 में निर्दिष्ट करने के बाद:

 total calls line1      total calls line2    perc.line 1    perc. line 2
 1                      0                    100%             0% 
                                             *above 60%      *below 40% <- next call to 2
 1                      1                    50%             50% 
                                             * below 60%:    *above40% next to line1
 2                      1                    66%             33%
                                             *above 60%      *below 40% <- next to line 2
 2                      2                    50%             50% 
                                             * below 60%:    *above40% next to line1
 3                      2                    60%             40% 
                                             * both hit the mark: next call arbitrary
 4                      2                    66%             33%
                                             *above 60%      *below 40% <- next to line 2
 4                      3                    57.1%             42.85%
                                             *below 60%      *above 40% <- next to line 1

...

संपादित करें: पूर्ण अंतर का उपयोग न करके इस दृष्टिकोण को और बेहतर बनाया जा सकता है, लेकिन उस पंक्ति को चुनना जो सभी विचलन के योग-वर्गों को कम करता है। यदि आप लक्ष्य मानों तक पहुँचते हैं तो इससे आपको बेहतर परिणाम मिलेगा।


2
आप चाहते हैं कि "जब तक" अधिक स्पष्ट "एक अलग टाईब्रेकर का उपयोग करें" संदर्भ, एफडब्ल्यूआईडब्ल्यू बदलना चाहते हैं।
डगएम

@DougM: मेरा संपादन देखें।
डॉक ब्राउन

5
  • मान लीजिए कि श्रमिकों की संख्या 100 से कम है
  • 100 की क्षमता वाले श्रमिकों की एक सरणी बनाएं
  • उस सरणी में एक कर्मी को कई बार कॉल प्राप्त करने के प्रतिशत के बराबर संख्या में होना चाहिए, उदाहरण के लिए यदि वर्कर 1 को सभी कॉल का 30% मिलना चाहिए, तो उसे सरणी के 0 से 29 के पदों पर रखें।
  • अंत में सरणी की प्रत्येक स्थिति का उपयोग किया जाना चाहिए, और श्रमिकों को सरणी में दिखाई देना चाहिए जितनी बार कॉल प्राप्त होनी चाहिए।
  • एक लूप में, 0 और 99 के बीच एक यादृच्छिक संख्या उत्पन्न करते हैं , और सरणी की उस स्थिति में कार्यकर्ता को आने वाली कॉल असाइन करते हैं। यदि कार्यकर्ता व्यस्त है, तो दोहराएं।
  • इस तरह, सरासर संभावना से बाहर, कॉल वांछित के रूप में वितरित किया जाएगा
  • मेरे उदाहरण में, कार्यकर्ता 1 में किसी भी दिए गए पुनरावृत्ति पर चुने जाने का 30/100 मौका है।

4

मैं @ DocBrown के समाधान से सहमत हूं। इसे एक एल्गोरिथम रूप में रखना:

for each incoming call:
    sort lines ascending by delta* (see footnote below)

    // first element in array gets the call 
    increase number of calls for first element by 1
  • डेल्टा वास्तविक प्रतिशत से एक रेखा के अपेक्षित प्रतिशत से निर्धारित होता है। इस तरह, सबसे बड़े नकारात्मक डेल्टा वाले वे हैं जिन्हें सबसे अधिक अपेक्षित प्रतिशत के अनुरूप कॉल की आवश्यकता होती है।

    उदाहरण के लिए, उस स्थिति में, जिसमें लाइनों 1 और 2 के लिए अपेक्षित प्रतिशत क्रमशः 60% और 40% हैं, और उनका वास्तविक प्रतिशत 50% और 50% है, तो आप क्रमांक 1 को पंक्ति 2 के बाद देखेंगे, -10 के बाद से % 10% से कम है। इसलिए लाइन 1 को कॉल मिलेगा।

    मैं अत्यधिक सम्मिलन प्रकार का उपयोग करने की सलाह देता हूं क्योंकि यह सबसे अच्छा प्रदर्शन करता है जब सरणी पहले से ही अधिक होती है।

इसके अलावा, एक मामूली अनुकूलन के रूप में, यदि आप प्रत्येक पंक्ति के वास्तविक प्रतिशत की गणना करने के बजाय इस प्रकार की कुल संख्याओं पर नज़र रखते हैं, तो आप बस उस पंक्ति की कुल संख्याओं की गणना कर सकते हैं, इसके लिए अपेक्षित प्रतिशत घटा सकते हैं। कॉल की कुल संख्या को लाइन बार (डेल्टा = t_i - p_i * T)। इस मामले में डेल्टा केवल अपेक्षित प्रतिशत प्राप्त करने के लिए कॉल की नकारात्मक संख्या है।

मुझे उम्मीद है कि किसी भी अन्य संदेह को स्पष्ट करता है।


धन्यवाद @ नील आपने वास्तव में मेरी मदद की लेकिन जब दोनों ने निशान मारा तो मुझे किस लाइन पर कॉल करना चाहिए, क्या इसके लिए कोई मापदंड है।
अक्कू

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

@ नील: आपका उत्तर ठीक है, लेकिन जब भी मैं किसी को न्यूनतम मान खोजने के लिए किसी सरणी को पूरी तरह से सॉर्ट करने का सुझाव देता हूं, मुझे लगता है कि "ग्रेट स्कॉट, क्या यह वास्तव में आवश्यक है?"
डॉक ब्राउन

@DocBrown O(n)वह है जो आप प्रविष्टि सॉर्ट के साथ पहले से ही सॉर्ट की गई सूची को सॉर्ट करने की अपेक्षा कर सकते हैं और O(n)वह है जो आपको सबसे छोटे मूल्य को खोजने के लिए उपयोग करना होगा। मुझे लगता है कि यह क्रमबद्ध है।
नील

@ नील: सिर्फ इसलिए कि दो एल्गोरिदम दोनों ओ (एन) हैं, वे समान रूप से सरल (या समान रूप से तेज़) नहीं हैं।
डॉक ब्राउन

2

जैसा कि ओपी ने कहा है

  1. लाइनों की संख्या, एन, ज्ञात है और;
  2. प्रत्येक पंक्ति का% ज्ञात है

एल्गोरिदम डिजाइन

  1. प्रत्येक पंक्ति को उसके% द्वारा परिभाषित करें

  2. प्रत्येक पंक्ति को 0 से दूर अपनी स्थिति के अनुसार क्रमबद्ध करें (वर्करों के वर्तमान% - वर्करों का%%) या यादृच्छिक असाइनमेंट द्वारा यदि सभी पंक्तियाँ = 0

  3. प्रत्येक कॉल को 0 से दूर सबसे बड़ी लाइन पर अग्रेषित करें

उदाहरण: क्रमशः 20, 30 और 50% के साथ 3 लाइनें। समय में बिंदु 1 पर 1 व्यक्ति कॉल करता है और चूंकि हर लाइन 0 से 0 दूर है, यह बेतरतीब ढंग से असाइन किया गया है - लाइन 2 पर कहें, जिसमें सभी कॉल का 30% होना चाहिए। चूंकि पंक्ति 2 में सभी कॉलों का 30% होना चाहिए और अब सभी कॉलों का 100% धारण करना चाहिए, 0 से इसकी स्थिति बढ़ जाती है। अगला कॉलर अब या तो लाइन 1 या लाइन 3 आदि को समतुल्य (0) तक सौंपा जाएगा और इस प्रकार लूप खुद को दोहराता है।


0

यह एक भोला समाधान है और कुछ भी नहीं मानता है लेकिन प्रतिशत आधारित वितरण की अनुमति देगा। इस समाधान में कई तरह से सुधार किया जा सकता है लेकिन यह इसका सार है। मुझे यकीन नहीं है कि यह वही है जो आप देख रहे हैं लेकिन यह आपको सच्चा वितरण देगा।

psuedo कोड ...

int running_total_of_calls = 0

//This is hard coded for clarity. You'd most likely want to dynamically populate this array depending and probably distribute the work by alternating workers. Notice how "worker1" appears 6 out of 10 times in the array.
string[] worker = new string[10]
workers[0] = "worker1"
workers[1] = "worker1"
workers[2] = "worker1"
workers[3] = "worker1"
workers[4] = "worker1"
workers[5] = "worker1"
workers[6] = "worker2"
workers[7] = "worker2"
workers[8] = "worker2"
workers[9] = "worker2"

while(1) //run forever
    //This is where the distribution occurs. 
    //first iteration: 0 modulus 10 = 0. 
    //second: 1 modulus 10 = 1
    //third: 2 modulus 10 = 2
    //...
    //10th: 10 modulus 10 = 0
    //11th: 11 modulus 10 = 1 
    //12th: 12 modulus 10 = 2
    //...
    int assigned_number = running_total_of_calls % workers.Count //count of workers array
    string assigned_worker = workers[assigned_number]
    do_work(assigned_worker)
    running_total_of_calls = ++running_total_of_calls
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.