Ada dua kategori solusi untuk masalah semacam ini yang saya ketahui: lotere bias dan disaring / dihasilkan secara acak .
Pertama, mari kita keluarkan dengan solusi mudah tapi salah yang tidak membuat negara. Solusi gaya lotre apa pun yang tidak mempertahankan keadaan akan memiliki jumlah kemenangan dalam distribusi binomial, yang gagal kriteria "sebanyak" kali. Anda dapat memilih urutan acak yang mengambil semua orang sama (hanya berkeliling daftar melakukan itu; permutasi memberikan keacakan), tetapi begitu orang mulai pergi liburan urutan Anda sekarang memiliki lubang. Kecuali Anda melacak, Anda akan menemukan diri Anda dengan distribusi binomial alih-alih mempertahankan upaya yang sama.
Mari kita juga berkomitmen untuk memiliki keacakan yang sebenarnya. Anda mungkin menginginkan ini sehingga, misalnya, seseorang tidak dapat menjadwalkan liburan mereka berdasarkan algoritma deterministik sehingga mereka tidak pernah hadir ketika giliran mereka untuk membeli croissant (sampai mereka menghabiskan seluruh hari liburan mereka, saya kira) .
Jadi, ke dua jenis solusi.
Untuk membuat lotere yang bias, perhatikan terlebih dahulu bahwa kita dapat memilih dari hampir semua distribusi berkelanjutan (dengan penyimpangan terbatas) untuk menghasilkan angka untuk lotre kita. Yang kalah kemudian bisa menjadi orang dengan angka terendah. Maka bias yang paling sederhana adalah melacak apakah setiap individu telah membeli lebih atau kurang dari bagiannya. Anda dapat mengukur bias dalam satuan croissant. Anda dapat menyesuaikan tingkat keacakan dengan mengubah lebar dan bentuk distribusi - ini juga akan menentukan seberapa jauh setiap individu dapat memperoleh dari "jumlah waktu yang sama". Gaussians itu mudah; mereka memungkinkan untuk kejutan yang masuk akal tanpa memiliki ekor yang terlalu panjang ("tidak adil"). Jadi bentuk dasar dari solusinya adalah (dalam kode Scala)
case class Employee(var bias: Double) {
def eat { bias -= 1 }
def buy(n: Int) { bias += n }
def roll = bias + stdev * Random.nextGaussian
}
Anda dapat melacak siapa yang membeli terakhir dan memberi mereka bonus bias yang lumayan (mis. 10*stdev
) Agar orang tidak membeli dua kali berturut-turut kecuali pada kasus tepi di mana struktur liburan memungkinkan setiap orang membeli waktu "terakhir". (yaitu Anda membeli, lalu pergi berlibur.) Hal yang sama karena tidak hadir pada hari mereka dipilih. (Jika seseorang tidak hadir setiap hari, mereka pada akhirnya akan muncul ketika mereka membakar bonus bias mereka; saya menganggap ini sebagai fitur daripada bug.)
Jadi, Anda mengumpulkan daftar karyawan Anda saat ini untuk hari itu, minta mereka semua ikut undian, pilih yang terendah, dan perbarui. Anda dapat memilih apakah memiliki bonus pembelian sama dengan jumlah karyawan (baik ketika biaya diabaikan tetapi perjalanan untuk mendapatkan croissant memberatkan), jumlah karyawan yang hadir (baik jika perjalanan itu mudah tetapi biayanya memberatkan ), atau sesuatu di antaranya (untuk mengakui kedua beban). Mungkin lebih baik hanya memiliki hukuman "makan" untuk orang-orang yang hadir, tetapi Anda bisa melakukannya jika Anda merasa bahwa hanya berlibur tidak memberi Anda hak yang lebih sedikit.
Untuk membuat urutan acak yang difilter, pertama-tama Anda perlu membuat urutan acak. Mengacak daftar karyawan adalah cara yang baik untuk memulai. Ikuti saja daftarnya, secara berurutan, dari hari ke hari. Jika seseorang tidak dapat membeli karena mereka tidak ada atau tidak dapat diberitahu atau dibeli sebelumnya, lewati saja. Sekarang Anda memiliki masalah: Anda mengumpulkan orang-orang yang telah dilewati. Tapi tidak apa-apa. Ketika Anda sampai ke akhir urutan Anda, tambahkan daftar karyawan yang dilewati ke daftar lengkap sebelum mengocok. Sekarang probabilitas untuk datang sebanding dengan berapa kali Anda dilewati, yang mempertahankan properti "jumlah yang sama".
log2(N)NN!NNlog2[(N!NN)1/N]≈−1log(2)+log22π/N√N≈−1.4NN=10 1.14
Secara pribadi saya menyukai solusi lotre yang bias karena kontrol atas keacakan lebih baik. Dengan urutan yang difilter, Anda dapat menemukan cara yang lebih kompleks untuk menghasilkan urutan. Misalnya, daripada mengambil permutasi acak, melakukan swap lokal ke jarak tertentu, atau memungkinkan bertukar orang keluar dari kolam sepenuhnya (tetapi mereka pergi ke daftar lompatan) - tetapi hal-hal ini membutuhkan upaya yang lebih algoritmik. Dengan lotere, Anda hanya menyesuaikan standar deviasi.