Algorithmus für Prozentsatz ohne Kenntnis der Gesamtzahl

17

Angenommen, es gibt nLeitungen für eine Hotline.

Wenn ein Kunde die Hotline anruft, wird der Anruf an eine der nLeitungen weitergeleitet. Und ich möchte jeder der n Leitungen einen Prozentsatz der Anrufe zuweisen. Angenommen, es gibt zwei Leitungen und eine Leitung ist mit 60% und die andere mit 40% belegt. Die Gesamtzahl der Anrufe beträgt 10, sodass die erste Leitung 6 Anrufe empfängt und die zweite 4 Anrufe erhält.

Ich kenne den Prozentsatz der Anrufe zu jeder Leitung im Voraus, aber das Problem ist, dass ich nicht weiß, wie viele Anrufe an einem Tag eingehen würden.

Wie kann ich die Anzahl der Anrufe verteilen, ohne die Gesamtanzahl der Anrufe zu kennen?

akku
quelle
2
Rufen Sie Leitung 2 4 an, nachdem Leitung 1 6 Anrufe erhalten hat. Das heißt, Sie sollten sich nicht um die tatsächliche Gesamtzahl kümmern, sondern um die Verteilung über den "Zeitraum" (in diesem Fall 10), den Sie kennen. Offensichtlich können Sie Dinge wie alternative Zeilen mit Ausnahme des letzten Werts tun, so dass auch keine strikte Wartezeit erforderlich ist. Wenn es eine Art Warteschlange gibt, geben Sie den Prozentsatz basierend auf den aktuellen Zeilen in der Warteschlange an.
Clockwork-Muse
was ist "asterisk" und "DID"?
gnat
@ Clockwork-Muse: Ich würde vorschlagen, hier ganze Zahlen zu runden, anstatt die 6-4-Verteilung beizubehalten. Andernfalls wird Ihre Verteilung deaktiviert, es sei denn, Sie wissen, dass Sie genau ein Vielfaches von 10 Anrufen haben. Wenn z. B. insgesamt 6 Anrufe eingehen, werden diese von Ihrem Lösungsvorschlag alle der Leitung A zugewiesen. wohingegen eine korrektere Annäherung 4 zu A und 2 zu B wäre (in der Reihenfolge ABAABA zugewiesen, wenn Sie auf ganzzahlige Zuweisungssummen für jede Zeile runden)
Flater

Antworten:

26

Führen Sie eine Buchhaltung über die bereits angenommenen Anrufe durch und berechnen Sie deren Verteilung auf die n Leitungen. Dies gibt Ihnen n Prozentwerte (Ihre bereits erreichte Verteilung), die mit den n Prozentwerten verglichen werden können, die Sie erreichen möchten. Wenn ein neuer Anruf eingeht, weisen Sie diesen Anruf der Leitung mit der größten Abweichung vom Zielwert zu (beachten Sie, dass es immer eine Leitung gibt, die zu wenige Anrufe hat, solange Sie die angegebene Verteilung nicht genau treffen.). im Vergleich zur Zielverteilung).

Zum Beispiel: Nach dem Zuweisen des ersten Anrufs zu Leitung 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

...

BEARBEITEN: Dieser Ansatz könnte weiter verbessert werden, indem nicht die absolute Differenz verwendet wird, sondern die Linie gewählt wird, die die Quadratsumme aller Abweichungen minimiert. Das würde auch zu einem besseren Ergebnis führen, wenn Sie die Zielwerte genau erreichen.

Doc Brown
quelle
2
Möglicherweise möchten Sie dies ändern, "solange" eine explizitere Referenz "Verwenden Sie einen anderen Tiebreaker", FWIW.
DougM
@DougM: siehe mein edit.
Doc Brown
5
  • Nehmen wir an, die Anzahl der Arbeiter liegt unter 100
  • Erstellen Sie eine Reihe von Mitarbeitern mit einer Kapazität von 100
  • Platzieren Sie einen Arbeiter so oft in diesem Array, wie es dem Prozentsatz der Anrufe entspricht, die er erhalten soll. Wenn beispielsweise Arbeiter1 30% aller Anrufe erhalten soll, platzieren Sie ihn in den Positionen 0 bis 29 des Arrays.
  • Am Ende sollte jede Position des Arrays verwendet werden, und die Arbeiter sollten so oft im Array erscheinen, wie der Prozentsatz der Anrufe, die sie erhalten sollten.
  • Generieren Sie in einer Schleife eine Zufallszahl zwischen 0 und 99 und weisen Sie den ankommenden Anruf dem Arbeiter an dieser Position des Arrays zu. Wenn der Arbeiter beschäftigt ist, wiederholen.
  • Auf diese Weise werden die Anrufe aus reiner Wahrscheinlichkeit wie gewünscht verteilt
  • In meinem Beispiel hat worker1 eine Chance von 30/100, bei einer bestimmten Iteration ausgewählt zu werden.
Tulains Córdova
quelle
4

Ich stimme der Lösung von @ DocBrown zu. Platzieren Sie es in einem Algorithmus-Formular:

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
  • Delta wird durch den tatsächlichen Prozentsatz minus dem erwarteten Prozentsatz einer Linie bestimmt. Auf diese Weise sind diejenigen mit dem größten negativen Delta diejenigen, bei denen ein Anruf am meisten erforderlich ist, um den erwarteten Prozentsatz einzuhalten.

    Beispiel: In dem Fall, in dem die erwarteten Prozentsätze für die Zeilen 1 und 2 60% bzw. 40% betragen und die tatsächlichen Prozentsätze 50% und 50% betragen, wird in der Reihenfolge Zeile 1 gefolgt von Zeile 2 angezeigt, seit -10 % ist weniger als 10%. Daher würde Leitung 1 den Anruf erhalten.

    Ich empfehle dringend, die Einfügesortierung zu verwenden, da sie am besten funktioniert, wenn das Array bereits größtenteils sortiert ist.

Als geringfügige Optimierung können Sie auch einfach die Gesamtzahl der Anrufe abzüglich des erwarteten Prozentsatzes für jede Leitung berechnen, wenn Sie die Gesamtzahl der bisherigen Anrufe verfolgen, anstatt den tatsächlichen Prozentsatz für jede Leitung berechnen zu müssen line mal die Gesamtzahl der Anrufe (Delta = t_i - p_i * T). In diesem Fall ist das Delta einfach die negative Anzahl von Anrufen, um den erwarteten Prozentsatz zu erreichen.

Ich hoffe, das klärt alle anderen Zweifel.

Neil
quelle
danke @Neil du hast mir wirklich geholfen aber wenn beide die Marke getroffen haben, welche Leitung soll ich dann anrufen, gibt es irgendwelche Kriterien dafür.
Akku
@akku Bei meinem Algorithmus nehmen Sie einfach immer den ersten nach dem Sortieren, was bedeutet, dass es dem Algorithmus egal ist. Wenn Sie ein anderes Kriterium anwenden müssen, müssen Sie es beim Sortieren entsprechend wiegen lassen. Mit anderen Worten, wenn die Zeilennummer wichtig ist, sollten Sie das Delta nehmen, mit der Gesamtzahl der Zeilen multiplizieren und dann die aktuelle Zeilennummer hinzufügen. Dies begünstigt höhere Zeilennummern, vorausgesetzt, alle anderen sind gleich.
Neil
@Neil: Ihre Antwort ist in Ordnung, aber wenn ich jemanden sehe, der vorschlägt, ein Array komplett zu sortieren, um den Mindestwert zu finden, denke ich: "Großartiger Scott, ist das wirklich notwendig?"
Doc Brown
@DocBrown O(n)ist das, was Sie erwarten können, wenn Sie eine bereits sortierte Liste mit Einfügesortierung sortieren, und O(n)das, was Sie verwenden müssen, um den kleinsten Wert zu finden. Ich gehe einfach davon aus, dass es sortiert ist.
Neil
@Neil: Nur weil zwei Algorithmen beide O (n) sind, sind sie nicht gleich einfach (oder gleich schnell).
Doc Brown
2

Annahmen wie OP angegeben

  1. Die Anzahl der Zeilen n ist bekannt und;
  2. Der Prozentsatz jeder Zeile ist bekannt

Algorithmus-Design

  1. Definiere jede Zeile durch%

  2. Sortieren Sie jede Zeile nach ihrer von 0 entfernten Position, definiert als (aktueller Prozentsatz der Beschäftigten - zugeordneter Prozentsatz der Beschäftigten) oder nach zufälliger Zuordnung, wenn alle Zeilen = 0 sind

  3. Leiten Sie jeden Anruf an die größte Leitung weiter, die von 0 entfernt ist

Beispiel: 3 Zeilen mit einem Prozentsatz von 20, 30 bzw. 50. Zum Zeitpunkt x ruft 1 Person an und da jede Leitung 0 von 0 entfernt ist, wird sie zufällig zugewiesen - sagen wir zu Leitung 2, die 30% aller Anrufe halten sollte. Da Leitung 2 30% aller Anrufe halten sollte und jetzt 100% aller Anrufe hält, erhöht sich ihre Position von 0. Der nächste Anrufer würde nun entweder Leitung 1 oder Leitung 3 usw. bis zum Gleichgewicht (0) zugewiesen und die Schleife wiederholt sich.

unerbittlich
quelle
0

Dies ist eine naive Lösung und setzt nichts voraus, würde aber eine prozentuale Verteilung ermöglichen. Diese Lösung könnte in vielerlei Hinsicht verbessert werden, aber das ist der Kern der Sache. Ich bin mir nicht sicher, ob dies das ist, wonach Sie suchen, aber es würde Ihnen wahre Verbreitung geben.

Pseudocode ...

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
Odnxe
quelle