I'm trying to get the simple first project from
http://www.ai-junkie.com/ga/intro/gat3.html done, and I pretty much have the code done and working - except the chromosomes aren't being evaluated correctly. I've stepped through the debugger, and it seems to work but I when try printing sample chromosomes to the console screen, they don't evaluate correctly..
Firstly, is there anything wrong with what I'm doing here?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
|
void Chromosome::CalculateScore()
{
// Buffer that contains a value corresponding to each 'gene'
// 0-13, where 0-9 are values and 10, 11, 12, and 13 symbolize operators.
int buff[CHROMOSOME_MAX_LEN];
// Are we searching for an operator?
bool wantOperator = false;
// Have we found a first value yet?
bool foundFirstNum = false;
float ret = 0.f;
// The code is easier to follow if we read to a buffer first.
for (int i=0; i<CHROMOSOME_MAX_LEN; i++)
buff[i] = BinToDec(data_[i].GetString());
// For every value in the buffer...
for (int i=0; i<CHROMOSOME_MAX_LEN; i++)
{
// Numbers.
if (buff[i] < 10)
{
// Were we looking for an operator?
if (wantOperator) continue;
// If this is the first one, let the ret val = the first
// buffer val.
if (!foundFirstNum)
{
ret = buff[i];
foundFirstNum = true;
wantOperator = true;
continue;
}
// Now, let's search for a new value.
wantOperator = true;
continue;
}
// Operators. Ensure that we won't overstep the array boundary
// when performing an operand.
else if ((buff[i] < 14) && ((i+1) < CHROMOSOME_MAX_LEN))
{
// If we didn't want an operator, keep going.
if (!wantOperator) continue;
// Ensure that we're operating with a value 0-9.
while (!(i < 10))
i++;
// If i does not fall within the bounds of the array, continue.
if (!(i < CHROMOSOME_MAX_LEN)) continue;
// We've made sure that we have a valid 2nd parameter for addition.
switch (buff[i])
{
// Otherwise...
wantOperator = false;
case 10:
ret += buff[i];
continue;
case 11:
ret -= buff[i];
continue;
case 12:
ret *= static_cast<float>(buff[i]);
continue;
case 13:
// To handle div by 0
if (buff[i] == 0)
{
ret += buff[i];
continue;
}
else
{
ret /= static_cast<float>(buff[i]);
continue;
}
default:
continue;
}
}
else continue;
}
value_ = ret;
}
|
What is meant to happen is:
Let 0-9 correspond to values.
Let 10, 11, 12, and 13 correspond to +, -, *, and / respectively.
Let 14 and 15 (which are viable numbers because genes are represented in binary)
be invalid and skipped.
The buffer might contain a sequence such as
0 13 12 9 10 3 4 15
Which would translate into
0 / * 9 + 3 4 invalid
The algorithm should be able to interpret this as
0 / 9 + 3
(ignoring order of operations for simplicity's sake)
which would equal three.
I think that maybe I could try incrementing by 2s instead, looking for operators (and checking validity of values index+1 and index-1 instead) but I'm not sure how I could get that to work.
It's possible that there's a problem elsewhere, so if you feel up to it, I posted a compilable version here:
http://codepad.org/uRb6SZJZ
(it complains if I try to use auto iter on line 45, but code::blocks rejects Vector<T>::iterator there so I just went with auto)