我正在实现进化神经网络。当涉及到两个double值的交叉时,我遇到了问题。我正在不断发展神经网络中链接的权重。
//Get the weights that I want to crossover
double weightA = a.getWeight();
double weightB = b.getWeight();
//Round to 6 decimal numbers.
weightA = (double)Math.round(weightA * 1000000) / 1000000;
weightB = (double)Math.round(weightB * 1000000) / 1000000;
//Convert the doubles to binary strings
String binaryA = Long.toBinaryString(Double.doubleToRawLongBits(weightA));
String binaryB = Long.toBinaryString(Double.doubleToRawLongBits(weightB));
//Define random crossover point.
int crossOverPoint = randInt(0, binaryA.length());
//Put the strings together based on the crossover point.
String newBinary = binaryA.substring(0,crossOverPoint) + binaryB.substring(crossOverPoint+1,binaryB.length());
double newWeight = Double.longBitsToDouble(new BigInteger(newBinary, 2).longValue());
我遇到的问题是,交叉后权重变得非常大或非常小,这可能是每个字符串中的小数位使用多少位的结果。我该怎么做才能在交叉后获得类似于两个父母的价值?
我有一个解决此问题的方法,可以给我不错的结果,但我可以肯定那不是正确的方法,该方法基本上是找到两个值之间的平均值,并基于原始两个值的间隔添加一些具有标准偏差的高斯噪声。
double interval = Math.abs(weightA-weightB);
double newWeight = (weightA+weightB)*0.5 + r.nextGaussian()*interval*2;
最佳答案
我对遗传算法不是很熟悉,但是据我所知,您对双打的处理似乎不是解决它的好方法:
我在这里假设您要使用第一个double的二进制表示形式的前crossOverPoint
位和第二个double的最后一个(64-crossOverPoint)
位(如果我错了,请更正我)。如果使用字符串,则必须确保包含前导0。比较简单的方法是使用位运算来组合long的二进制表示形式:
long weightALong = Double.doubleToRawLongBits(weightA);
long weightBLong = Double.doubleToRawLongBits(weightB);
long mask = -1L; // all bits set to 1
int crossOverPoint = randInt(0, Long.SIZE);
long combined;
// treat special cases because of modulo Long.SIZE of second parameter of shifting operations
if (crossOverPoint == 0) {
combined = weightBLong;
} else if (combined == Long.SIZE) {
combined = weightALong;
} else {
combined = (weightALong & (mask << (Long.SIZE - crossOverPoint))) |
(weightBLong & (mask >>> crossOverPoint));
}
double newWeight = Double.longBitsToDouble(combined);
但是从binary representation of doubles中,我猜想以这种方式组合二进制表示可能不是组合双精度的最佳方法:
如果前几位不同,则正确选择
crossOverPoint
(1)即可更改符号。指数完全来自所有情况下(52/64)中的
weightA
。如果尾数出现不幸的组合,则
NaN
,POSITIVE_INFINITY
和NEGATIVE_INFINITY
的值可以不同于这三个值。我想您的解决方法似乎是更好的选择。 (也许您应该在https://cs.stackexchange.com/上问这个问题)
关于java - Java:将两个双位串混合在一起以进行遗传算法交叉,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23970715/