Latar Belakang
Gambar ini mengilustrasikan masalahnya:
Saya bisa mengontrol lingkaran merah. Targetnya adalah segitiga biru. Panah hitam menunjukkan arah pergerakan target.
Saya ingin mengumpulkan semua target dalam jumlah langkah minimum.
Setiap belokan saya harus bergerak 1 langkah ke kiri / kanan / atas atau bawah.
Setiap belokan target juga akan bergerak 1 langkah sesuai dengan petunjuk yang tertera di papan.
Demo
Saya telah membuat demo yang bisa dimainkan dari masalah ini di sini di Google appengine .
Saya akan sangat tertarik jika ada yang bisa mengalahkan skor target karena ini akan menunjukkan bahwa algoritme saya saat ini kurang optimal. (Pesan selamat harus dicetak jika Anda mengatur ini!)
Masalah
Algoritme saya saat ini berskala sangat buruk dengan jumlah target. Waktu bertambah secara eksponensial dan untuk 16 ikan sudah beberapa detik.
Saya ingin menghitung jawaban untuk ukuran papan 32 * 32 dan dengan 100 target bergerak.
Pertanyaan
Apa algoritme yang efisien (idealnya dalam Javascript) untuk menghitung jumlah langkah minimum untuk mengumpulkan semua target?
Apa yang saya coba
Pendekatan saya saat ini didasarkan pada memoisation tetapi sangat lambat dan saya tidak tahu apakah itu akan selalu menghasilkan solusi terbaik.
Saya memecahkan sub-masalah "berapa jumlah minimum langkah untuk mengumpulkan serangkaian target tertentu dan berakhir pada target tertentu?".
Masalah ini diselesaikan secara rekursif dengan memeriksa setiap pilihan untuk target yang dikunjungi sebelumnya. Saya berasumsi bahwa itu selalu optimal untuk mengumpulkan subkumpulan target sebelumnya secepat mungkin dan kemudian berpindah dari posisi yang Anda selesaikan ke target saat ini secepat mungkin (walaupun saya tidak tahu apakah ini asumsi yang valid).
Ini menghasilkan n * 2 ^ n status yang akan dihitung yang tumbuh dengan sangat cepat.
Kode saat ini ditunjukkan di bawah ini:
var DX=[1,0,-1,0];
var DY=[0,1,0,-1];
// Return the location of the given fish at time t
function getPt(fish,t) {
var i;
var x=pts[fish][0];
var y=pts[fish][1];
for(i=0;i<t;i++) {
var b=board[x][y];
x+=DX[b];
y+=DY[b];
}
return [x,y];
}
// Return the number of steps to track down the given fish
// Work by iterating and selecting first time when Manhattan distance matches time
function fastest_route(peng,dest) {
var myx=peng[0];
var myy=peng[1];
var x=dest[0];
var y=dest[1];
var t=0;
while ((Math.abs(x-myx)+Math.abs(y-myy))!=t) {
var b=board[x][y];
x+=DX[b];
y+=DY[b];
t+=1;
}
return t;
}
// Try to compute the shortest path to reach each fish and a certain subset of the others
// key is current fish followed by N bits of bitmask
// value is shortest time
function computeTarget(start_x,start_y) {
cache={};
// Compute the shortest steps to have visited all fish in bitmask
// and with the last visit being to the fish with index equal to last
function go(bitmask,last) {
var i;
var best=100000000;
var key=(last<<num_fish)+bitmask;
if (key in cache) {
return cache[key];
}
// Consider all previous positions
bitmask -= 1<<last;
if (bitmask==0) {
best = fastest_route([start_x,start_y],pts[last]);
} else {
for(i=0;i<pts.length;i++) {
var bit = 1<<i;
if (bitmask&bit) {
var s = go(bitmask,i); // least cost if our previous fish was i
s+=fastest_route(getPt(i,s),getPt(last,s));
if (s<best) best=s;
}
}
}
cache[key]=best;
return best;
}
var t = 100000000;
for(var i=0;i<pts.length;i++) {
t = Math.min(t,go((1<<pts.length)-1,i));
}
return t;
}
Apa yang saya pertimbangkan
Beberapa opsi yang membuat saya penasaran adalah:
Caching hasil menengah. Penghitungan jarak mengulangi banyak simulasi dan hasil antara dapat disimpan dalam cache.
Namun, saya tidak berpikir ini akan menghentikannya memiliki kompleksitas eksponensial.Algoritme pencarian A * meskipun tidak jelas bagi saya heuristik yang dapat diterima yang sesuai dan seberapa efektif ini dalam praktiknya.
Menyelidiki algoritme yang baik untuk masalah penjual keliling dan melihat apakah algoritme tersebut berlaku untuk masalah ini.
Mencoba membuktikan bahwa masalahnya NP-hard dan karenanya tidak masuk akal untuk mencari jawaban yang optimal untuk itu.