Kalender / Perencanaan algoritma

24

Saya menghadapi masalah saya tidak yakin bagaimana cara mendekati. Saya harus membuat kalender untuk karyawan, masing-masing dari mereka memiliki batasan kerja tertentu (beberapa pribadi, beberapa umum)

Apa yang saya kerjakan:

  • Saya punya Dokter
  • Setiap dokter harus bekerja 5 hari / minggu.
  • Setiap dokter harus bekerja 1 malam / minggu
  • Setiap dokter harus bekerja dalam jumlah malam yang sama dibandingkan dengan dokter lain (atau sedekat mungkin)
  • Setiap dokter harus bekerja dalam jumlah yang sama dari malam Kamis dan malam minggu dibandingkan dengan dokter lain (atau sedekat mungkin)
  • Beberapa dokter tidak dapat bekerja pada hari / malam tertentu (diinput oleh pengguna)
  • Beberapa dokter ingin bekerja pada hari / malam tertentu (diinput oleh pengguna)
  • Beberapa dokter ingin tidak bekerja pada hari / malam tertentu (diinput oleh pengguna)

Pengguna yang dimaksud adalah orang yang berurusan dengan kalender, saya mencoba membangun solusi yang secara otomatis akan menghasilkan kalender yang mematuhi semua kendala. Solusinya hanyalah pengaturan besar input "tambah dokter" dan "tambah kendala" untuk setiap dokter, lalu tombol "hasilkan kalender". Ini sangat mendasar bagi pengguna.

Masalahku :

Saya tidak yakin bagaimana membuat perencanaan yang sebenarnya, saya sudah membaca tentang Neural Networks, Genetic Algorithms, dan sebagainya, dan mereka semua tampak semacam solusi yang tepat tetapi juga tidak terlalu.

Ketika saya melihat GA, mereka dibuat untuk menemukan solusi dengan populasi tertentu (masalah saya), tetapi populasi awal harus mematuhi serangkaian kendala yang diberikan, yang kemudian akan dioptimalkan. Dalam hal ini, populasi awal saya sudah menjadi solusinya. Saya tidak perlu "dioptimalkan". Tidak masalah bahwa satu orang bekerja 3 malam Senin berturut-turut, selama itu benar dan orang lain bekerja dengan jumlah yang sama, itu berarti orang lain juga akan bekerja 3 malam Senin di beberapa titik dan tidak masalah. Yang membuat saya berpikir bahwa GA terlalu "maju" untuk saya, karena masalah saya sudah diselesaikan dengan titik awal GA.

Tapi sekali lagi, GA benar-benar terlihat seperti dibuat untuk ini, jadi saya mungkin tidak memahaminya dengan benar?

Ngomong-ngomong, karena saya belum pernah menggunakan GAS (atau jaringan saraf, atau semacamnya), saya ingin memastikan saya akan menggunakan pendekatan yang benar sebelum terlibat dalam kurva pembelajaran seperti itu.

Pertanyaan saya :

Menurut Anda apa pendekatan / algoritma / teknik yang baik untuk masalah seperti masalah saya? Gas? Jaringan saraf? Sesuatu yang sama sekali berbeda?

Saya semua mendengar dan terbuka untuk rincian lebih lanjut jika perlu, tapi saya pikir saya sudah membuat diri saya cukup jelas :)

Gil Sand
sumber
22
Mungkin layak untuk melihat literatur di sekitar masalah daftar perawat en.wikipedia.org/wiki/Nurse_scheduling_problem
Renaud M.
Istilah yang nyaman! Hehe, terima kasih atas tautannya;)
Gil Sand
8
Saya bukan ahli dalam bidang ini, namun jika apa yang Anda cari adalah pendekatan yang akan membuat Anda menghemat waktu dalam pengembangan, mungkin ada baiknya mencoba memodelkan masalah ini sebagai Masalah Pemrograman Bilangan Campuran ( en.wikipedia. org / wiki / Linear_programming # Integer_unknowns ) dan kemudian masukan ke pemecah MIP, atau sebagai masalah pemrograman kendala dan kemudian masukkan ke pemecah CP, seperti alat-OR ( developers.google.com/optimization ). Dengan cara ini yang harus Anda lakukan adalah mengungkapkan masalah Anda.
Renaud M.
3
Pemrograman Linier dijamin untuk mendapatkansolusi optimal !
recursion.ninja
2
@RenaudM. Sangat disayangkan betapa sedikit programmer profesional yang memahami bidang matematika yang sangat berguna ini. Setiap kali seseorang menyarankan simulasi anil atau algoritma genetika di luar bidang AI, respons usus saya adalah: Mungkin dapat dimodelkan lebih baik sebagai pengoptimalan Program Linier
recursion.ninja

Jawaban:

14

Algoritma Genetika dan Jaringan Saraf Tiruan tidak cocok di sini. Mereka adalah meta-heuristik untuk menemukan solusi perkiraan yang cukup bagus untuk suatu masalah. Khususnya, keduanya mengharuskan Anda untuk menemukan fungsi biaya untuk menilai solusi kandidat. Setelah Anda memiliki fungsi biaya seperti itu, mungkin akan lebih mudah untuk membuat algoritma yang mengoptimalkan biaya ini secara manual.

Ini adalah pemikiran penting: mengingat dua jadwal, kita perlu cara untuk memutuskan apakah jadwal A atau jadwal B adalah "lebih baik". Anda telah mendaftar berbagai kriteria, tetapi tidak jelas bagaimana mereka berhubungan. Apakah gagal memenuhi satu kriteria gagal seluruh solusi? Atau apakah sebagian gagal karena kendala hanya menjadikannya solusi yang lebih buruk daripada yang lain?

Pada level paling dasar, Anda bisa mempartisi minggu menjadi slot waktu yang terpisah, dan memaksa semua kombinasi slot-dokter dengan kasar. Namun, Anda dapat menggunakan batasan yang gagal untuk mengurangi ruang pencarian ini ke ukuran yang lebih mudah dikelola. Pembatasan waktu kerja dan shift malam tampaknya cocok untuk pembatasan ruang pencarian seperti itu. Anda kemudian dibiarkan dengan ratusan solusi kandidat.

Untuk memilih solusi kandidat terbaik, Anda perlu menentukan peringkat mereka. Ini cukup mudah jika satu kendala lunak lebih diutamakan daripada semua kendala lunak lainnya, misalnya jika dokter tidak dapat mengerjakan shift tertentu, yang diberikan lebih penting daripada dokter yang tidak ingin mengerjakan shift itu. Tapi saya tidak bisa memutuskan aturan ini untuk Anda - itu adalah keputusan manajerial. Lebih sulit jika dua kendala lunak tidak memiliki prioritas yang jelas, dalam hal ini Anda harus membuat semacam fungsi biaya yang menyatukan pentingnya dua kendala dalam satu metrik tunggal.


Saya mungkin akan membangun algoritma serakah yang mengisi tabel waktu kosong sesuai dengan beberapa kriteria yang diprioritaskan. Ini mungkin bukan solusi yang paling optimal, tetapi jauh lebih mudah daripada berfilsafat tentang apa yang sebenarnya "optimal" maksudkan.

Sebagai langkah pertama, Anda bisa mengisi shift malam di akhir pekan, dan mencoba memilih dokter yang belum melakukan shift malam akhir pekan untuk waktu yang lama, juga dengan mempertimbangkan keinginan pengguna "Saya tidak bisa bekerja di sana" . Dengan asumsi bahwa keinginan ini adalah per minggu dan tidak berkelanjutan, ini berarti dokter yang tidak dapat bekerja pada malam akhir pekan selama satu minggu akan dipilih minggu depan.

Prosedur serupa dapat digunakan untuk malam-malam lainnya: setelah mencoba menghormati keinginan pengguna, Anda mengisi dokter sesuai dengan yang belum melakukan shift malam untuk waktu terlama. Prosedur ini diulangi dengan cara yang sama untuk slot waktu jenis ketiga, hari berganti. Jika dua keinginan pengguna tidak dapat direkonsiliasi, Anda dapat melacak seberapa sering keinginan pengguna dikabulkan, dan kemudian memprioritaskan dokter dengan keinginan yang diberikan lebih sedikit.

Sayangnya, saya dapat melihat beberapa cara untuk memainkan sistem ini: misalnya jika seorang dokter akan dipilih untuk bekerja pada shift malam akhir pekan tetapi memasukkan permintaan "tidak dapat bekerja di sana", pilihan mereka akan ditunda satu minggu - mengurangi jumlah mereka. frekuensi malam akhir pekan bergeser dengan mengorbankan kolega mereka. Jika prosedur resolusi permintaan diterapkan yang melihat jumlah permintaan yang ditolak, pengguna dapat mengajukan beberapa permintaan yang tidak mungkin untuk meningkatkan satu permintaan yang ingin mereka lalui. Namun, dengan asumsi itikad baik (dan fleksibilitas bagi dokter untuk bertukar shift satu sama lain), algoritma seperti itu harus menghasilkan solusi yang cukup baik.

amon
sumber
Terima kasih atas jawaban Anda, saya akan menggali sedikit lebih dalam dengan kolega saya :) Untuk memberi Anda lebih banyak informasi: ya, kami dapat menentukan peringkat sebagian besar solusi / kriteria, dan kami dapat memutuskan apakah ada yang lebih diutamakan daripada yang lain. Juga, mereka benar-benar bekerja dengan itikad baik sekarang, dan itu bekerja dengan baik. Mereka dong dengan tangan dan tidak menggunakan "aku tidak bisa bekerja hari itu" terlalu banyak. Cukup bagus bagaimana mereka bisa bekerja sekarang karena mereka benar-benar melakukannya dengan tangan . Jadi solusi yang "layak" sudah akan berarti dunia bagi mereka, dan menyelamatkan mereka BANYAK waktu brainstorming siapa yang bisa bekerja ketika
Gil Sand
5
@Zil, orang-orang yang saat ini membuat jadwal mungkin sudah menggunakan algoritma informal. Anda bisa berbicara dengan mereka dan mencoba memahami proses keputusan mereka, kemudian memformalkan dan mengimplementasikannya. Ini akan menjadi cara yang lebih mudah daripada mengatur dan melatih jaringan saraf.
amon
Itu langkah pertama kami: p kami sudah mengadakan pertemuan dengan mereka! Terima kasih atas semua bantuan Anda :)
Gil Sand
3
Untuk kasus penggunaan ini, Algoritma Genetika secara konsisten lebih rendah daripada Tabu Search dan Simulasi Annealing, sebagaimana dibuktikan oleh kompetisi penelitian Kompetisi Perawat Internasional. (Tapi tentu saja, mereka masih lebih baik daripada hanya algo serakah.)
Geoffrey De Smet
12

Anda dapat menggunakan anil simulasi .

Saya melakukan sesuatu seperti itu sebelum saya mendapatkan pekerjaan pertama saya - lihat https://vimeo.com/20610875 (demo mulai pukul 2:50, algoritma menjelaskan dari 6:15).

Simulated annealing adalah jenis algoritma genetika, dan mungkin itu tidak cocok secara teori (seperti @amon pertahankan dalam jawabannya ), tetapi itu bekerja dengan sangat baik dalam praktiknya, dan itu tentang kasus penggunaan yang sama seperti milik Anda.

Kode sumber tersedia (C #), tetapi ketika bekerja, itu mengerikan. Sayangnya, beberapa tahun yang lalu dan menjadi autodidak, saya tidak tahu apa-apa tentang pemeliharaan. Ini menghasilkan hasil yang sangat bagus.

Singkatnya, cara kerjanya singkat:

  • Buat 1 jadwal waktu yang mungkin (mungkin tidak terlalu bagus, tapi mungkin secara fisik) sebagai titik awal. Algoritme genetika tidak diperlukan pada saat ini - Anda hanya bisa memaksa jalan Anda ke solusi pertama yang dapat Anda temukan. Saya menggunakan backtracking . Kompleksitas komputasi dapat diatasi dengan menyelesaikan rasio untuk setiap hari secara terpisah. Jika tidak ada solusi sama sekali (seperti kasusnya), pada titik inilah Anda mendeteksinya.

  • Buat kumpulan solusi - katakanlah, 100 salinan solusi entry-level ini sebagai permulaan.

  • Mutasikan setiap solusi secara acak: minta dokter menukar shift antara satu sama lain, lepaskan dokter secara acak dari shift mereka dan letakkan orang yang tersedia secara acak di dalamnya.

  • Evaluasi setiap solusi dengan fungsi kebugaran yang menentukan seberapa baik itu. Satu pria bekerja lebih banyak malam daripada yang lain? Kurangi poin penalti. Seseorang ingin melakukan hari Senin tetapi tidak? Kurangi poin penalti lagi.

  • Ambil - katakan - 20 solusi terbaik dan salin masing - masing 5 kali, timpa sisa 80 dengan mereka, sehingga membawa mereka ke generasi berikutnya. Kelangsungan hidup yang terkuat.

  • Bilas & ulangi.

Angka jelas sewenang-wenang, Anda mungkin perlu mengutak-atik parameter untuk mengetahui pengaturan optimal untuk skenario Anda.

Adapun untuk bermutasi solusi, anil simulasi memberikan sesuatu yang disebut suhu. Pada dasarnya itu berarti bahwa pada awalnya Anda harus bermutasi solusi Anda cukup keras (katakanlah, selalu melakukan 10 upaya bertukar shift dalam sekali jalan) dan secara bertahap menjadi kurang agresif dengan iterasi berikutnya, sehingga mereka menjadi lebih dari fine-tuning (katakanlah, turun untuk hanya 2 upaya tweak per generasi).

Konrad Morawski
sumber
4
Saya telah menggunakan OptaPlanner (nee Drools Planner) dengan Simulasi Annealing untuk jadwal kuliah. Nyatakan model - Pergeseran punya waktu dan Doktor. Menulis aturan deklaratif untuk fungsi kebugaran - kendala keras (Dokter tidak dapat mengambil shift yang tumpang tindih) dan hukuman (Ann membenci Senin). Menulis deklaratif (itulah intinya!) Swap bergantian. OptaPlanner akan membuat keadaan awal secara acak (mungkin tidak mungkin), menghitung fungsi kebugaran dari aturan dan bahkan mengoperasikan swap sesuai dengan algoritma pengoptimalan. Anda dapat memilih dan menyetel parameter seperti jadwal anil.
Jesvin Jose
6

Algoritma Genetika berlaku di sini. Selama program sarjana saya, salah satu rekan saya menulis makalah untuk masalah Anda yang sangat mirip.

Anda dapat mencari Penjadwalan Job Shop dan juga Open Shop Scheduling atau Flow Shop Scheduling dapat menjadi titik awal yang menarik

Untuk menggunakan algoritma genetika Anda tidak memerlukan solusi yang sempurna, Anda bisa mulai dengan N kandidat acak, dan menerapkan fungsi kebugaran untuk masing-masing, misalnya:

  • Perbedaan malam yang ditetapkan antara dokter paling sibuk dan kurang sibuk bekerja adalah hukuman dalam fungsi biaya
  • Setiap kali seorang dokter bekerja lebih dari 5 hari per minggu atau 1 malam per minggu, Anda menerapkan penalti
  • Setiap kendala Anda, dll ...

Menghasilkan kandidat N Anda akan memilih X terbaik dari mereka , mereka akan menjadi orang-orang yang menimbulkan kendala semakin sedikit. Bekerja dengan mereka, menyeberang dan bermutasi selama beberapa generasi seseorang dapat berakhir dengan solusi yang baik.

Setelah berbicara tentang semua itu, setiap kali saya menggunakan Algoritma Genetika yang lebih mengandalkan mutasi yang pada persimpangan, saya dapat mengembangkan Annealing Simulasi yang akan melakukan jauh lebih baik, dengan implementasi yang lebih mudah. Biaya / kebugaran dan fungsi mutasi untuk algoritma genetika mungkin akan sangat mirip dengan yang digunakan dalam Annealing Simulasi. Saya akan mulai dari sana, lihat jawaban @Konrad Morawski

Pencarian Google menemukan hasil yang baik untuk Job Shop dan GA

RMalke
sumber