Sorry if this isn’t clear as I’m writing this on a mobile device and I’m trying to make it quick.
I’ve written a basic Genetic Algorithm with a binary encoding (genes) that builds a fitness value and evolves through several iterations using tournament selection, mutation and crossover. As a basic command-line example it seems to work.
The problem I’ve got is with applying a genetic algorithm within a GUI as I am writing a maze-solving program that uses the GA to find a method through a maze. How do I turn my random binary encoded genes and fitness function (add all the binary values together) into a method to control a bot around a maze? I have built a basic GUI in Java consisting of a maze of labels (like a grid) with the available routes being in blue and the walls being in black.
To reiterate my GA performs well and contains what any typical GA would (fitness method, get and set population, selection, crossover, etc) but now I need to plug it into a GUI to get my maze running. What needs to go where in order to get a bot that can move in different directions depending on what the GA says? Rough pseudocode would be great if possible
As requested, an Individual is built using a separate class (Indiv), with all the main work being done in a Pop class. When a new individual is instantiated an array of ints represent the genes of said individual, with the genes being picked at random from a number between 0 and 1. The fitness function merely adds together the value of these genes and in the Pop class handles selection, mutation and crossover of two selected individuals. There’s not much else to it, the command line program just shows evolution over n generations with the total fitness improving over each iteration.
EDIT: It’s starting to make a bit more sense now, although there are a few things that are bugging me…
As Adamski has suggested I want to create an “Agent” with the options shown below. The problem I have is where the random bit string comes into play here. The agent knows where the walls are and has it laid out in a 4 bit string (i.e. 0111), but how does this affect the random 32 bit string? (i.e. 10001011011001001010011011010101) If I have the following maze (x is the start place, 2 is the goal, 1 is the wall):
x 1 1 1 1
0 0 1 0 0
1 0 0 0 2
If I turn left I’m facing the wrong way and the agent will move completely off the maze if it moves forward. I assume that the first generation of the string will be completely random and it will evolve as the fitness grows but I don’t get how the string will work within a maze.
So, to get this straight…
The fitness is the result of when the agent is able to move and is by a wall.
The genes are a string of 32 bits, split into 16 sets of 2 bits to show the available actions and for the robot to move the two bits need to be passed with four bits from the agent showings its position near the walls. If the move is to go past a wall the move isn’t made and it is deemed invalid and if the move is made and if a new wall is found then the fitness goes up.
Is that right?
BadHorse’s answer is good if you want to solve a specific maze; you simply intepret your bit string as a sequence of precise instructions to guide the agent through the maze. In this case your fitness is not the sum of the bit string (as you state in your question) but rather some metric measuring how successfull the agent was in solving the problem. For example, your fitness might be defined as “distance in a straight line from end of maze after processing 20 instructions“.
Hence, when evaluating each individual you allow it to process the first 20 instructions from your bit string and then compute its fitness, perform any crossovers / mutations and then create the next generation of individuals.
If you wish to develop your agent to solve any maze you need to encode rules within your bit string rather than a sequence of instructions. You could define rules based on whether a wall was immediately behind, in front, left or right of the robot; e.g.
This gives you a bit string consisting of 16 actions, each action encoded as 2 bits (00 = Move Forward, 01 = Turn Right, 10 = Turn Left, 11 = Move Backwards). When evaluating your agent it simply determines its current state and uses the bit string as a lookup table to determine how it should respond. It then repeats this a certain number of times after which point you evaluate its fitness.
Given this encoding the agent could evaluate the rule humans typically use which is “Follow the left hand wall continuously”. Obviously this approach will fail if the maze is not fully connected and in this case you need to encode more state into your rules based approach (e.g. the agent could respond differently if going over “old ground”).
Hope that helps.
EDIT
In response to your latest edit:
The fact that I’ve encoded the agent “sensors” detecting whether it is next to a wall or not isn’t relevant to the bit string (your gene), and perhaps I’ve slightly confused things with my example. The gene only encodes the actions (move forward, etc.) not the sensor states.
You should therefore write code to look-up the relevant part of the bit string given a particular combination of sensor readings; e.g.
Given this simple definition of a
Geneyou could embed this class within anAgentimplementation and record how the agent performs with the current gene “installed”; e.g.