public static List <Node> Reproduce(Node p1, Node p2) { int initialMove; List <Node> children = new List <Node>(); children.Add(new Node()); children.Add(new Node()); children[1].staleness = children[0].staleness = (p1.staleness + p2.staleness) / 2; for (int i = 0; i < (int)(NumMoves * CrossoverPoint); i++) { // copy parent genes children[0].moves.Add(p1.moves[i]); children[1].moves.Add(p2.moves[i]); // add mutation for (int j = 0; j < 2; j++) { if (MyRand.rand.NextDouble() < AILearning.MUTATION_PERCENT) { initialMove = children[j].moves[i]; do { children[j].moves[i] = MyRand.NextInt(4); } while (children[j].moves[i] != initialMove); } } } for (int i = (int)(NumMoves * CrossoverPoint); i < NumMoves; i++) { // copy parent genes children[0].moves.Add(p2.moves[i]); children[1].moves.Add(p1.moves[i]); // add mutation for (int j = 0; j < 2; j++) { if (MyRand.rand.NextDouble() < AILearning.MUTATION_PERCENT) { initialMove = children[j].moves[i]; do { children[j].moves[i] = MyRand.NextInt(4); } while (children[j].moves[i] != initialMove); } } } //Debug.Assert(children[0].moves.Count == children[1].moves.Count); return(children); }
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); }