// Genetic Ant Algorithm // Carl E. Bredlau // from Koza, _Genetic Programming_, MIT Press // programmed modeled after sga. Thanks to the author. package geneticAnt; public class Ant implements Cloneable { // An ant // From the ant's point of view it only sees food. It does not know // where on the board it is. // For counting ants: private static int antCount = 0; int antID = 0; // which ant Chromosome chromo; int state = 0; // internal state; int fitness = 1; // How good the ant is int parent1 = -1; // "Parents" of the ant int parent2 = -1; int age = 0; // age of ant int gene = -1; // where we swap or mutate public Ant(int states) { chromo = new Chromosome(states); antID = antCount++; } // Ant moves: public static final int MOVE = Chromosome.MOVE; // move foward public static final int LEFT = Chromosome.LEFT; // turn left public static final int RIGHT = Chromosome.RIGHT; // move right public static final int NOP = Chromosome.NOP; // don't move public int move(boolean sees_food) { // depending upon the state and whether it sees food, change // state and return what it will do. int mem_loc = 2*state; if (sees_food) { // move down one state if food is there... mem_loc++; } state = chromo.mem[mem_loc].state; return chromo.mem[mem_loc].action; } public void incFitness() {fitness++;} public void walk (Board board, int numMoves) { // Ant walks on the board to determine fitness fitness = 1; state = 0; // Put ant on board board.place(); // System.out.println("Move: " + 0 + " State: " + state + // " Fitness is " + fitness); // board.show(); // for testing. for (int moves = 1; moves <= numMoves; moves++) { int ant_move = move(board.isFood()); // Ant moves or turns int foodEaten = board.moveAnt(ant_move); if (foodEaten == board.FOOD) incFitness(); // for testing... // System.out.println("Move: " + moves + " State: " + state + // " Fitness is " + fitness); // board.show(); } } // (new IntRandom(2)).nextInt()) public Ant mutate() { // returns a mutated ant: one state or action is changed Ant a = (Ant) clone(); a.parent1 = antID; a.parent2 = -1; a.gene = a.chromo.randGene.nextInt(); a.chromo.mem[a.gene].state = a.chromo.randState.nextInt(); a.chromo.mem[a.gene].action = a.chromo.randAction.nextInt(); // if ( (new IntRandom(2)).nextInt() == 0 ) // Which one to mutate // a.chromo.mem[a.gene].state = a.chromo.randState.nextInt(); // else // a.chromo.mem[a.gene].action = a.chromo.randAction.nextInt(); return a; } public Ant[] crossover(Ant a) { // returns two ants that contain the swapped genes of the parente Ant[] newAnt = new Ant[2]; newAnt[0] = (Ant) this.clone(); newAnt[1] = (Ant) a.clone(); newAnt[0].parent2 = this.antID; newAnt[0].parent1 = a.antID; newAnt[1].parent1 = this.antID; newAnt[1].parent2 = a.antID; // choose gene to crossover do { newAnt[0].gene = newAnt[0].chromo.randGene.nextInt(); // System.out.println(" Gene is " + newAnt[0].gene); } while (newAnt[0].gene == 0); newAnt[1].gene = newAnt[0].gene; // copy genes for (int i = 0; i < newAnt[0].gene; i ++) newAnt[0].chromo.mem[i] = (Gene) a.chromo.mem[i].clone(); for (int i = 0; i < newAnt[0].gene; i ++) newAnt[1].chromo.mem[i] = (Gene) this.chromo.mem[i].clone(); return newAnt; } public void show() { System.out.print("Ant " + antID + ": fit: " + fitness + " age: " + age); if (parent1 != -1) if (parent2 != -1) System.out.print(" parents (" + parent1 + "," + parent2 + ") "); else System.out.print(" parent " + parent1 +" "); System.out.print( " gene "); if (gene == -1) System.out.println("[ - ]"); else { String s; int x = gene/2; int y = gene %2; if (y == 0) s = "N"; else s = "Y"; System.out.println("[" + x + " " + s + "]"); } } public void show(boolean show_mem) { show(); if (show_mem) chromo.show(); } public static int numAnts() { return Ant.antCount; } protected Object clone() { // The only thing we need to worry about is the states and the age Ant a; try { a = (Ant) super.clone(); a.chromo = (Chromosome) chromo.clone(); a.antID = antCount++; a.age = 0; // new age } catch (CloneNotSupportedException e) { // cannot happen so throw new InternalError(e.toString()); } return a; } public static void main(String args[]) { Board board = new Board(10); // one board Ant a = new Ant(6); Board b = (Board) board.clone(); a.walk(b,200); a.show(true); b.show(); for (int i = 0; i < 1; i++) { System.out.println("============================"); a = a.mutate(); b = (Board) board.clone(); a.walk(b,200); a.show(true); b.show(); } Ant c = new Ant(6); b = (Board) board.clone(); c.walk(b,200); c.show(true); Ant[] ants = new Ant[2]; ants = a.crossover(c); b = (Board) board.clone(); ants[0].walk(b,200); ants[0].show(true); b = (Board) board.clone(); ants[1].walk(b,200); ants[1].show(true); System.out.println(Ant.antCount); } }