public NeatAI crossOver(NeatAI second, double fitness1, double fitness2, double disableRate) { NeatAI first; // Line up links/genes ArrayList<Integer> ai1linkListPos; ArrayList<Integer> ai2linkListPos; ArrayList<ArrayList<Integer>> temp = lineUpAILinks(second); ArrayList<Integer> linkIDs = temp.get(0); // Make it so first is the fitter individual. if (fitness2 > fitness1) { first = second; second = this; ai1linkListPos = temp.get(2); ai2linkListPos = temp.get(1); } else { first = this; ai1linkListPos = temp.get(1); ai2linkListPos = temp.get(2); } // Clone data. // System.out.println("p2"); ArrayList<Gene> firstL = first.getCloneLinks(); ArrayList<Gene> secondL = second.getCloneLinks(); ArrayList<Neuron> newN = new ArrayList<Neuron>(); ArrayList<Gene> newL = new ArrayList<Gene>(); newN = first.getCloneNeurons(); // System.out.println("p3"); for (int i = 0; i < firstL.size(); i++) { Gene gene1 = firstL.get(i); Gene gene2; int gene2pos = ai2linkListPos.get(linkIDs.indexOf(gene1.getHistID())); if (gene2pos == -1) { gene2 = null; } else { gene2 = secondL.get(gene2pos); } if (gene2 != null && rand.nextBoolean() && !gene2.isDisabled()) { newL.add(gene2); } else { newL.add(gene1); } } // System.out.println("New AI"); // (SimpleMap sm_, ArrayList<Neuron> n, ArrayList<Link> l, int numInputs_, int numOutputs_) { // System.out.println("p4"); NeatAI newai = new NeatAI(sm, newN, newL, numInputs, numOutputs); return newai; }
/* * This method lines up two AI's links, aka genes, and returns the order of the lined up genes, and where they occur. * This method returns an arraylist of arraylist of Integer. * The outer arraylist contains arraylists on: * 0: neuron historical ID of links present in the two AI * 1: where in the first ai's link list the link occurs * 2: where in the second ai's link list the link occurs */ public ArrayList<ArrayList<Integer>> lineUpAILinks(NeatAI second) { ArrayList<Gene> secondL = second.getCloneLinks(); ArrayList<Integer> ai1histIDlist = new ArrayList<Integer>(); ArrayList<Integer> ai2histIDlist = new ArrayList<Integer>(); ArrayList<Integer> linkID = new ArrayList<Integer>(); ArrayList<Integer> linkList1Pos = new ArrayList<Integer>(); ArrayList<Integer> linkList2Pos = new ArrayList<Integer>(); // Get genes. int histID; for (Gene l : links) { histID = l.getHistID(); linkID.add(histID); ai1histIDlist.add(histID); } int pos; for (Gene l : secondL) { histID = l.getHistID(); pos = linkID.indexOf(histID); if (pos == -1) { // New histID found linkID.add(histID); } ai2histIDlist.add(histID); } // Sort genes // Bubble sort, meh int lowest; for (int i = 0; i < linkID.size(); i++) { lowest = i; for (int j = i + 1; j < linkID.size(); j++) { if (linkID.get(j) < linkID.get(lowest)) { lowest = j; } } int temp = linkID.get(i); linkID.set(i, linkID.get(lowest)); linkID.set(lowest, temp); } // Add gene positions for (Integer tempID : linkID) { linkList1Pos.add(ai1histIDlist.indexOf(tempID)); linkList2Pos.add(ai2histIDlist.indexOf(tempID)); } ArrayList<ArrayList<Integer>> temp = new ArrayList<ArrayList<Integer>>(); temp.add(linkID); temp.add(linkList1Pos); temp.add(linkList2Pos); return temp; }
public double compatibilityDistance(NeatAI second, double c1, double c2, double c3, int minSize) { double compatibilityDistance = 0.0; ArrayList<Gene> secondL = second.getCloneLinks(); // Line up links/genes ArrayList<ArrayList<Integer>> temp; temp = lineUpAILinks(second); ArrayList<Integer> ai1linkListPos = temp.get(1); ArrayList<Integer> ai2linkListPos = temp.get(2); ArrayList<Double> nodeWeightDifferences = new ArrayList<Double>(); int disjointGeneCount = 0; int excessGeneCount = 0; int pos1; int pos2; for (int i = 0; i < ai1linkListPos.size(); i++) { pos1 = ai1linkListPos.get(i); pos2 = ai2linkListPos.get(i); if (pos1 == -1 || pos2 == -1) { excessGeneCount++; } else { disjointGeneCount += excessGeneCount; excessGeneCount = 0; nodeWeightDifferences.add( Math.abs(links.get(pos1).getWeight() - secondL.get(pos2).getWeight())); } } double sum = 0; double averageWeightDifference; for (double weightDifference : nodeWeightDifferences) { sum += weightDifference; } averageWeightDifference = sum / nodeWeightDifferences.size(); int largerGenomeSize = Math.max(links.size(), secondL.size()); if (largerGenomeSize < minSize) { largerGenomeSize = 1; } compatibilityDistance = c1 * excessGeneCount / largerGenomeSize + c2 * disjointGeneCount / largerGenomeSize + c3 * averageWeightDifference; return compatibilityDistance; }