public Simulator() { Population = new Dictionary<int, Chromosome>(); Scores = new Dictionary<int, int>(); Trace.WriteLine("Sim setting up, creating " + PopulationSize + " genomes."); Random = new Random((int)DateTime.Now.Ticks % Int32.MaxValue); for (int i = 0; i < PopulationSize; i++) { var c = new Chromosome(Chromosome.CreateOriginAction()); var cond = c.CreateConditional(); cond.Success = c.CreateAction(); cond.Failure = c.CreateAction(); c.Genome.AddChild(cond); Population.Add(c.GetHashCode(), c); } Trace.WriteLine("Sim simulator ready to go."); }
public void DoRun(Chromosome DNA, int RunLength) { ResetState(); var runStart = DateTime.Now.Ticks; while ( DateTime.Now.Ticks - runStart < RunLength) { var actions = DNA.Enumerate(State).ToList(); Trace.Write("Emu got "+actions.Count()+" actions for this tick. Applying..."); foreach (var action in actions.OfType<Action>()) { //write action's angles to state foreach (var kv in action.Angles) State[kv.Key] = kv.Value; //upload the new state to the device UpdateState(State); //wait for the actions to complete var start = DateTime.Now.Ticks; while (!ReadState().SequenceEqual(State) && DateTime.Now.Ticks- start < ActionCompletionTimeout) ; } Trace.WriteLine(" done"); } }
protected int JudgeFitness(Chromosome g) { //run simulation var robot = new Robot(); robot.DoRun(g, RunLength); //judge score var gyro = robot.GetGyroState(); var tilt = Math.Abs(gyro[0]) + Math.Abs(gyro[1]); if (tilt < 1) //floor tilt at 1 so there arn't DbZ issues tilt = 1; //we're trying to judge closeness to 0 for the x and y but height for z also encourage smalller programs var score = (100 / tilt) * gyro[2] / g.Enumerate().Count(); Trace.WriteLine(String.Format("Run ended, judging fitness for " + g + " Gyro state: {0}, {1}, {2}. Score: {3}", gyro[0], gyro[1], gyro[2], score)); return score; }
/// <summary> /// Creates and returns a mutated version of this chromosome /// </summary> /// <param name="MutatePercentChance">The percentage chance that any given node in the chromosome will be modified</param> /// <returns></returns> public Chromosome Mutate(int MutatePercentChance) { var c = new Chromosome(Genome.Clone() as Node); var nodes = c.Enumerate().ToList(); Trace.Write("Mutating: "); foreach (var n in nodes) { if (Random.Next(100) < MutatePercentChance) { //can add a child if (Random.Next(100) < MutateChanceAdd && nodes.Count < MutateMaxSize) { Trace.Write(" add "); n.AddChild(CreateNode()); } //can lose a child if ((Random.Next(100) < MutateChanceLose && nodes.Count > MutateMinSize) || nodes.Count > MutateMaxSize) { Trace.Write(" rem "); if (n.Children.Count > 0) n.RemoveChild(n.Children[Random.Next(n.Children.Count)]); } //can change an action (this is like add and lose) or a functor if (Random.Next(100) < MutateChanceMutate) { Trace.Write(" mut "); var a = n as Action; if (a != null) Mutate(a); else { var co = n as Conditional; if (co != null) Mutate(co); } //n.GetType().GetMethod("Mutate").Invoke(n, null); } } } Trace.WriteLine(""); return c; }
/// <summary> /// Swaps a random subtree in this chromosome with a random subtree in the partner one. won't modify the chromosome if nodes <= 1 /// </summary> /// <param name="partner"></param> public Chromosome[] Crossover(Chromosome partner) { var child1 = this.Clone() as Chromosome; var child2 = partner.Clone() as Chromosome; var nodes1 = child1.Enumerate().Count(); var nodes2 = child2.Enumerate().Count(); Node parent1 = null, parent2 = null; while (parent1 == null && parent2 == null && nodes1 > 1 && nodes2 > 1) { var child1Site = child1.Enumerate().ElementAt(Random.Next(nodes1)); var child2Site = child2.Enumerate().ElementAt(Random.Next(nodes2)); parent1 = child1.Enumerate().FirstOrDefault(n => n.Children.Contains(child1Site)); parent2 = child2.Enumerate().FirstOrDefault(n => n.Children.Contains(child2Site)); if (parent1 != null && parent2 != null) //can't be crossing over root nodes! { parent1.AddChild(child2Site, parent1.Children.IndexOf(child1Site)); parent2.AddChild(child1Site, parent2.Children.IndexOf(child2Site)); parent1.RemoveChild(child1Site); parent2.RemoveChild(child2Site); } } return new Chromosome[] { child1, child2 }; }
public object Clone() { var c = new Chromosome(Genome.Clone() as Node); return c; }