void Reproduce() { Node p1, p2; int[] parents = new int[2]; int length; //if (stalenessCount > 5 && AILearning.MUTATION_PERCENT < .5) // AILearning.MUTATION_PERCENT += .05; //else if (stalenessCount <= 5 && AILearning.MUTATION_PERCENT > .05) // AILearning.MUTATION_PERCENT -= .05; //if (stalenessCount > 5 && Node.CrossoverPoint >= 0.1) // Node.CrossoverPoint -= 0.1; //else if (stalenessCount <= 5 && Node.CrossoverPoint < .75) // Node.CrossoverPoint += .01; // select the x% fittest population to have an orgy; slaughter the rest int numToRemove = ((int)(GENERATION_SIZE * (1.0 - SELECTION_PERCENT))) - (GENERATION_SIZE - nodes.Count); if (numToRemove >= 0 && nodes.Count - numToRemove >= 10) { nodes.RemoveRange(0, numToRemove); } if (nodes[nodes.Count - 1].moves.Count != nodes[0].moves.Count) { nodes.RemoveAt(nodes.Count - 1); } length = nodes.Count; while (nodes.Count < GENERATION_SIZE) { // pick two parents MyRand.GenerateRandomList(2, length, parents); p1 = nodes[parents[0]]; p2 = nodes[parents[1]]; //Debug.Assert(p1.moves.Count == p2.moves.Count); // ahh, the magic of life nodes.AddRange(Node.Reproduce(p1, p2)); } //nodes.ForEach(n => Debug.Assert(n.moves.Count == Node.NumMoves)); for (int i = 0; i < nodes.Count; i++) { nodes[i].x = 1; nodes[i].y = 0; } }
int GenerateMove(Node n, int expectedMove) { return(MyRand.rand.Next(4)); int[] moves = new int[4]; MyRand.GenerateRandomList(4, moves); int x, y; int move; int index = 0; do { // this is essentially our repair function for invalid paths // this introduces more variability into the population as well move = expectedMove >= 0 ? expectedMove : moves[index++]; //move = moves[0]; x = n.x; y = n.y; switch (move) { case 0: x++; break; case 1: y++; break; case 2: x--; break; case 3: y--; break; } expectedMove = -1; } while (!maze.isValidMove(x, y)); return(move); }