Genetic Algorithm Maze Solving Program
Genetic Algorithm Maze Solving Program
ECE-478
10-10-10
ID: 4691
tempStore.resize(populationSize);
Calculate Fitness:
The next step is to calculate the fitness. We first find the starting and ending points.
for(i=0; i<8; i++)
{
for(j=0; j<8; j++)
{
if(mazeSeq[i][j] == 7)
{
startX = i;
startY = j;
}
}
}
for(i=0; i<8; i++)
{
for(j=0; j<8; j++)
{
if(mazeSeq[i][j] == 8)
{
endX = i;
endY = j;
}
}
}
We then reset the array which holds where the robot is going. A 1 represent a place
that the robot has gone to. The maze is then filled with the sequence of the
corresponding chromosome. Afterwards we check if the robot dies by this
sequence and calculate the fitness using the amount of spaces remaining.
for(i=0; i<8; i++)
{
for(j=0; j<8; j++)
{
if(mazeSeq[i][j] == 8)
{
endX = i;
endY = j;
}
}
}
for(l=0; l<chromozone.size(); l++)
{
distT = 0;
curX = startX;
curY = startY-1;
for(i=0; i<8; i++)
{
for(j=0; j<8; j++)
{
mazeCopy[i][j]=0;
}
while((curY != endY));
chromozone[l].fitness = usedSpace - distT;
In more detail, there is a do loop which repeats along if the robot is alive. The
function checkDeath checks if the robot dies and returns a 1 if it is dead. The
amount of remaining spaces is the Manhattan distance, and is calculated by the
total number of moveable spaces subtracted by the number of spaces the robot
travelled.
case 1:
// If the robot
if(mazeSeq[X][Y-1] == 9)
{
rcode = 1;
break;
}
nxtX = X;
nxtY = Y-1;
break;
case 2:
if(mazeSeq[X-1][Y] == 9)
// If the robot
{
rcode = 1;
break;
}
nxtX = X-1;
nxtY = Y;
break;
case 3:
if(mazeSeq[X+1][Y] == 9)
// If the robot
{
rcode = 1;
break;
}
nxtX = X+1;
nxtY = Y;
break;
case 4:
// If the robot
if(Y+1 > 7)
// If the robot
{
rcode = 1;
break;
}
if((mazeSeq[X][Y+1] == 9) && (mazeSeq[X][Y+1]
{
rcode = 1;
break;
}
nxtX = X;
nxtY = Y+1;
break;
}
return rcode;
goes forward
goes left
goes right
goes backwards
goes out of bounds
== 8))
This functions gets the next space in the maze and see if the robot will hit a wall
using this command. If so, the function returns a 1.
}
void GA::mutate(chromozone &member)
{
int lowest=1, highest=4;
int range=(highest-lowest)+1;
int mutPos = rand() % usedSpace;
int delta = lowest+int(range*rand()/(RAND_MAX + 1.0));
member.chromo[mutPos] = delta;
}
Swapping:
At last, we take the newly produced chromosones and replace the old ones with
them. This is done by:
inline void swap(vChrom *&population, vChrom *&tempStore);
inline void swap(vChrom *&population, vChrom *&tempStore)
{
vChrom *temp = population;
population = tempStore;
tempStore = temp;
}
}
_getch();
return 0;
Analysis:
Overall, the genetic algorithm performed very good, very little have fitness functions
higher than the previous fitness. The problem was that sometimes there would be
lots of generations before it found the solution, most of the time at the same fitness
and not improving.
10
5
0
Generation
So therefore, in order to find the best value to divide the population (how many are
canidates to pick for selection), the values 2, 3, and 4 where tried. Any number after
that would have a limited selection, therefore leading to a greater number of
generations.
j = rand() % (populationSize / n); // n = to the values 2, 3, 4
k = rand() % (populationSize / n);
GA Maze Test 1
20
15
Fitness Value
Population / 2
Population / 3
10
Population / 4
5
0
Generation
In the results for test 1, the values of 3 and 4 did the best with a generation maxium
of 21 while the value of 2 lacked behind with a generation maxium of 35.
GA Maze Test 2
20
15
Fitness Value
Population / 2
Population / 3
10
Population / 4
5
0
Generation
In test 2, a value of 3 significantly did better with a generation maxium of 25. This
was almost two times less than a value of 2 which got 40. A value of 4 was in the
middle with a value of 34
GA Maze Test 3
20
15
Fitness Value
Population / 2
Population / 3
10
Population / 4
5
0
Generation
In test 3, a value of 3 again did the best with a generation of 22 while a value of 2
severly lacked behind with a genration of 37. A value of 4 was closer to a value of 2
with a generation of 26.
In conclusion, the algorithm worked 100% of the time using any population to be
selected. However a range of 500 was very ineffecient because it gets to the goal
in about 35 tries. A range of 250 was better with an average of about 27 tries. A
range of about 333 was optimal with an average of 23. This is a significant
difference from a range of 500 and results in faster calculation.