マルコフ連鎖モンテカルロ (MCMC)と密接に関連するシミュレーテッド アニーリング。おそらく必要なバリアントはMetropolis-Hastingsです。コツをつかめば、なかなかいいものです。入力と結果はすべて整数であるため、最適化する方法がいくつかある可能性があります。計算量が多く、多少の調整が必要になる場合がありますが、非常に堅牢であり、他の方法でこれ以上うまくいくかどうかはわかりません.
これを行うための脳死のコードを次に示します。
const int n = 100; // length of vector to optimize
int a[n]; // the vector to optimize
double P(a){..} // Get the probability of vector a.
// This is the function to optimize.
// for a large number of a samples
for (i = 0; i < large_number; i++){
// get P(a)
double p = P(a);
// for each element of vector a
for (j = 0; j < n; j++){
// get an amount by which to change it. This choice has to be symmetric.
// this is called the Proposal Distribution
int step = uniform_random_choice_from(-2, -1, 1, 2);
// make the change to a[j], and get p1, the new value of p
a[j] += step;
double p1 = P(a);
bool bKeepTheStep = true;
// if p1 is better than p, keep the step
// if p1 is worse than p, then keep the step p1/p of the time
if (p1 < p){
bKeepTheStep = (unif(0,1) < p1/p);
}
if (bKeepTheStep) p = p1;
else a[j] -= step;
}
// now a is a sample, and p is its value
// record a and p
}
// what you have now is a large random sampling of vectors from distribution P
// now you can choose the best one, the average, the variance,
// any statistic you like
それを微調整する方法は、提案の分布を広げたり狭めたりすることです。そのため、ステップを大きくしたり小さくしたりできます。または、最初に大きなステップを実行してから小さなステップを実行することもできます。探しているのは、高すぎず低すぎずに保持されている歩数のパーセンテージです。モードの領域を探している間に、破棄する最初の 1k 程度のサンプルの「焼き込み」フェーズが必要になる場合があります。
そしてぜひ、プロファイル P を。できるだけ高速にする必要があります。これが私のお気に入りの方法です。