public override void Setup(IEvolutionState state, IParameter paramBase) { base.Setup(state, paramBase); var def = DefaultBase; var p = paramBase.Push(P_NODESELECTOR).Push("0"); var d = def.Push(P_NODESELECTOR).Push("0"); NodeSelect0 = (IGPNodeSelector)(state.Parameters.GetInstanceForParameter(p, d, typeof(IGPNodeSelector))); NodeSelect0.Setup(state, p); p = paramBase.Push(P_NODESELECTOR).Push("1"); d = def.Push(P_NODESELECTOR).Push("1"); if (state.Parameters.ParameterExists(p, d) && state.Parameters.GetString(p, d).Equals(V_SAME)) { // can't just copy it this time; the selectors // use internal caches. So we have to clone it no matter what NodeSelect1 = (IGPNodeSelector)(NodeSelect0.Clone()); } else { NodeSelect1 = (IGPNodeSelector)(state.Parameters.GetInstanceForParameter(p, d, typeof(IGPNodeSelector))); NodeSelect1.Setup(state, p); } NumTries = state.Parameters.GetInt(paramBase.Push(P_NUM_TRIES), def.Push(P_NUM_TRIES), 1); if (NumTries == 0) { state.Output.Fatal("InternalCrossover Pipeline has an invalid number of tries (it must be >= 1).", paramBase.Push(P_NUM_TRIES), def.Push(P_NUM_TRIES)); } MaxDepth = state.Parameters.GetInt(paramBase.Push(P_MAXDEPTH), def.Push(P_MAXDEPTH), 1); if (MaxDepth == 0) { state.Output.Fatal("InternalCrossover Pipeline has an invalid maximum depth (it must be >= 1).", paramBase.Push(P_MAXDEPTH), def.Push(P_MAXDEPTH)); } Tree1 = TREE_UNFIXED; if (state.Parameters.ParameterExists(paramBase.Push(P_TREE).Push("" + 0), def.Push(P_TREE).Push("" + 0))) { Tree1 = state.Parameters.GetInt(paramBase.Push(P_TREE).Push("" + 0), def.Push(P_TREE).Push("" + 0), 0); if (Tree1 == -1) { state.Output.Fatal("Tree fixed value, if defined, must be >= 0"); } } Tree2 = TREE_UNFIXED; if (state.Parameters.ParameterExists(paramBase.Push(P_TREE).Push("" + 1), def.Push(P_TREE).Push("" + 1))) { Tree2 = state.Parameters.GetInt(paramBase.Push(P_TREE).Push("" + 1), def.Push(P_TREE).Push("" + 1), 0); if (Tree2 == -1) { state.Output.Fatal("Tree fixed value, if defined, must be >= 0"); } } }
public override object Clone() { var c = (InternalCrossoverPipeline)(base.Clone()); // deep-cloned stuff c.NodeSelect0 = (IGPNodeSelector)(NodeSelect0.Clone()); c.NodeSelect1 = (IGPNodeSelector)(NodeSelect1.Clone()); return(c); }
public override int Produce( int min, int max, int subpop, IList <Individual> inds, IEvolutionState state, int thread, IDictionary <string, object> misc) { int start = inds.Count; // grab n individuals from our source and stick 'em right into inds. // we'll modify them from there var n = Sources[0].Produce(min, max, subpop, inds, state, thread, misc); IntBag[] parentparents = null; IntBag[] preserveParents = null; if (misc != null && misc.ContainsKey(KEY_PARENTS)) { preserveParents = (IntBag[])misc[KEY_PARENTS]; parentparents = new IntBag[2]; misc[KEY_PARENTS] = parentparents; } // should we bother? if (!state.Random[thread].NextBoolean(Likelihood)) { return(n); } var initializer = (GPInitializer)state.Initializer; for (var q = start; q < n + start; q++) { var i = (GPIndividual)inds[q]; if (Tree1 != TREE_UNFIXED && (Tree1 < 0 || Tree1 >= i.Trees.Length)) { // uh oh state.Output.Fatal("Internal Crossover Pipeline attempted to fix tree.0 to a value" + " which was out of bounds of the array of the individual's trees. " + " Check the pipeline's fixed tree values -- they may be negative" + " or greater than the number of trees in an individual"); } if (Tree2 != TREE_UNFIXED && (Tree2 < 0 || Tree2 >= i.Trees.Length)) { // uh oh state.Output.Fatal("Internal Crossover Pipeline attempted to fix tree.0 to a value" + " which was out of bounds of the array of the individual's trees. " + " Check the pipeline's fixed tree values -- they may be negative" + " or greater than the number of trees in an individual"); } var t1 = 0; var t2 = 0; if (Tree1 == TREE_UNFIXED || Tree2 == TREE_UNFIXED) { do // pick random trees -- their GPTreeConstraints must be the same { if (Tree1 == TREE_UNFIXED) { if (i.Trees.Length > 1) { t1 = state.Random[thread].NextInt(i.Trees.Length); } else { t1 = 0; } } else { t1 = Tree1; } if (Tree2 == TREE_UNFIXED) { if (i.Trees.Length > 1) { t2 = state.Random[thread].NextInt(i.Trees.Length); } else { t2 = 0; } } else { t2 = Tree2; } }while (i.Trees[t1].Constraints(initializer) != i.Trees[t2].Constraints(initializer)); } else { t1 = Tree1; t2 = Tree2; // make sure the constraints are okay if (i.Trees[t1].Constraints(initializer) != i.Trees[t2].Constraints(initializer)) { // uh oh state.Output.Fatal("GP Crossover Pipeline's two tree choices are both specified by the user -- but their GPTreeConstraints are not the same"); } } // prepare the nodeselectors NodeSelect0.Reset(); NodeSelect1.Reset(); // pick some nodes GPNode p1 = null; GPNode p2 = null; var res = false; for (var x = 0; x < NumTries; x++) { // pick a node in individual 1 p1 = NodeSelect0.PickNode(state, subpop, thread, i, i.Trees[t1]); // pick a node in individual 2 p2 = NodeSelect1.PickNode(state, subpop, thread, i, i.Trees[t2]); // make sure they're not the same node res = (p1 != p2 && (t1 != t2 || NoContainment(p1, p2)) && VerifyPoints(initializer, p1, p2) && VerifyPoints(initializer, p2, p1)); // 2 goes into 1 if (res) { break; // got one } } // if res, then it's time to cross over! if (res) { var oldparent = p1.Parent; var oldArgPosition = p1.ArgPosition; p1.Parent = p2.Parent; p1.ArgPosition = p2.ArgPosition; p2.Parent = oldparent; p2.ArgPosition = oldArgPosition; if (p1.Parent is GPNode) { ((GPNode)(p1.Parent)).Children[p1.ArgPosition] = p1; } else { ((GPTree)(p1.Parent)).Child = p1; } if (p2.Parent is GPNode) { ((GPNode)(p2.Parent)).Children[p2.ArgPosition] = p2; } else { ((GPTree)(p2.Parent)).Child = p2; } i.Evaluated = false; // we've modified it } // add the individuals to the population //inds[q] = i; inds.Add(i); if (preserveParents != null) { parentparents[0].AddAll(parentparents[1]); preserveParents[q] = new IntBag(parentparents[0]); } } return(n); }