模拟退火,与马尔可夫链蒙特卡罗 (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。它需要尽可能快。这是我最喜欢的方法。