BadHorse's answer is good if you want to solve a specific maze; you simply index your bit string as a sequence of precise instructions to guide the agent through the maze. In this case, your suitability is not the sum of the bit string (as you state in your question), but rather some metric that measures how successful the agent was in solving the problem. For example, your fitness may be defined as "the distance in a straight line from the end of the maze after processing 20 instructions."
Therefore, when evaluating each person, you allow him to process the first 20 commands from your bit string, and then calculate its suitability, perform any crossovers / mutations, and then create the next generation of people.
If you want to develop your agent to solve any maze , you need to encode the rules in your bit string, not a sequence of instructions. You could define rules based on whether the wall was immediately behind, in front, to the left or right of the robot; eg.
FBLR Action 0000 Move Forward 0001 Move Forward 0010 Turn Right etc
This gives you a 16-action bit string, each action is 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. Then he repeats this a certain number of times, after which you evaluate its suitability.
Given this encoding, the agent can evaluate the rule that people usually use that "continuously follows the left wall." Obviously, this approach will not work if the labyrinth is not fully connected, in which case you will need to encode more states in your rule-based approach (for example, the agent may react differently if iterates over the “old land”) .
Hope this helps.
EDIT
In response to your last change:
The fact that I encoded the "sensors" agent, which detects that it is near the wall or not, is not related to the bit string (your gene), and maybe I messed things up a bit in my example. The gene only encodes actions (moving forward, etc.) not the state of the sensor.
Therefore, you must write code to search for the corresponding part of the bit string, taking into account a specific combination of sensor readings; eg.
public enum Action { MOVE_FORWARD, REVERSE, TURN_LEFT, TURN_RIGHT Action decodeAction(boolean b1, boolean b2) { Action ret; if (b1) { ret = b2 ? Action.MOVE_FORWARD : Action.TURN_LEFT; } else { ret = b2 ? Action.TURN_RIGHT : Action.REVERSE; } return ret; } } public class Gene { private final boolean[] values = new boolean[32]; public Action getActionForSensorInputs(boolean wallInFront, boolean wallBehind, boolean wallToLeft, boolean wallToRight) { int i=0;
Given this simple definition of a Gene , you can embed this class in the Agent implementation and record how the agent executes the current “installed” gene; eg.
private enum Direction { NORTH, SOUTH, EAST, WEST }; public class Agent { private final Geneva gene; private final int x; // x position in maze; private final int y; // y position in maze; private Direction currentDirection; public double evaluate() { double fitness; // Perform up to 20 actions and then evaluate fitness. for (int i=0; i<20; ++i) { // TODO Determine sensor inputs. Action action = gene.getActionForSensorInputs(...); // TODO: Now apply action to update agent state. // If agent has reached goal exit loop and return fitness 1.0 (max fitness). // If agent has exited the maze then exit loop and return 0.0 (min fitness). } // Calculate fitness after 100 steps taken. For example could be // calculated as sqrt((goal.x - x) ^ 2 + (goal.y - y) ^ 2). return fitness; } }