Algoritma untuk persentase tanpa mengetahui jumlah total

17

Misalkan ada ngaris untuk hotline.

Setiap kali pelanggan menelepon hotline, panggilan diteruskan ke salah satu njalur. Dan saya ingin menetapkan persentase panggilan ke masing-masing n baris. Misalkan ada dua saluran dan satu saluran ditugaskan 60% dan lainnya adalah 40%, jumlah total panggilan adalah 10 sehingga saluran pertama akan menerima 6 panggilan dan yang kedua akan mendapatkan 4 panggilan.

Saya tahu persentase panggilan ke setiap saluran di muka tetapi masalahnya adalah saya tidak tahu jumlah panggilan yang akan diterima dalam sehari.

Bagaimana saya bisa mendistribusikan jumlah panggilan tanpa mengetahui total panggilan?

akku
sumber
2
Setelah saluran 1 mendapat 6 panggilan, berikan saluran 2 4 panggilan. Artinya, tidak peduli dengan jumlah total aktual, peduli tentang distribusi selama "periode" (10, dalam hal ini) yang Anda tahu. Jelas Anda dapat melakukan hal-hal seperti baris alternatif kecuali nilai terakhir, jadi tidak perlu menunggu ketat juga. Jika ada semacam antrian, lakukan persentase berdasarkan baris saat ini dalam antrian.
Clockwork-Muse
apa itu "asterisk" dan "DID"?
agas
@ Clockwork-Muse: Saya akan menyarankan pembulatan pada bilangan bulat di sini daripada mempertahankan distribusi 6-4. Kalau tidak, distribusi Anda akan dimatikan kecuali Anda tahu Anda memiliki kelipatan 10 panggilan. Misalnya, jika 6 total panggilan masuk, pendekatan yang Anda sarankan akan menetapkan semuanya ke jalur A; sedangkan pendekatan yang lebih benar adalah 4 ke A dan 2 ke B (ditugaskan dalam urutan ABAABA jika Anda membulatkan total penugasan integer untuk setiap baris)
Flater

Jawaban:

26

Lakukan beberapa pembukuan tentang panggilan yang sudah diambil dan hitung distribusinya melalui n baris. Ini memberi Anda n nilai persentase (distribusi yang sudah Anda capai), yang dapat dibandingkan dengan n persentase yang ingin Anda capai. Setiap kali ada panggilan baru, tetapkan panggilan itu ke saluran dengan penyimpangan tertinggi dari nilai target (perhatikan bahwa selama Anda tidak menekan distribusi yang diberikan dengan tepat, selalu ada garis yang memiliki terlalu sedikit panggilan sejauh ini, bila dibandingkan dengan target distribusi).

Misalnya: setelah menetapkan panggilan pertama ke saluran 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: Pendekatan ini dapat lebih ditingkatkan dengan tidak menggunakan perbedaan absolut, tetapi memilih garis yang meminimalkan jumlah kuadrat dari semua penyimpangan. Itu juga akan memberi Anda hasil yang lebih baik jika Anda mencapai nilai target dengan tepat.

Doc Brown
sumber
2
Anda mungkin ingin mengubah referensi "selama" menjadi "lebih eksplisit" menggunakan tiebreak yang berbeda, FWIW.
DougM
@DougM: lihat edit saya.
Doc Brown
5
  • Misalkan jumlah pekerja kurang dari 100
  • Buat array pekerja dengan kapasitas 100
  • Masukkan array yang pekerja beberapa kali sama dengan persentase panggilan yang harus dia dapatkan, misalnya jika pekerja1 harus mendapatkan 30% dari semua panggilan, kemudian menempatkannya di posisi 0 hingga 29 dari array.
  • Pada akhirnya setiap posisi array harus digunakan, dan pekerja harus muncul dalam array sebanyak persentase panggilan yang harus mereka terima.
  • Dalam satu lingkaran, buat angka acak antara 0 dan 99, dan tetapkan panggilan masuk ke pekerja di posisi array tersebut. Jika pekerja sibuk, ulangi.
  • Dengan begitu, di luar kemungkinan belaka, panggilan akan didistribusikan sesuai keinginan
  • Dalam contoh saya, pekerja1 memiliki peluang 30/100 untuk dipilih pada setiap iterasi yang diberikan.
Tulains Córdova
sumber
4

Saya setuju dengan solusi @ DocBrown. Menempatkannya dalam bentuk algoritma:

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 ditentukan oleh persentase aktual dikurangi persentase yang diharapkan dari suatu garis. Dengan cara ini, mereka yang memiliki delta negatif terbesar adalah mereka yang paling membutuhkan panggilan untuk menyesuaikan dengan persentase yang diharapkan.

    Misalnya, dalam kasus di mana persentase yang diharapkan untuk jalur 1 dan 2 masing-masing adalah 60% dan 40%, dan persentase aktualnya adalah 50% dan 50%, Anda akan melihat garis pemesanan 1 diikuti oleh baris 2, karena -10 % kurang dari 10%. Karenanya saluran 1 akan menerima telepon.

    Saya sangat merekomendasikan menggunakan jenis penyisipan karena berkinerja terbaik ketika sebagian besar array sudah diurutkan.

Juga, sebagai optimasi kecil, jika Anda melacak jumlah total panggilan sejauh ini, daripada harus menghitung persentase aktual dari setiap baris, Anda dapat menghitung jumlah total panggilan untuk saluran itu dikurangi persentase yang diharapkan untuk itu baris kali jumlah total panggilan (delta = t_i - p_i * T). Dalam kasus ini, delta hanyalah jumlah panggilan negatif untuk mencapai persentase yang diharapkan.

Saya harap itu menjelaskan keraguan lainnya.

Neil
sumber
terima kasih @Neil Anda benar-benar membantu saya tetapi ketika keduanya mencapai sasaran sehingga baris mana yang harus saya hubungi, apakah ada kriteria untuk itu.
akku
@akku Dengan algoritme saya, Anda cukup mengambil yang pertama setelah mengurutkan, artinya algoritme tidak peduli. Jika Anda memiliki kriteria lain untuk diterapkan, Anda harus membuatnya sesuai saat Anda mengurutkannya. Dengan kata lain, jika nomor baris penting, maka Anda harus mengambil delta, kalikan dengan jumlah total baris, lalu tambahkan nomor baris saat ini. Itu mendukung nomor baris yang lebih tinggi, dengan anggapan semuanya sama.
Neil
@ Neil: jawaban Anda baik-baik saja, tetapi setiap kali saya melihat seseorang menyarankan untuk mengurutkan array sepenuhnya hanya untuk menemukan nilai minimum, saya pikir "Hebat Scott, apakah ini benar-benar diperlukan?"
Doc Brown
@DocBrown O(n)adalah apa yang dapat Anda harapkan menyortir daftar yang sudah diurutkan dengan jenis penyisipan dan O(n)apa yang harus Anda gunakan untuk menemukan nilai terkecil. Saya hanya berasumsi telah diurutkan.
Neil
@ Neil: hanya karena dua algoritma keduanya O (n), mereka tidak sama sederhana (atau sama cepatnya).
Doc Brown
2

Asumsi seperti yang dinyatakan OP

  1. Jumlah garis, n, diketahui dan;
  2. % Dari setiap baris diketahui

Desain Algoritma

  1. Tentukan setiap baris dengan% nya

  2. Urutkan setiap baris dengan posisinya menjauh dari 0 yang didefinisikan sebagai (% saat ini dari pekerja - yang ditugaskan% dari pekerja) atau dengan penetapan acak jika semua baris = 0

  3. Teruskan setiap panggilan ke saluran terbesar dari 0

Contoh: 3 baris dengan% masing-masing 20, 30 dan 50. Pada titik x dalam waktu 1 orang memanggil dan karena setiap saluran 0 dari 0, maka akan ditugaskan secara acak - katakanlah ke saluran 2 yang harus menampung 30% dari semua panggilan. Karena saluran 2 harus menahan 30% dari semua panggilan dan sekarang memegang 100% dari semua panggilan, posisinya dari 0 meningkat. Penelepon berikutnya sekarang akan ditugaskan untuk jalur 1 atau jalur 3 dll hingga keseimbangan (0) dan dengan demikian loop berulang dengan sendirinya.

tanpa henti
sumber
0

Ini adalah solusi naif dan tidak mengasumsikan apa pun selain akan memungkinkan distribusi berbasis persentase. Solusi ini dapat ditingkatkan dalam banyak hal tetapi inilah intinya. Saya tidak yakin apakah ini yang Anda cari tetapi itu akan memberi Anda distribusi yang benar.

kode 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
Odnxe
sumber