我有一个功能,
P(x0,x1,...,xn)
以100个整数作为输入,并将整数作为输出。 P是一个很慢的评估函数(范围从30秒到几分钟)。
我需要知道哪些点的值会最大化P的屈服值。
我可以使用哪些技术来实现这一目标?我知道人们通常会使用遗传算法,但我担心用它们计算它会花费很长时间,因为即使人口很少而且几代人(比如说,人口= 50,世代= 50),P是这样的慢一点,计算它需要40多个小时。
有没有更便宜的方法呢?也许是一个迭代过程?我不需要它是真正的最佳,但我没有任何关于它如何表现的想法(我已经尝试过线性/二次/指数但它似乎没有产生任何好的值。我知道P可以返回价值比我得到的价值至少高5到10倍。
它应该更容易实现(即,我必须自己实现)。
由于
编辑:P是一个随机过程。
答案 0 :(得分:4)
Simulated annealing,与Markov Chain Monte Carlo (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.它需要尽可能快。 Here's my favorite way to do that.
答案 1 :(得分:2)
您的算法的很大一部分可以并行化吗?如果是这样,您是否考虑过并行化代码?
答案 2 :(得分:2)
查看列出的各种随机优化技术here。我推荐simulated annealing。
答案 3 :(得分:2)
有许多众所周知的全局优化算法(模拟退火,随机隧道等)可以找到全局最大值,但没有一个能保证在合理的时间内找到它而不做出关于功能的形状。
你不会找到一种快速/简单的方法来优化100维,非平凡的功能。你需要大量的处理能力和时间。假设您不想自己编写优化代码(根据您的问题),您还需要一些优秀的数学软件(例如Mathematica)。
答案 4 :(得分:2)
另一个不完全认真的答案,但值得深思:
这个问题看起来很大,以至于通过权利你需要像SETI @ Home这样的东西来解决它。成千上万的计算机可以轻松地完成这类工作。但是我不确定你是如何接触成千上万的计算机用户来获得他们的计算机使用的。
实际上,我这样做。请不要理解这一切的合法性,请耐心等待我。
有些人隐藏在前铁幕后面的僵尸网络。我最近看到了24小时以70美元的价格租用僵尸网络的提议。试想,成千上万的0wned PC准备好你的出价了!您可以让他们为您的问题烦恼,而不是让他们拥有DDOS互联网站点。 :)
最后两点建议:
答案 5 :(得分:1)
作为此类问题的第一线算法,我建议模拟退火。 SA是一个很好的首选,因为您可以清楚地控制起点和运行时间。
如果您对100维空间的结构有所了解,使用SA可以选择一个好的起点,这会对结果的质量产生重大影响。使用SA,您可以控制“冷却速率”,这会影响运行时间和结果质量 - 自然会在相反的方向上。我通常首先以相对较快的冷却速度运行以寻找良好的起始矢量,然后在后续运行中减慢冷却速率以改善结果。一种可以自动化的meta-SA技术。
我成功地使用SA来最大化用于模拟中子质子相互作用的非常高的维度函数。
另外,如果可能的话,我会在尺寸上减少P()。对于您的特定问题,是否需要所有100个变量?如果你可以修复其中的1/2,你将加速任何优化器并最终获得更好的结果。
(SA很容易实现。)
答案 6 :(得分:1)
假设:
首先 - 变量必须是整数 第二 - 目标函数P()是非线性的。
观察:
通常,非线性整数编程很难解决。实际上,如上所述,通过放宽整数限制来舍入解决方案可能有所帮助。
有一般的无约束优化技术可用。实验设计的一种方法是称为“响应面方法”。当实验成本很高时非常有用。方法是通过从一个点开始并以设定的增量偏离每个输入来运行一组实验。然后,计算每个输入的梯度,并为每个输入向该方向迈出一步,然后重复。 Fletcher - 优化的实用方法和Box Hunter&amp; Hunter Statistics for Experimenters是值得一看的地方。
答案 7 :(得分:0)
答案 8 :(得分:0)
如果您可以访问matlab,则可以非常快速且非常轻松地并行化代码。即使它可以使用与parfor循环平行的简单线性循环
答案 9 :(得分:0)
如果可以选择Microsoft解决方案,请查看Solver Foundation。我听说过Scott Hanselman的播客(#191)。