I am trying to implement genetic algorithm for maximizing a function of n integer variables x1..xn where each variable belongs to the range [-n, n]. I am thinking of using binary encoding for representing chromosome but I am not sure about how to encode negative integers. I have searched for quite some time but I haven't come across a common formula for binary encoding. What is the most common way to encode integers in the range [-n,n] for genetic algorithms? I want crossover and mutation to have less complexity (less condition checking). Will it work if for the initial population, instead of generating numbers between -n and n, I generate numbers from 0 to 2n and encode them in binary and then, while decoding, I subtract n every time (for every subsequent generation)?
-
not sure if this would help, but you could store the numbers in two's complement form – jg943 Apr 22 '13 at 22:45
-
1What's the difference between encoding [-n, n] and [0, 2n]? I guess there souldn't be... – sashkello Apr 22 '13 at 22:53
-
C will do the encoding in bytes for you, I'd expect. – flup Apr 22 '13 at 23:11
1 Answers
user1765444's answer makes good sense... and I just read sashkello's suggestion (using offset binary would eliminate having to frig about with signed ints inside the GA). Doing the crossover and mutates etc would be easy that way - using a combo of both shashkello's and user1765444's answers. The problem is if your datatype has a larger width than your range, then crossover could yield invalid children.
Let's say an int32 has the width you require. Then int32 array[n]. You know there are 32n bits so you might take a crossover point at random m, where m >=0 and m < 32n. You know bit m occurs in array[m/n], bit position m%n starting at the msb (imagining the array to be just one long binary string).
Then say you have 2 parents int32 parent1[n] and int32 parent2[n]. Something like the following pseudo-ish code? In this crossover the string is just a binary string for the sake of the cross (i.e. sign bit treated as just another bit)...
Disclaimer: Sorry, code below is rough n ready, uncompiled, so may contain errors... just a thought!
int child1[n];
uint32 m = rand_like_func(); // random cross over point, a bit position
// in the binary string of length n*32;
uint32 arraySlotForCrossOvr = (uint32)(m / n);
uint32 bitInSlotForCrossOvr = 31 - m % n;
uint32 maskForCrossOvrP2 = (1 << bitInSlotForCrossOvr) - 1;
uint32 maskForCrossOvrP1 = ~maskForCrossOvrP2;
// crossover to create child 1
memcpy(child1, parent1, arraySlotForCrossOvr);
child1[arraySlotForCrossOvr] =
(int32)( ((uint32)parent1[arraySlotForCrossOvr] & maskForCrossOverP1) |
((uint32)parent2[arraySlotForCrossOvr] & maskForCrossOvrP2) )
memcpy(
child1,
parent2 + arraySlotForCrossOvr + 1,
total_num_slots - arraySlotForCrossOvr);
Then you might have to detect children that are out of range, or let out of range children just score zero in the next round. Perhaps you could augment the crossover with some intelligence like capping invalid values to the nearest valid value etc?
Hope that helped?
Also, I found "How to Solve It: Modern Heuristics by Z. Michalewicz and D Fogel" really helpful when trying to understand encoding of problems etc :)

- 4,352
- 3
- 27
- 44
-
thanks for the explanation. But as far as the encoding is concerned, should I generate numbers from 0 to 2n and then while decoding subtract n from them ? – vjain27 Apr 23 '13 at 01:08
-
1I'd prob go for 2n implementation. Then you're dealing with unsigned whilst doing bit manipulation which is slightly more friendly. E.g. if you right shift a signed quantity the results might not be well defined (http://stackoverflow.com/questions/7622/shift-operator-in-c) – Jimbo Apr 23 '13 at 06:23