TWEANNCrossover extends Crossover<TWEANN> { @Override public Genotype<TWEANN> crossover(Genotype<TWEANN> toModify, Genotype<TWEANN> toReturn) { includeExcess = RandomNumbers.randomGenerator.nextFloat() < includeExcessRate; TWEANNGenotype tr = (TWEANNGenotype) toReturn; TWEANNGenotype tm = (TWEANNGenotype) toModify; ArrayList<ArrayList<NodeGene>> alignedNodes = new ArrayList<ArrayList<NodeGene>>(2); alignedNodes.add(alignNodesToArchetype(tm.nodes, tr.archetypeIndex)); alignedNodes.add(alignNodesToArchetype(tr.nodes, tr.archetypeIndex)); ArrayList<ArrayList<NodeGene>> crossedNodes = cross(alignedNodes.get(0), alignedNodes.get(1)); ArrayList<ArrayList<LinkGene>> alignedLinks = alignLinkGenes(((TWEANNGenotype) toModify).links, tr.links); ArrayList<ArrayList<LinkGene>> crossedLinks = cross(alignedLinks.get(0), alignedLinks.get(1)); int[] originalAssociations = Arrays.copyOf(tm.moduleAssociations, tm.moduleAssociations.length); tm.nodes = crossedNodes.get(0); tm.links = crossedLinks.get(0); tm.calculateNumModules(); if (CommonConstants.hierarchicalMultitask) { tm.crossModuleAssociations(originalAssociations, tr.moduleAssociations); } tr.nodes = crossedNodes.get(1); tr.links = crossedLinks.get(1); tr.calculateNumModules(); if (CommonConstants.hierarchicalMultitask) { tr.crossModuleAssociations(tr.moduleAssociations, originalAssociations); } if(!TWEANNGenotype.smallerGenotypes) { if (CommonConstants.meltAfterCrossover) { tm.meltNetwork(); tr.meltNetwork(); } else { if (!tm.existsAlterableLink()) { if (Parameters.parameters.booleanParameter("prefFreezeUnalterable")) { new MeltThenFreezePreferenceMutation().mutate(tm); } else if (Parameters.parameters.booleanParameter("policyFreezeUnalterable")) { new MeltThenFreezePolicyMutation().mutate(tm); } else { System.out.println("Crossover allowed an unalterable network to be created"); System.exit(1); } } if (!tr.existsAlterableLink()) { if (Parameters.parameters.booleanParameter("prefFreezeUnalterable")) { new MeltThenFreezePreferenceMutation().mutate(tr); } else if (Parameters.parameters.booleanParameter("policyFreezeUnalterable")) { new MeltThenFreezePolicyMutation().mutate(tr); } else { System.out.println("Crossover allowed an unalterable network to be created"); System.exit(1); } } } } return tr; } TWEANNCrossover();  TWEANNCrossover(double includeExcessRate); @Override Genotype<TWEANN> crossover(Genotype<TWEANN> toModify, Genotype<TWEANN> toReturn); @SuppressWarnings("unchecked") ArrayList<ArrayList<G>> cross(ArrayList<G> left, ArrayList<G> right); void crossIndex(G leftGene, G rightGene, ArrayList<G> crossedLeft, ArrayList<G> crossedRight); static void printNodeAlignmentColumns(ArrayList<NodeGene> list, int archetypeIndex);  }
@Test public void test_Upper_Boundary() { Parameters.initializeParameterCollections(new String[] { "io:false", "netio:false", "connectToInputs:false", "crossExcessRate:1.0", "mating:true" }); MMNEAT.loadClasses(); TWEANNGenotype m = new TWEANNGenotype(MMNEAT.networkInputs, MMNEAT.networkOutputs, true, 1, 1, 0); for (int i = 0; i < NUM_MUTATION_ITERATIONS; i++) { m.linkMutation(); m.spliceMutation(); m.linkMutation(); m.weightMutation(); ; } TWEANNGenotype f = (TWEANNGenotype) m.copy(); for (int i = 0; i < NUM_MUTATION_ITERATIONS; i++) { m.linkMutation(); m.spliceMutation(); m.linkMutation(); m.weightMutation(); f.linkMutation(); f.spliceMutation(); f.linkMutation(); f.weightMutation(); } TWEANNGenotype originalM = (TWEANNGenotype) m.copy(); TWEANNGenotype originalF = (TWEANNGenotype) f.copy(); assertTrue(m.numIn == f.numIn && m.neuronsPerModule == f.neuronsPerModule); TWEANNGenotype o = (TWEANNGenotype) m.crossover(f); assertTrue(o.numIn == DEFAULT_NUMIN); assertTrue(o.numOut == DEFAULT_NUMOUT); assertTrue(m.numIn == DEFAULT_NUMIN); assertTrue(m.numOut == DEFAULT_NUMOUT); ArrayList<NodeGene> mGenotype = m.nodes; long[] mInno = new long[mGenotype.size()]; for (int i = 0; i < mGenotype.size(); i++) { mInno[i] = mGenotype.get(i).innovation; } ArrayList<NodeGene> oGenotype = o.nodes; long[] oInno = new long[oGenotype.size()]; for (int i = 0; i < oGenotype.size(); i++) { oInno[i] = oGenotype.get(i).innovation; } ArrayList<NodeGene> originalFGenotype = originalF.nodes; long[] originalFInno = new long[originalFGenotype.size()]; for (int i = 0; i < originalFGenotype.size(); i++) { originalFInno[i] = originalFGenotype.get(i).innovation; } ArrayList<NodeGene> originialMGenotype = originalM.nodes; long[] originalMInno = new long[originialMGenotype.size()]; for (int i = 0; i < originialMGenotype.size(); i++) { originalMInno[i] = originialMGenotype.get(i).innovation; } for (int i = 0; i < originalFInno.length; i++) { assertTrue(ArrayUtil.member(originalFInno[i], mInno)); assertTrue(ArrayUtil.member(originalFInno[i], oInno)); } for (int i = 0; i < originalMInno.length; i++) { assertTrue(ArrayUtil.member(originalMInno[i], oInno)); assertTrue(ArrayUtil.member(originalMInno[i], mInno)); } }
@Test public void test_Lower_Boundary() { Parameters.initializeParameterCollections(new String[] { "io:false", "netio:false", "connectToInputs:false", "crossExcessRate:0.0", "mating:true" }); MMNEAT.loadClasses(); TWEANNGenotype m = new TWEANNGenotype(MMNEAT.networkInputs, MMNEAT.networkOutputs, true, 1, 1, 0); TWEANNGenotype f = (TWEANNGenotype) m.copy(); for (int i = 0; i < NUM_MUTATION_ITERATIONS; i++) { m.linkMutation(); m.spliceMutation(); m.linkMutation(); m.weightMutation(); f.linkMutation(); f.spliceMutation(); f.linkMutation(); f.weightMutation(); } TWEANNGenotype originalM = (TWEANNGenotype) m.copy(); TWEANNGenotype originalF = (TWEANNGenotype) f.copy(); assertTrue(m.numIn == f.numIn && m.neuronsPerModule == f.neuronsPerModule); TWEANNGenotype o = (TWEANNGenotype) m.crossover(f); assertTrue(o.numIn == DEFAULT_NUMIN); assertTrue(o.numOut == DEFAULT_NUMOUT); assertTrue(m.numIn == DEFAULT_NUMIN); assertTrue(m.numOut == DEFAULT_NUMOUT); ArrayList<NodeGene> mGenotype = m.nodes; long[] mInno = new long[mGenotype.size()]; for (int i = 0; i < mGenotype.size(); i++) { mInno[i] = mGenotype.get(i).innovation; } ArrayList<NodeGene> oGenotype = o.nodes; long[] oInno = new long[oGenotype.size()]; for (int i = 0; i < oGenotype.size(); i++) { oInno[i] = oGenotype.get(i).innovation; } ArrayList<NodeGene> originalFGenotype = originalF.nodes; long[] originalFInno = new long[originalFGenotype.size()]; for (int i = 0; i < originalFGenotype.size(); i++) { originalFInno[i] = originalFGenotype.get(i).innovation; } ArrayList<NodeGene> originialMGenotype = originalM.nodes; long[] originalMInno = new long[originialMGenotype.size()]; for (int i = 0; i < originialMGenotype.size(); i++) { originalMInno[i] = originialMGenotype.get(i).innovation; } for (int i = 0; i < originalFInno.length; i++) { if (originalFInno[i] > 0) { assertFalse(ArrayUtil.member(originalFInno[i], mInno)); assertTrue(ArrayUtil.member(originalFInno[i], oInno)); } } for (int i = 0; i < originalMInno.length; i++) { if (originalMInno[i] > 0) { assertFalse(ArrayUtil.member(originalMInno[i], oInno)); assertTrue(ArrayUtil.member(originalMInno[i], mInno)); } } }