編集:高度に変更されたダイクストラのアルゴリズムを使用した適切なソリューションは次のとおりです。
ダイクストラのアルゴリズムを使用して、一連のノード(通常は場所ですが、この例ではアクションであるとしましょう)であるマップ(グラフアブストラクトの)を指定して最短パスを見つけます。この場合、距離の代わりに、各アークには「値」があります)
これが本質的な構造です。
Graph{//in most implementations these are not Arrays, but Maps. Honestly, for your needs you don't a graph, just nodes and arcs... this is just used to keep track of them.
node[] nodes;
arc[] arcs;
}
Node{//this represents an action
arc[] options;//for this implementation, this will always be a list of all possible Actions to use.
float value;//Action value
}
Arc{
node start;//the last action used
node end;//the action after that
dist=1;//1 second
}
このデータ型を使用して、各パスの最終合計を確認することに基づいて、最適なソリューションを取得するために実行可能なすべてのオプションのマップを作成できます。したがって、パターンを探す秒数が長いほど、非常に最適なパスを見つける可能性が高くなります。
地図上の道路のすべてのセグメントには、その値を表す距離があり、道路のすべての停車地は1秒のマークです。これは、次に進む場所(実行するアクション)を決定する時間だからです。 。簡単にするために、AとBが唯一の実行可能なオプションであるとしましょう。naは、使用可能なアクションがないため、アクションがないことを意味します。あなたが4秒間旅行している場合(量が多いほど、結果は良くなります)、あなたの選択は...
A->na->A->na->A
B->na->na->B->na
A->B->A->na->B
B->A->na->B->A
...
他にもありますが、最適なパスはB-> A-> na-> B-> Aであることがすでにわかっています。これは、その値が最も高いためです。したがって、このアクションの組み合わせを処理するための確立された最良のパターンは、(少なくとも4秒間分析した後)B-> A-> na->B->Aです。これは実際には非常に簡単な再帰アルゴリズムになります。
/*
cur is the current action that you are at, it is a Node. In this example, every other action is seen as a viable option, so it's as if every 'place' on the map has a path going to every other path.
numLeft is the amount of seconds left to run the simulation. The higher the initial value, the more desirable the results.
This won't work as written, but will give you a good idea of how the algorithm works.
*/
function getOptimal(cur,numLeft,path){
if(numLeft==0){
var emptyNode;//let's say, an empty node wiht a value of 0.
return emptyNode;
}
var best=path;
path.add(cur);
for(var i=0;i<cur.options.length;i++){
var opt=cur.options[i];//this is a COPY
if(opt.timeCooled<opt.cooldown){
continue;
}
for(var i2=0;i2<opt.length;i2++){
opt[i2].timeCooled+=1;//everything below this in the loop is as if it is one second ahead
}
var potential=getOptimal(opt[i],numLeft-1,best);
if(getTotal(potential)>getTotal(cur)){best.add(potential);}//if it makes it better, use it! getTotal will sum up the values of an array of nodes(actions)
}
return best;
}
function getOptimalExample(){
log(getOptimal(someNode,4,someEmptyArrayOfNodes));//someNode will be A or B
}
編集を終了します。
私は質問に少し混乱していますが...
アクションの数が限られている場合は、それだけです。クールダウンがまだ満たされていない場合を除き、常に最も価値のあるアクションを選択してください。
このようなものが必要なようです(擬似コードで):
function getOptimal(){
var a=[A,B,C,D];//A,B,C, and D are actions
a.sort()//(just pseudocode. Sort the array items by how much value they have.)
var theBest=null;
for(var i=0;i<a.length;++i){//find which action is the most valuable
if(a[i].timeSinceLastUsed<a[i].cooldown){
theBest=a[i];
for(...){//now just loop through, and add time to each OTHER Action for their timeSinceLastUsed...
//...
}//That way, some previously used, but more valuable actions will be freed up again.
break;
}//because a is worth the most, and you can use it now, so why not?
}
}