Java: Mixing together two double bitstrings for Genetic Algorithm crossover -
i implementing evolutionary neural network. ran problem when comes crossover of 2 double values. evolving weights of links in neural network.
//get weights want crossover double weighta = a.getweight(); double weightb = b.getweight(); //round 6 decimal numbers. weighta = (double)math.round(weighta * 1000000) / 1000000; weightb = (double)math.round(weightb * 1000000) / 1000000; //convert doubles 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 strings based on crossover point. string newbinary = binarya.substring(0,crossoverpoint) + binaryb.substring(crossoverpoint+1,binaryb.length()); double newweight = double.longbitstodouble(new biginteger(newbinary, 2).longvalue());
the problem encountering getting large or small weights after crossover result of how many bits used in each string decimal places. how should values after crossover similar 2 parents?
i had workaround problem gave me decent results sure not correct approach, finds average between 2 values , adds gaussian noise standard deviation based on interval of original 2 values.
double interval = math.abs(weighta-weightb); double newweight = (weighta+weightb)*0.5 + r.nextgaussian()*interval*2;
i'm not familiar genetic algorithms, know treatment of doubles doesn't seem way of approaching it:
i assume here want use first crossoverpoint
bits of binary representation of first double , last (64-crossoverpoint)
bits of second double (correct me if i'm wrong). if use strings you'll have make sure include leading 0s. simpler approach combine binary representations of longs using bit operations:
long weightalong = double.doubletorawlongbits(weighta); long weightblong = double.doubletorawlongbits(weightb); long mask = -1l; // bits set 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);
however binary representation of doubles guess combining binary representations way may not best way combine doubles:
- if first bits different, right choice of
crossoverpoint
(1) can change sign. - the exponent comes
weighta
in (52 / 64) of cases. nan
,positive_infinity
, ,negative_infinity
can produced values different of these 3 if unlucky combination in mantissa.
i guess workaround seems better choice. (maybe should ask question on https://cs.stackexchange.com/)
Comments
Post a Comment