পটভূমি
এই ছবিটি সমস্যার চিত্র তুলে ধরেছে:
আমি লাল বৃত্তটি নিয়ন্ত্রণ করতে পারি। লক্ষ্যগুলি হ'ল নীল ত্রিভুজ। কালো তীরগুলি লক্ষ্যগুলি যে দিকে অগ্রসর হবে সেদিকে নির্দেশ করে।
ন্যূনতম পদক্ষেপে আমি সমস্ত লক্ষ্যমাত্রা সংগ্রহ করতে চাই।
প্রতিটি পালা আমাকে অবশ্যই 1 টি পদক্ষেপ বাম / ডান / উপরে বা নীচে সরানো উচিত।
প্রতিটি টার্ন লক্ষ্যবস্তু বোর্ডে প্রদর্শিত নির্দেশাবলী অনুযায়ী 1 পদক্ষেপও সরানো হবে।
ডেমো
আমি গুগল অ্যাপেনেগিনে সমস্যার একটি প্লেযোগ্য ডেমো রেখেছি ।
আমি খুব আগ্রহী হব যদি কেউ লক্ষ্য স্কোরকে হারাতে পারে কারণ এটি দেখায় যে আমার বর্তমান অ্যালগরিদম সাব-কোটিস্টাল। (আপনি যদি এটি পরিচালনা করেন তবে অভিনন্দন বার্তা প্রিন্ট করা উচিত!)
সমস্যা
আমার বর্তমান অ্যালগরিদম স্কেলগুলি লক্ষ্যমাত্রার সংখ্যা সহ সত্যই খারাপ। সময়টি তাত্পর্যপূর্ণভাবে বেড়ে যায় এবং 16 টি মাছের জন্য এটি ইতিমধ্যে বেশ কয়েক সেকেন্ড।
আমি 32 * 32 বোর্ডের মাপের এবং 100 টি চলন্ত লক্ষ্যমাত্রার সাথে উত্তরটি গণনা করতে চাই।
প্রশ্ন
সমস্ত লক্ষ্যমাত্রা সংগ্রহের জন্য ন্যূনতম পদক্ষেপের গণনা করার জন্য একটি দক্ষ অ্যালগরিদম (আদর্শভাবে জাভাস্ক্রিপ্টে) কী?
আমি কি চেষ্টা করেছি
আমার বর্তমান পদ্ধতির স্মৃতিচারণের উপর ভিত্তি করে তবে এটি খুব ধীর এবং এটি সর্বদা সেরা সমাধান উত্পন্ন করবে কিনা তা আমি জানি না।
আমি "প্রদত্ত লক্ষ্যমাত্রার একটি সেট সংগ্রহ করতে এবং নির্দিষ্ট লক্ষ্যবস্তুতে শেষ করতে সর্বনিম্ন পদক্ষেপের সংখ্যাটি কী?" এর সাব-প্রবলেমটি আমি সমাধান করি।
পূর্ববর্তী লক্ষ্যটি দেখার জন্য প্রতিটি পছন্দ যাচাই করে সাব-সমস্যাটি পুনরাবৃত্তভাবে সমাধান করা হয়। আমি ধরে নিয়েছি যে লক্ষ্যগুলি পূর্বের সাবসেটটি যত তাড়াতাড়ি সম্ভব সংগ্রহ করা সর্বদা অনুকূল এবং তারপরে আপনি যে অবস্থানটি বর্তমান টার্গেটে পৌঁছেছিলেন যত তাড়াতাড়ি সম্ভব সরিয়ে নেওয়া (যদিও আমি জানি না এটি বৈধ অনুমান কিনা)।
এর ফলে n * 2 ^ n এর ফলাফল গণনা করা যায় যা খুব দ্রুত বৃদ্ধি পায়।
বর্তমান কোডটি নীচে দেখানো হয়েছে:
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;
}
আমি কি বিবেচনা করেছি
কিছু বিকল্পের বিষয়ে আমি ভাবলাম যা হ'ল:
মধ্যবর্তী ফলাফলের ক্যাচিং। দূরত্ব গণনা অনেক সিমুলেশন পুনরাবৃত্তি করে এবং মধ্যবর্তী ফলাফল ক্যাশে হতে পারে।
যাইহোক, আমি মনে করি না এটি এটি ঘনিষ্ঠ জটিলতা থাকা বন্ধ করবে।একটি এ * অনুসন্ধান অ্যালগরিদম যদিও এটি আমার কাছে স্পষ্ট নয় যে উপযুক্ত গ্রহণযোগ্য হিউরিস্টিক কী হবে এবং এটি বাস্তবে কার্যকর হবে।
ভ্রমণের বিক্রয়কর্মী সমস্যার জন্য ভাল অ্যালগরিদমগুলি তদন্ত করছে এবং দেখুন যে তারা এই সমস্যায় প্রযোজ্য কিনা।
সমস্যাটি এনপি-হার্ড এবং এটির জন্য সর্বোত্তম উত্তর চেয়ে নেওয়া অযৌক্তিক তা প্রমাণ করার চেষ্টা করা।