private void Mutate_Node(Random rand) { //UnityEngine.Debug.Log("starting mutate node"); if (ConnectionGeneSet.Count > 0) { ConnectionGene conn = ConnectionGeneSet.OrderBy(x => rand.Next()).FirstOrDefault(); //for(int i=0;i<ConnectionGeneSet.Count;i++) //{ //ConnectionGene conn = ConnectionGeneSet.ElementAt(i); NodeGene nodeFrom = NodeGeneSet.Where(x => x.Id.Equals(conn.NodeIn)).FirstOrDefault(), nodeTo = NodeGeneSet.Where(x => x.Id.Equals(conn.NodeOut)).FirstOrDefault(); NodeGene node = pool.NodeGene_Get(conn.ReplaceIndex); node.x = (nodeFrom.x + nodeTo.x) * .5f; node.y = (nodeFrom.y + nodeTo.y) * (.4f + rand.Next(1, 20) * .01f); node.y = (node.y >= 1f) ? 0.99f : (node.y <= 0f) ? 0.01f : node.y; ConnectionGene connA = pool.ConnectionGene_GetOrCreate(conn.NodeIn, node.Id), connB = pool.ConnectionGene_GetOrCreate(node.Id, conn.NodeOut); connA.RandomizeWeight(); connA.IsEnabled = true; connB.IsEnabled = conn.IsEnabled; connB.Weight = conn.Weight; connGeneSet.Add(connA); connGeneSet.Add(connB); conn.IsEnabled = false; nodeGeneSet.Add(node); //} // UnityEngine.Debug.Log("mutate node succesfull"); } }
/// <summary> /// Creates new ConnectionGene. /// </summary> /// <param name="nIn">Input node id</param> /// <param name="nOut">Output node id</param> /// <returns></returns> public ConnectionGene ConnectionGene_Add(int nIn, int nOut) { //int inv = ((connGeneList.Count > 0) ? connGeneList.Max(x => x.InnovationNumber) : 0) + 1; innovationNumberList.Add(innovationNumber++); int replaceIndex = NodeGene_Next().Id; ConnectionGene connGene = new ConnectionGene(nIn, nOut, GetRandomWeight(), true, innovationNumberList.Last(), replaceIndex); connGeneList.Add(connGene); return(connGene); }
//private float BLX(float x1,float x2,Random rand) //{ // float a = rand.Next(0, 100) * 0.01f, // d = Math.Abs(x2 - x1), // min = Math.Min(x1, x2), // max = Math.Max(x1, x2); // return Utils.Utilities.Lerp(min - a * d, max + a * d, (float)rand.NextDouble()); //} public float CalculateDistance(Genome genomeB, float coef1, float coef2, float coef3) { Genome genomeA; if (genomeB.ConnectionGeneSet.Max(x => x.InnovationNumber) > this.ConnectionGeneSet.Max(x => x.InnovationNumber)) { genomeA = genomeB; genomeB = this; } else { genomeA = this; } int nExcess = 0, nDisjoints = 0, nSimilar = 0, iGenomeA = 0, iGenomeB = 0; float weight_diff = 0f; int countA = genomeA.ConnectionGeneSet.Count(), countB = genomeB.ConnectionGeneSet.Count(); while (iGenomeA < countA && iGenomeB < countB) { ConnectionGene connA = genomeA.ConnectionGeneSet.ElementAt(iGenomeA), connB = genomeB.ConnectionGeneSet.ElementAt(iGenomeB); int innovA = connA.InnovationNumber, innovB = connB.InnovationNumber; if (innovA == innovB) { nSimilar++; weight_diff += Math.Abs(connA.Weight - connB.Weight); iGenomeA++; iGenomeB++; } else if (innovA > innovB) { // disjoint of geneA nDisjoints++; iGenomeB++; } else { //disjoint of geneB nDisjoints++; iGenomeA++; } } // string innovGenomeA = ""; // UnityEngine.Debug.Log("similarity = " + nSimilar); // UnityEngine.Debug.Log("pre weight_diff = " + weight_diff); weight_diff /= (nSimilar > 0) ? nSimilar : 1; // UnityEngine.Debug.Log("post weight_diff = " + weight_diff); nExcess = countA - iGenomeA; float max = Math.Max(countA, countB); float n = (max < 20) ? 1f : max; float dist = coef1 * nExcess / n + coef2 * nDisjoints / n + coef3 * weight_diff; return(dist); }
public Genome Crossover(Genome genomeB, Random rand) { Genome genomeA, offspring = new Genome(InputNodeNumber, OutputNodeNumber, pool); if (genomeB.Fitness > Fitness) { genomeA = genomeB; genomeB = this; } else { genomeA = this; } //if (genomeB.ConnectionGeneSet.Max(x => x.InnovationNumber) > this.ConnectionGeneSet.Max(x => x.InnovationNumber)) //{ // genomeA = genomeB; // genomeB = this; //} //else //{ // genomeA = this; //} int iGenomeA = 0, iGenomeB = 0, countA = genomeA.ConnectionGeneSet.Count, countB = genomeB.ConnectionGeneSet.Count; while (iGenomeA < countA && iGenomeB < countB) { ConnectionGene connA = genomeA.ConnectionGeneSet.ElementAt(iGenomeA), connB = genomeB.ConnectionGeneSet.ElementAt(iGenomeB); int innovA = connA.InnovationNumber, innovB = connB.InnovationNumber; if (innovA == innovB) { ConnectionGene newConn; if (rand.NextDouble() < .5) { newConn = connA.Clone() as ConnectionGene; } else { newConn = connB.Clone() as ConnectionGene; } //ConnectionGene conn = connA.Clone() as ConnectionGene; //conn.RandomizeWeight(); //offspring.ConnectionGeneSet.Add(conn); //float min = Math.Min(connA.Weight, connB.Weight), // max = Math.Max(connA.Weight, connB.Weight); //newConn.Weight = (float)((max - min) * rand.NextDouble()) + min; //newConn.Weight = BLX(connA.Weight, connB.Weight, rand); //if (rand.NextDouble() < .25) // newConn.IsEnabled = !newConn.IsEnabled; offspring.ConnectionGeneSet.Add(newConn); iGenomeA++; iGenomeB++; } else if (innovA > innovB) { // disjoint of geneB iGenomeB++; } else { //disjoint of geneA offspring.ConnectionGeneSet.Add(connA.Clone() as ConnectionGene); iGenomeA++; } } while (iGenomeA < countA) { ConnectionGene conn = genomeA.ConnectionGeneSet.ElementAt(iGenomeA).Clone() as ConnectionGene; offspring.ConnectionGeneSet.Add(conn); iGenomeA++; } foreach (ConnectionGene conn in genomeA.ConnectionGeneSet) { offspring.NodeGeneSet.Add(pool.NodeGene_Get(conn.NodeIn)); offspring.NodeGeneSet.Add(pool.NodeGene_Get(conn.NodeOut)); } offspring.parentColor = species?.color ?? new float[] { 1f, 0f, 0f, }; return(offspring); }