Diberikan daftar poin, temukan jalur terpendek yang mengunjungi semua titik dan kembali ke titik awal.
Masalah Travelling Salesman terkenal di bidang ilmu komputer, seperti banyak cara untuk menghitung / memperkirakannya. Sudah dipecahkan untuk kelompok poin yang sangat besar, tetapi beberapa yang terbesar membutuhkan banyak CPU-tahun untuk menyelesaikannya.
Jangan sampai terbakar oleh kentang.
Hot Potato adalah gim di mana 2+ pemain mengedarkan "kentang" dalam lingkaran sambil memainkan musik. Tujuannya adalah untuk meneruskannya ke pemain berikutnya dengan cepat. Jika Anda memegang kentang saat musik berhenti, Anda keluar.
Objek dari Penjual Kentang Panas adalah:
Dengan seperangkat 100 poin unik , kembalikan poin-poin itu dalam urutan yang lebih baik ( jarak total lebih pendek seperti yang didefinisikan lebih jauh ke bawah ). Ini akan "meneruskan" masalahnya ke pemain berikutnya. Mereka harus meningkatkan dan meneruskannya ke yang lain, dll. Jika seorang pemain tidak dapat meningkatkannya, mereka keluar dan bermain terus sampai satu pemain tersisa.
Agar ini tidak menjadi kompetisi "brute-force-me-a-path", ada ketentuan berikut:
Anda tidak dapat mengambil lebih dari satu menit untuk melewatkan kentang. Jika Anda belum menemukan dan memberikan solusi yang lebih singkat saat satu menit berlalu, Anda keluar.
Anda tidak dapat mengubah posisi lebih dari 25 poin. Tepatnya,
>= 75
poin harus berada di posisi yang sama dengan yang Anda terima. Tidak masalah mana yang Anda putuskan untuk diubah, hanya jumlah yang Anda ubah.
Ketika hanya satu pemain yang tersisa, dia adalah pemenang dari permainan itu, dan menerima satu poin. Turnamen terdiri dari 5*n
permainan, di mana n
jumlah pemain. Setiap permainan, pemain awal akan diputar , dan urutan pemain yang tersisa akan diacak . Pemain dengan poin terbanyak di akhir adalah pemenang pertandingan. Jika pertandingan berakhir dengan dasi untuk tempat pertama, pertandingan baru akan dimainkan hanya dengan para kontestan. Ini akan berlanjut sampai tidak ada dasi.
Pemain pemula untuk setiap permainan akan menerima satu set poin pseudorandomly yang dipilih tanpa urutan tertentu.
Poin didefinisikan sebagai pasangan x,y
koordinat bilangan bulat pada kisi kartesius. Jarak diukur dengan menggunakan Manhattan jarak , |x1-x2| + |y1-y2|
. Semua koordinat akan terletak pada [0..199]
kisaran.
Memasukkan
Input diberikan dengan argumen string tunggal. Ini akan terdiri dari 201 bilangan bulat yang dipisahkan koma yang mewakili jumlah pemain saat ini ( m
) dan 100 poin:
m,x0,y0,x1,y1,x2,y2,...,x99,y99
Urutan titik-titik ini adalah jalur saat ini. Total jarak diperoleh dengan menambahkan jarak dari setiap titik ke titik berikutnya ( dist(0,1) + dist(1,2) + ... + dist(99,0)
). Jangan lupa untuk kembali memulai ketika menghitung jarak total!
Perhatikan bahwa m
ini bukan jumlah pemain yang memulai pertandingan, itu adalah jumlah yang masih dalam.
Keluaran
Output diberikan dengan cara yang sama seperti input, minus m
; string tunggal berisi bilangan bulat yang dipisahkan koma yang mewakili titik dalam orde baru mereka.
x0,y0,x1,y1,x2,y2,...,x99,y99
Program kontrol akan menunggu output hanya untuk satu menit. Ketika output diterima, itu akan memverifikasi bahwa:
- output terbentuk dengan baik
- output hanya terdiri dari dan semua 100 poin hadir dalam input
>=75
poin ada di posisi semula- panjang lintasan lebih kecil dari lintasan sebelumnya
Jika salah satu dari cek ini gagal (atau tidak ada output), Anda keluar dan permainan akan berlanjut ke pemain berikutnya.
Program Kontrol
Anda dapat menemukan program kontrol di tautan ini . Program kontrol itu sendiri bersifat deterministik, dan diposting dengan benih dummy 1
. Benih yang digunakan selama penilaian akan berbeda, jadi jangan repot-repot mencoba menganalisis daftar urutan belokan / titik yang dikeluarkannya.
Kelas utamanya adalah Tourney
. Menjalankan ini akan melakukan turnamen penuh dengan kontestan yang diberikan sebagai argumen. Itu memuntahkan pemenang dari setiap pertandingan dan penghitungan di akhir. Contoh pertandingan dengan dua SwapBots terlihat seperti:
Starting tournament with seed 1
(0) SwapBot wins a game! Current score: 1
(1) SwapBot wins a game! Current score: 1
(1) SwapBot wins a game! Current score: 2
(1) SwapBot wins a game! Current score: 3
(0) SwapBot wins a game! Current score: 2
(1) SwapBot wins a game! Current score: 4
(1) SwapBot wins a game! Current score: 5
(1) SwapBot wins a game! Current score: 6
(1) SwapBot wins a game! Current score: 7
(1) SwapBot wins a game! Current score: 8
Final Results:
Wins Contestant
2 (0) SwapBot
8 (1) SwapBot
Jika Anda ingin menguji hanya satu game pada satu waktu, Anda dapat menjalankan Game
kelas sebagai gantinya. Ini akan menjalankan satu game dengan pemain dalam urutan yang diberikan sebagai argumen. Secara default, itu juga akan mencetak play-by-play yang menunjukkan pemain saat ini dan panjang lintasan.
Juga termasuk beberapa pemain tes: SwapBot
, BlockPermuter
, dan TwoSwapBot
. Dua yang pertama tidak akan dimasukkan dalam penilaian berjalan, jadi jangan ragu untuk menggunakan dan menyalahgunakannya selama pengujian. TwoSwapBot
akan dimasukkan dalam penilaian, dan dia tidak bungkuk, jadi bawalah A-game Anda.
Varia
Anda tidak dapat menyimpan informasi status, dan setiap belokan adalah program terpisah dari program Anda. Satu-satunya informasi yang akan Anda terima setiap belokan adalah serangkaian poin.
Anda tidak dapat menggunakan sumber daya eksternal. Ini termasuk panggilan jaringan dan akses file.
Anda tidak dapat menggunakan fungsi pustaka yang dirancang untuk memecahkan / membantu dengan masalah TSP atau variannya.
Anda tidak dapat memanipulasi atau mengganggu pemain lain dengan cara apa pun.
Anda tidak dapat memanipulasi atau mengganggu program kontrol atau kelas atau file yang disertakan dengan cara apa pun.
Multi-threading diizinkan.
Satu pengiriman per pengguna. Jika Anda mengirim lebih dari satu entri, saya hanya akan memasukkan entri pertama yang dikirimkan. Jika Anda ingin mengubah kiriman Anda, edit / hapus yang asli.
Turnamen akan berjalan di Ubuntu 13.04, di komputer dengan CPU i7-3770K dan RAM 16GB. Itu tidak akan dijalankan di VM. Apa pun yang saya anggap berbahaya akan segera mendiskualifikasi entri saat ini dan di masa mendatang yang Anda kirimkan.
Semua entri harus dapat dijalankan dari baris perintah dengan perangkat lunak gratis ( seperti bir ). Jika saya memiliki masalah dalam mengkompilasi / menjalankan entri Anda, saya akan meminta bantuan dalam komentar. Jika Anda tidak merespons atau pada akhirnya saya tidak dapat menjalankannya, itu akan didiskualifikasi.
Hasil (22 Mei 2014)
Hasil baru ada di! UntangleBot telah mengalahkan kompetisi dengan cukup baik. TwoSwapBot berhasil tujuh kemenangan, dan SANNbot menyelipkan kemenangan juga. Ini papan skor, dan tautan ke output mentah :
Wins Contestant
22 (2) ./UntangleBot
7 (0) TwoSwapBot
1 (5) SANNbot.R
0 (1) BozoBot
0 (3) Threader
0 (4) DivideAndConquer
Seperti sekarang , UntangleBot telah memenangkan tanda centang. Namun, jangan biarkan hal itu menghalangi Anda untuk masuk, karena saya akan menjalankan turnamen karena semakin banyak kontestan muncul dan ubah jawaban yang diterima.
sumber
Jawaban:
UntangleBot (sebelumnya NiceBot)
Bot C ++ 11 yang menggunakan dua strategi.
Pada awalnya ia akan mencoba untuk "mengurai" jalan jika mungkin, dengan mendeteksi persimpangan antara jalur yang lebih dekat dari 25 poin (karena penguraian menyiratkan memodifikasi semua titik di antara).
Jika strategi pertama gagal, itu secara acak bertukar poin untuk menemukan jarak yang lebih baik sampai jalan yang lebih baik telah ditemukan.
Bot ini secara konsisten mengalahkan TwoSwapBot dengan rasio perkiraan lima kemenangan untuk satu kekalahan di turnamen tes saya.
sumber
SANNbot
(bot anil yang disimulasikan dalam R )
Harus dipanggil dengan
Rscript SANNbot.R
.Idenya relatif sederhana: setiap belokan adalah satu "langkah pendinginan" dari anil simulasi dengan jumlah pemain yang masih dalam permainan sebagai "suhu" (dimodifikasi oleh jarak saat ini lebih dari 12000, yaitu kira-kira jarak awal). Satu-satunya perbedaan dengan annealing simulasi yang tepat adalah bahwa saya memeriksa bahwa saya tidak mengubah permutasi lebih dari 25 elemen dan jika saya menggunakan 20 gerakan tetapi urutan yang dihasilkan bernilai dari awal maka mulai lagi dari awal.
sumber
java Tourney "java Swapbot" "Rscript SANNbot.R"
dan sepertinya berhasil.u
batas pemeriksaan, ini tidak terjadi (dan kinerjanya jauh lebih baik). Sementara kode Anda tampaknya cukup mudah, saya tidak tahu kebiasaan R jadi saya tidak tahu apakah logikanya salah. (versi terbaru dari pengontrol akan memberikan pesan tentang mengapa bot padam saat berjalanGame
, sehingga dapat membantu menunjukkan masalah)BozoBot
Memanfaatkan logika kompleks di belakang Bozosort untuk menemukan jalan yang lebih baik. Ini terlihat seperti ini.
BozoBot sekarang telah ditingkatkan dengan Multithreading ! Empat antek sekarang tanpa tujuan menyulap poin sampai mereka menemukan peningkatan. Yang pertama menemukan solusi mendapat cookie!Ternyata saya gagal dalam multithreading.
sumber
new Thread(new Minion()).start()
TwoSwapBot
Upgrade ke
SwapBot
, orang ini memeriksa setiap pasang swap. Pertama, ia memeriksa apakah ada pertukaran tunggal yang akan mempersingkat jalur. Jika ya, ia segera kembali. Jika tidak, ia memeriksa masing-masing untuk melihat apakah swap lain akan mempersingkatnya. Jika tidak, dia mati saja.Sementara jalur masih semi-acak, biasanya kembali dalam sekitar 100 ms. Jika dia harus memeriksa masing-masing dan setiap 2 swap (kira-kira 25 juta), dibutuhkan sekitar 20 detik.
Pada saat pengajuan, ini mengalahkan semua pesaing lainnya di babak uji.
sumber
Utas
Bot ini
410 buah2510 poinIdenya adalah untuk menemukan peningkatan terbaik ke jalur, sehingga bot lain akan gagal dengan logika mereka.
sumber
println
untukprint
menghilangkan baris baru di akhir output Anda. Kalau tidak, crash.println
menjadiprint
dan membuat penghitungan utas menjadi dinamis. Sekarang mulai dengan 10 utas ...Membagi Dan Menaklukkan + Bot Serakah
CATATAN: Saya melihat kode Anda
Game
yang mencakup hal-hal berikut di Game.parsePath:Namun, tidak ada
catch(NumberFormatException)
blok, sehingga program Anda kemungkinan akan macet ketika program pemain mengeluarkan string (seperti yang ditunjukkan pada akhirmain
metode program saya ). Saya menyarankan Anda memperbaikinya, karena program dapat menampilkan pengecualian, jejak tumpukan, atau sejenisnya. Kalau tidak, komentari baris itu di program saya sebelum Anda menjalankannya.Kembali ke topik
Implementasi ini (di Jawa) membagi daftar poin menjadi potongan-potongan 25, spasi secara acak pada daftar. Kemudian, ia menciptakan utas untuk mempersingkat jalur antara titik-titik di setiap potongan (Oleh karena itu, "Bagi dan Taklukkan"). Utas utama memantau yang lain dan memastikan untuk menghadirkan solusi terpendek dalam batas waktu. Jika sebuah utas mati dengan atau tanpa solusi, itu memulai utas lain lagi pada potongan yang berbeda.
Setiap utas menggunakan algoritme "serakah", yang dimulai dari titik acak, menuju ke titik terdekat, dan berulang hingga semua titik dibahas (Oleh karena itu, "serakah").
Catatan
Hanya kompilasi dan gunakan
java DivideAndConquer.class
untuk menjalankan.sumber
<200
token sebelum mencoba parsing. Masih lebih baik untuk memeriksanya.)
baris 19; ubahsubstr
kesubstring
pada 38; menginisialisasiidx
ke sesuatu dalamrun()
metode ini.