Algoritmo per percentuale senza conoscere il numero totale

17

Supponiamo che ci siano n di linee per una hotline.

Ogni volta che un cliente chiama la hotline, la chiamata viene inoltrata a una delle righe n . E voglio assegnare la percentuale di chiamate a ciascuna delle n linee. Supponiamo che ci siano due linee e una linea sia assegnata al 60% e l'altra al 40%, il numero totale di chiamate è 10, quindi la prima linea riceverà 6 chiamate e la seconda riceverà 4 chiamate.

Conosco la percentuale di chiamate a ciascuna linea in anticipo, ma il problema è che non conosco il numero di chiamate che verrebbero ricevute in un giorno.

Come posso distribuire il numero di chiamate senza conoscere le chiamate totali?

    
posta akku 27.06.2014 - 08:28
fonte

5 risposte

26

Fai un po 'di contabilità sulle chiamate già fatte e calcola la loro distribuzione sulle n linee. Questo ti dà n valori percentuali (la tua distribuzione già raggiunta), che può essere paragonata alle n percentuali che vuoi raggiungere. Ogni volta che arriva una nuova chiamata, assegna quella chiamata alla linea con la deviazione più alta dal valore target (nota che finché non si preme esattamente la distribuzione data, c'è sempre una linea che ha ricevuto così poche chiamate fino a quel momento, rispetto alla distribuzione target).

Ad esempio: dopo aver assegnato la prima chiamata alla linea 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

...

EDIT: Questo approccio potrebbe essere ulteriormente migliorato non usando la differenza assoluta, ma scegliendo la linea che minimizza la somma dei quadrati di tutte le deviazioni. Ciò ti darebbe anche un risultato migliore nel caso in cui raggiungi esattamente i valori target.

    
risposta data 27.06.2014 - 08:37
fonte
5
  • Supponiamo che il numero di lavoratori sia inferiore a 100
  • Crea un array di lavoratori con una capacità di 100
  • Inserisci in quell'array un numero di volte uguale alla percentuale di chiamate che deve ricevere, ad esempio se worker1 dovrebbe ricevere il 30% di tutte le chiamate, quindi inserirlo nelle posizioni da 0 a 29 dell'array.
  • Alla fine dovrebbe essere usata ogni posizione dell'array, e gli operatori dovrebbero apparire nell'array tante volte quante sono le percentuali delle chiamate che dovrebbero ricevere.
  • In un ciclo, genera un numero casuale compreso tra 0 e 99 e assegna la chiamata in arrivo al lavoratore in quella posizione dell'array. Se il lavoratore è occupato, ripeti.
  • In questo modo, per pura probabilità, le chiamate verranno distribuite come desiderato
  • Nel mio esempio, worker1 ha una probabilità 30/100 di essere scelto in una determinata iterazione.
risposta data 27.06.2014 - 23:59
fonte
4

Sono d'accordo con la soluzione di @ DocBrown. Inserendolo in un modulo algoritmo:

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 è determinato dalla percentuale effettiva meno la percentuale prevista di una linea. In questo modo, quelli con il delta negativo più grande sono quelli che più richiedono una chiamata per conformarsi alla percentuale prevista.

    Ad esempio, nel caso in cui le percentuali previste per le linee 1 e 2 siano rispettivamente del 60% e del 40% e le loro percentuali effettive sono 50% e 50%, vedresti la linea di ordine 1 seguita dalla linea 2, dal -10% è inferiore al 10%. Quindi la linea 1 otterrebbe la chiamata.

    Raccomando caldamente di usare l'ordinamento per inserzione poiché è il migliore quando l'array è già in gran parte ordinato.

Inoltre, come ottimizzazione minore, se si tiene traccia del numero totale di chiamate fino a quel momento, piuttosto che dover calcolare la percentuale effettiva di ogni riga, è sufficiente calcolare il numero totale di chiamate per quella linea meno il previsto percentuale per quella linea moltiplicata per il numero totale di chiamate (delta = t_i - p_i * T). In questo caso il delta è semplicemente il numero negativo di chiamate per raggiungere la percentuale prevista.

Spero che chiarisca ogni altro dubbio.

    
risposta data 27.06.2014 - 11:09
fonte
2

I presupposti come OP hanno indicato

  1. Il numero di righe, n, è noto e
  2. La% di ogni riga è nota

Algorithm Design

  1. Definisci ogni riga in base al%

  2. Ordina ogni riga in base alla sua posizione a partire da 0 definito come (% attuale di lavoratori - assegnato% di lavoratori) o casuale se tutte le linee = 0

  3. Inoltra ogni chiamata alla riga più grande a partire da 0

Esempio: 3 righe con% di 20, 30 e 50 rispettivamente. Al punto x nel tempo 1 persona chiama e poiché ogni linea è 0 lontano da 0, viene assegnato in modo casuale, ad esempio alla riga 2 che dovrebbe contenere il 30% di tutte le chiamate. Poiché la linea 2 dovrebbe contenere il 30% di tutte le chiamate e ora detiene il 100% di tutte le chiamate, la sua posizione da 0 aumenta. Il prossimo chiamante verrebbe ora assegnato alla linea 1 o alla linea 3 ecc. Fino all'equilibrio (0) e quindi il ciclo si ripeterà.

    
risposta data 29.06.2014 - 11:44
fonte
0

Questa è una soluzione ingenua e non assume nient'altro che consentirebbe una distribuzione basata sulla percentuale. Questa soluzione potrebbe essere migliorata in molti modi, ma questo è il succo di ciò. Non sono sicuro se questo è ciò che stai cercando, ma ti darebbe una vera distribuzione.

codice 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
    
risposta data 27.06.2014 - 19:02
fonte

Leggi altre domande sui tag