如何使用微分演化来找到函数函数f(x)= -x(x 1)从-500到500的最大值?我正在制作一个国际象棋程序时需要这个,我已经开始研究差异进化,但仍然发现它很难理解,更不用说用于程序了.谁能通过简单的方式向我介绍算法并为该程序提供一些示例伪代码来帮助我?
解决方法:
首先,对于延迟的回复,我们深表歉意.
我敢打赌,您将不知道将要尝试最大化的函数的派生类,这就是为什么要使用差分演化算法而不是使用Newton-Raphson方法之类的原因.
在第一页上,有一个部分介绍了该算法:
Let each generation of points consist of n points, with j terms in each.
初始化大小为j的数组.在从-500到500(您正在考虑的间隔)中添加数量j的不同随机x值.理想情况下,您会知道最大值在哪里,并使x值更可能出现在其中.
For each j, randomly select two points yj,1 and yj,2 uniformly from the set of points x
(m)
.
Construct a candidate point cj = x
(m)
j + α(yj,1 − yj,2). Basically the two y values involve
picking a random direction and distance, and the candidate is found by adding that random
direction and distance (scaled by α) to the current value.
嗯…这有点复杂.遍历在上一步中创建的数组.对于每个x值,选择两个随机索引(yj1和yj2).构造一个候选x值,其中cx =α(yj1-yj2),在其中选择α.您可以尝试使用不同的alpha值进行试验.
检查j中的哪个更大,候选值或x值.如果候选值较大,则将其替换为j处的x值.
进行所有操作,直到数组中的所有值或多或少都相似为止.
Tahdah,数组的任何值都将是最大值.只是为了减少随机性(或者也许这并不重要…),将它们平均在一起.
您对about方法进行的严格程度越高,得到的近似值越好,但是花费的时间也就越多.
例如,代替Math.abs(a-b)< = alpha / 10,我将使用Math.abs(a-b)< = alpha / 10000以获得更好的近似值.
您将获得所需值的近似值.
编码愉快!
我为此响应编写的代码:
public class DifferentialEvolution {
public static final double alpha = 0.001;
public static double evaluate(double x) {
return -x*(x+1);
}
public static double max(int N) { // N is initial array size.
double[] xs = new double[N];
for(int j = 0; j < N; j++) {
xs[j] = Math.random()*1000.0 - 500.0; // Number from -500 to 500.
}
boolean done = false;
while(!done) {
for(int j = 0; j < N; j++) {
double yj1 = xs[(int)(Math.random()*N)]; // This might include xs[j], but that shouldn't be a problem.
double yj2 = xs[(int)(Math.random()*N)]; // It will only slow things down a bit.
double cj = xs[j] + alpha*(yj1-yj2);
if(evaluate(cj) > evaluate(xs[j])) {
xs[j] = cj;
}
}
double average = average(xs); // Edited
done = true;
for(int j = 0; j < N; j++) { // Edited
if(!about(xs[j], average)) { // Edited
done = false;
break;
}
}
}
return average(xs);
}
public static double average(double[] values) {
double sum = 0;
for(int i = 0; i < values.length; i++) {
sum += values[i];
}
return sum/values.length;
}
public static boolean about(double a, double b) {
if(Math.abs(a - b) <= alpha /10000) { // This should work.
return true;
}
return false;
}
public static void main(String[] args) {
long t = System.currentTimeMillis();
System.out.println(max(3));
System.out.println("Time (Milliseconds): " + (System.currentTimeMillis() - t));
}
}
如果您在阅读本文后有任何疑问,请随时在评论中提问.我会尽力的帮助.
标签:chess,evolutionary-algorithm,differential-evolution,java