public override void MutateWeightShift(ChaoticSeer seer) { ConnectionGene con = seer.Connections.Random; if (con != null) { con.Weight += ((Rng.GetRngF() * 2) - 1) * NeatCNS.WEIGHT_SHIFT_STRENGTH; } }
static void Main(string[] args) { NeatCNS neat = new NeatCNS(3, 3, 100); ChaoticSeer g = new ChaoticSeer(neat); //Genome g = neat.NewEmptyGenome(); Console.WriteLine(g.Nodes.Count); Console.ReadKey(); }
public override void MutateToggleConnection(ChaoticSeer seer) { ConnectionGene con = seer.Connections.Random; if (con != null) { con.IsEnabled = con.IsEnabled; } }
private void GeneticsTest_Load(object sender, EventArgs e) { tribe = new TribeST(2, 1, 10); region = new RegionST(3, 2, 1, 10); genomeRepresentative = tribe.Species[0]; pictureBoxes = new PictureBox[tribe.Species.Count]; InitializePictureBoxes(); Console.WriteLine("Nodes: " + genomeRepresentative.Nodes.Count); Console.WriteLine("Connections: " + genomeRepresentative.Connections.Count); }
public override void MutateNode(ChaoticSeer seer) { if (seer.Nodes.Count >= NeatCNS.MAX_NODES) { return; // Cap nodes } if (seer.Nodes.Count >= NeatCNS.T_MAX_NODES) { return; // Cap nodes } ConnectionGene con = seer.Connections.Random; if (con == null) { return; } NodeGene from = con.From; NodeGene middle; NodeGene to = con.To; int replaceIndex = Sg.Neat.GetReplaceIndex(from, to); if (replaceIndex == 0) { middle = Sg.Neat.AddNode(); middle.X = (from.X + to.X) / 2; middle.Y = (from.Y + to.Y) / 2 + (float)((Rng.GetRngF() * 0.1) - 0.05); Sg.Neat.SetReplaceIndex(from, to, middle.InnovationNumber); } else { middle = Sg.Neat.AddNode(replaceIndex); } //NodeGene middle = Neat.AddNode(); //middle.X = (from.X + to.X) / 2; //Divide by to to get the center //middle.Y = (from.Y + to.Y) / 2; //Divide by to to get the center ConnectionGene con1 = Sg.Neat.AddConnection(from, middle); ConnectionGene con2 = Sg.Neat.AddConnection(middle, to); con1.Weight = 1; con2.Weight = con.Weight; con2.IsEnabled = con.IsEnabled; seer.Connections.Remove(con); seer.Connections.Add(con1); seer.Connections.Add(con2); seer.Nodes.Add(middle); }
public override void MutateConnection(ChaoticSeer seer) { for (int i = 0; i < 100; i++) { NodeGene a = seer.Nodes.Random; NodeGene b = seer.Nodes.Random; if (a == null || b == null) { continue; //skip if empty } if (a.X == b.X) { continue; //skip if thesame } // Create connection for the new seed ConnectionGene con; if (a.X < b.X) { con = new ConnectionGene(a, b); } else { con = new ConnectionGene(b, a); } if (seer.Connections.Contains(con)) { //skip if newly generated connection already exist continue; } con = Sg.Neat.AddConnection(con.From, con.To); con.Weight = ((Rng.GetRngF() * 2) - 1) * NeatCNS.WEIGHT_RANDOM_STRENGTH; //Attempt to ensure that the data is sorted by its InnovaitonNumber for (int cI = 0; i < seer.Connections.Count; i++) { int innovation = seer.Connections[cI].InnovationNumber; if (con.InnovationNumber < innovation) { //Insert it right next seer.Connections.Insert(cI, con); return; } } seer.Connections.Add(con); return; } }
public FPropagateST(ChaoticSeer seer) { InputNodes = new List <CalcNode>(); HiddenNodes = new List <CalcNode>(); OutputNodes = new List <CalcNode>(); GeneHashSet <NodeGene> _nodes = seer.Nodes; GeneHashSet <ConnectionGene> _cons = seer.Connections; Dictionary <int, CalcNode> _nodeHashMap = new Dictionary <int, CalcNode>(); foreach (NodeGene item in _nodes.Data) { CalcNode node = new CalcNode(item.X); _nodeHashMap.Add(item.InnovationNumber, node); if (item.X <= 0.1f) { InputNodes.Add(node); } else if (item.X >= 0.9f) { OutputNodes.Add(node); } else { HiddenNodes.Add(node); } } HiddenNodes.Sort(); //This thing is working correct foreach (ConnectionGene item in _cons.Data) { NodeGene from = item.From; NodeGene to = item.To; CalcNode node_from = _nodeHashMap[from.InnovationNumber]; CalcNode node_to = _nodeHashMap[to.InnovationNumber]; CalcConnection con = new CalcConnection(node_from, node_to) { Weight = item.Weight, IsEnabled = item.IsEnabled }; node_to.Connections.Add(con); } }
public override void Reproduce() { //Currently it will just fill up to max population // TODO: add something to prevent mating with self //for (int i = 0; i < 1; i++) { // ChaoticSeer _seerX = Species.Random; // ChaoticSeer _seerY = Species[i]; // ChaoticSeer _seerChild = _seerY.MateWith(_seerX); // _seerChild.Identity = _seerX.Identity + _seerY.Identity; // Species.Add(_seerChild); //} do { ChaoticSeer _seerX = Species.Random; ChaoticSeer _seerY = Species.Random; ChaoticSeer _seerChild = _seerX.MateWith(_seerY); _seerChild.Identity = _seerX.Identity + _seerY.Identity; Species.Add(_seerChild); } while (Species.Count < MAX_POPULATION); }
/// <summary> /// Creates a new genome based on two genomes /// </summary> /// <param name="g1">X Genome</param> /// <param name="g2">Y Genome</param> /// <returns></returns> public abstract ChaoticSeer CrossOver(ChaoticSeer g1, ChaoticSeer g2);
/// <summary> /// Toggle connection /// </summary> public abstract void MutateToggleConnection(ChaoticSeer seer);
/// <summary> /// Shift weight based on random strength /// </summary> public abstract void MutateWeightRandom(ChaoticSeer seer);
/// <summary> /// Shift weight based on shift strength /// </summary> public abstract void MutateWeightShift(ChaoticSeer seer);
/// <summary> /// Add node /// </summary> public abstract void MutateNode(ChaoticSeer seer);
public static Bitmap GenBitmap(ChaoticSeer _seer) { Bitmap Bm; int PictureScale = 1; //PictureScale = 1; Pen connectionPen = new Pen(Color.Blue); SolidBrush nodeBrush = new SolidBrush(Color.Green); SolidBrush textBrushWhite = new SolidBrush(Color.White); SolidBrush textBrushBlack = new SolidBrush(Color.Black); Point[] nodePoints = NodeToPoints(_seer.Nodes.ToArray()); Point[][] connectionPoints = ConnectionsToPoint(_seer.Connections.ToArray()); float CanvasWidth = 100; //Limit the minimun size float CanvasHeight = 100; //Limit the minimun size //Get the largest point for (int i = 0; i < nodePoints.Length; i++) { CanvasWidth = Math.Max(nodePoints[i].X, CanvasWidth); CanvasHeight = Math.Max(nodePoints[i].Y, CanvasHeight); } CanvasWidth += 10; CanvasHeight += 10; Bm = new Bitmap( (int)(PictureScale * CanvasWidth), (int)(PictureScale * CanvasHeight)); //Console.WriteLine("Canvas Size: " + CanvasWidth + " x " + CanvasHeight); //Console.WriteLine("Nodes: " + _seer.Nodes.Count); //Console.WriteLine("Connections: " + _seer.Connections.Count); Graphics gr = Graphics.FromImage(Bm); gr.Clear(Color.AliceBlue); gr.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; gr.ScaleTransform(PictureScale, PictureScale); Rectangle[] rectangles = new Rectangle[nodePoints.Length]; ////Draw line //gr.DrawCurve(connectionPen, nodePoints, 0.0f); for (int i = 0; i < connectionPoints.Length; i++) { gr.DrawLine(connectionPen, connectionPoints[i][0], connectionPoints[i][1]); } //Draw circle/node for (int i = 0; i < nodePoints.Length; i++) { Point _offset = nodePoints[i]; _offset.Offset(-8, -8); rectangles[i] = new Rectangle(_offset, new Size(16, 16)); } foreach (Rectangle item in rectangles) { gr.FillEllipse(nodeBrush, item); } //Draw text InnovationNumber //gr.DrawString("ASDF", new Font("Arial", 16), textBrush, new Point(10,10)); for (int i = 0; i < nodePoints.Length; i++) { Point _offset = nodePoints[i]; _offset.Offset(-5, -7); gr.DrawString("" + _seer.Nodes[i].InnovationNumber, new Font("Courier New", 8), textBrushWhite, _offset); //rectangles[i] = new Rectangle(_offset, new Size(10, 10)); } //Draw text Status string status = "Identity: " + _seer.Identity + Environment.NewLine + "Fitness: " + _seer.Fitness + Environment.NewLine + "Day: " + _seer.Day + Environment.NewLine + "Age: " + _seer.Year; gr.DrawString(status, new Font("Courier New", 8), textBrushBlack, new Point(600, 0)); //picCanvas.Image = Bm; return(Bm); }
public override ChaoticSeer CrossOver(ChaoticSeer g1, ChaoticSeer g2) { /// current g1 should have the higher score /// take all the genes of g1 /// if there is a genome in g1 that is also in g2, choose randomly /// do not take disjoint genes of g2 /// take excess genes of g1 if they exist // NeatCNS neat = g1.Cns; //Genome _genomeBuffer = neat.NewEmptyGenome(); ChaoticSeer _genomeBuffer = new ChaoticSeer(); int indexG1 = 0; int indexG2 = 0; //Handle not connectec genes while (indexG1 < g1.Connections.Count && indexG2 < g2.Connections.Count) { ConnectionGene gene1 = g1.Connections[indexG1]; ConnectionGene gene2 = g2.Connections[indexG2]; //Because I seperated the client, the innovation number for them is different. This is a problem int in1 = gene1.InnovationNumber; int in2 = gene2.InnovationNumber; if (in1 == in2) { // basically if they are thesame, just select either of them randomly if (Rng.GetRngF() > 0.5f) { _genomeBuffer.Connections.Add(Sg.Neat.Connections[gene1]); } else { _genomeBuffer.Connections.Add(Sg.Neat.Connections[gene2]); } indexG1++; indexG2++; } else if (in1 > in2) { //genome.Connections.Add(neat.Connections[gene2]); //disjoint/skip gene of b indexG2++; } else { //disjoint/skip gene of a _genomeBuffer.Connections.Add(Sg.Neat.Connections[gene1]); indexG1++; } } // Add the connections while (indexG1 < g1.Connections.Count) { ConnectionGene gene1 = g1.Connections[indexG1]; _genomeBuffer.Connections.Add(Sg.Neat.Connections[gene1]); indexG1++; } // Add the nodes foreach (ConnectionGene c in _genomeBuffer.Connections) { _genomeBuffer.Nodes.Add(c.From); _genomeBuffer.Nodes.Add(c.To); } return(_genomeBuffer); }