public double EvaluateNetwork(INetwork cppn) { lock (locker) { m_evalCount++; SharpNeatLib.NeatGenome.NeatGenome subsGenome = m_substrate.GenerateGenome(cppn); INetwork subsNet = subsGenome.Decode(HyperNEATParameters.substrateActivationFunction); m_neatQTable.NetworkToEvaluateBallOwner = subsNet; m_neatQTable.NetworkToEvaluateNotBallOwner = subsNet; m_neatQTable.m_eventNewNetReady.Set(); m_neatQTable.m_eventNetFitnessReady.WaitOne(); double reward = m_neatQTable.PerformanceNetworkToEvaluate.Reward; double maxTime = NeatExpParams.EpisodesPerGenome * 3 * (m_neatQTable.Rows + m_neatQTable.Cols); double globalFitness = (m_neatQTable.PerformanceNetworkToEvaluate.GoalsScoredByTeam * NeatExpParams.GoalScoreEffect); double localFitness = (m_neatQTable.PerformanceNetworkToEvaluate.GoalsScoredByMe * NeatExpParams.GoalScoreEffect); double fitness = globalFitness; switch (NeatExpParams.CreditAssignment) { case CreditAssignments.Global: fitness = globalFitness; break; case CreditAssignments.Local: fitness = localFitness; break; case CreditAssignments.Mid: fitness = (localFitness + globalFitness) * 0.5; break; default: break; } if (m_neatQTable.PerformanceNetworkToEvaluate.GoalsScoredByTeam > 0) { fitness += (maxTime - m_neatQTable.PerformanceNetworkToEvaluate.PerformanceTime); } //- m_neatQTable.PerformanceNetworkToEvaluate.GoalsReceived * NeatExpParams.GoalRecvEffect if (fitness < 0) { fitness = 0; } Console.WriteLine("G: {0,-3} - Rew: {1,-10:F3} - Fitness: {2,-15:F3}", m_neatQTable.GenerationNo, reward, fitness); return(fitness); } }
//private Position GetHomePos(int unum, int r) //{ // if (unum == 1) // return new Position(2, 2); // else if (unum == 2) // return new Position(r - 1, 2); // else if (unum == 3) // return new Position(r / 2 + 1, 4); // else // return new Position(0, 0); //} public double EvaluateNetwork(INetwork cppn) { // lazy loading //if (m_substratesBallOwner == null) //{ // m_substratesBallOwner = new ISubstrate[m_neatQTables.Length]; // m_substratesNotBallOwner = new ISubstrate[m_neatQTables.Length]; // //Debug.Assert(m_neatQTable != null); // // we put (cols + 2) columns in substrate to allaw players to go beyond the columns and score a goal // for (int i = 0; i < m_neatQTables.Length; i++) // { // //Position homPos = GetHomePos(i + 1, m_neatQTables[i].Rows); // float homex = ((float) m_neatQTables[i].NeatClient.MyHomePosCol / ((float)m_neatQTables[i].Cols * 0.5f)); // float homey = ((float)m_neatQTables[i].NeatClient.MyHomePosRow / (float)m_neatQTables[i].Rows); // m_substratesBallOwner[i] = new FourDFieldSubstrate(homex, homey, m_neatQTables[i].Rows, m_neatQTables[i].Cols + 2, // NeatExpParams.AddBiasToSubstrate, HyperNEATParameters.substrateActivationFunction, 0); // m_substratesNotBallOwner[i] = new FourDFieldSubstrate(homex, homey, m_neatQTables[i].Rows, m_neatQTables[i].Cols + 2, // NeatExpParams.AddBiasToSubstrate, HyperNEATParameters.substrateActivationFunction, // NeatExpParams.AddBiasToSubstrate ? 2 : 1); // } //} // end of lazy loading lock (locker) { m_evalCount++; for (int i = 0; i < m_neatQTables.Length; i++) { SharpNeatLib.NeatGenome.NeatGenome tempGenomeBallOwner = m_substratesBallOwner[i].GenerateGenome(cppn); INetwork tempNetBallOwner = tempGenomeBallOwner.Decode(HyperNEATParameters.substrateActivationFunction); SharpNeatLib.NeatGenome.NeatGenome tempGenomeNotBallOwner = m_substratesNotBallOwner[i].GenerateGenome(cppn); INetwork tempNetNotBallOwner = tempGenomeNotBallOwner.Decode(HyperNEATParameters.substrateActivationFunction); m_neatQTables[i].NetworkToEvaluateBallOwner = tempNetBallOwner; m_neatQTables[i].NetworkToEvaluateNotBallOwner = tempNetNotBallOwner; m_neatQTables[i].m_eventNewNetReady.Set(); } double[] fitnesses = new double[m_neatQTables.Length]; for (int i = 0; i < m_neatQTables.Length; i++) { m_neatQTables[i].m_eventNetFitnessReady.WaitOne(); double reward = m_neatQTables[i].PerformanceNetworkToEvaluate.Reward; double maxTime = NeatExpParams.EpisodesPerGenome * 3 * (m_neatQTables[i].Rows + m_neatQTables[i].Cols); double globalFitness = (m_neatQTables[i].PerformanceNetworkToEvaluate.GoalsScoredByTeam * NeatExpParams.GoalScoreEffect); double localFitness = (m_neatQTables[i].PerformanceNetworkToEvaluate.GoalsScoredByMe * NeatExpParams.GoalScoreEffect); double fitness = globalFitness; switch (NeatExpParams.CreditAssignment) { case CreditAssignments.Global: fitness = globalFitness; break; case CreditAssignments.Local: fitness = localFitness; break; case CreditAssignments.Mid: fitness = (localFitness + globalFitness) * 0.5; break; default: break; } if (m_neatQTables[i].PerformanceNetworkToEvaluate.GoalsScoredByTeam > 0) { fitness += (maxTime - m_neatQTables[i].PerformanceNetworkToEvaluate.PerformanceTime); } //- m_neatQTable.PerformanceNetworkToEvaluate.GoalsReceived * NeatExpParams.GoalRecvEffect if (fitness < 0) { fitness = 0; } fitnesses[i] = fitness; Console.WriteLine("[{0}] G: {1,-3} - Rew: {2,-10:F3} - Fitness: {3,-15:F3}", m_neatQTables[i].NeatClient.MyUnum, m_neatQTables[i].GenerationNo, reward, fitness); } Console.WriteLine("These are all fitnesses:"); foreach (var f in fitnesses) { Console.Write("{0} ", f); } Console.WriteLine("::::::::::::::::::::::::::::::::"); Console.WriteLine(); return(fitnesses[0]); } }
//saves a CPPN in dot file format. //Assumes that inputs are X1, Y1, X2, Y2, Z public static void saveCPPNasDOT(SharpNeatLib.NeatGenome.NeatGenome genome, string filename) { StreamWriter SW = File.CreateText(filename); SW.WriteLine("digraph g { "); String activationType = ""; foreach (NeuronGene neuron in genome.NeuronGeneList) { switch (neuron.NeuronType) { case NeuronType.Bias: SW.WriteLine("N0 [shape=box, label=Bias]"); break; case NeuronType.Input: string str = "?"; switch (neuron.InnovationId) { case 1: str = "X1"; break; case 2: str = "Y1"; break; case 3: str = "X2"; break; case 4: str = "Y2"; break; case 5: str = "Z"; break; } SW.WriteLine("N" + neuron.InnovationId + "[shape=box label=" + str + "]"); break; case NeuronType.Output: SW.WriteLine("N" + neuron.InnovationId + "[shape=triangle]"); break; case NeuronType.Hidden: if (neuron.ActivationFunction.FunctionDescription.Equals("bipolar steepend sigmoid")) { activationType = "S"; } if (neuron.ActivationFunction.FunctionDescription.Equals("bimodal gaussian")) { activationType = "G"; } if (neuron.ActivationFunction.FunctionDescription.Equals("Linear")) { activationType = "L"; } if (neuron.ActivationFunction.FunctionDescription.Equals("Sin function with doubled period")) { activationType = "Si"; } if (neuron.ActivationFunction.FunctionDescription.Equals("Returns the sign of the input")) { activationType = "Sign"; } SW.WriteLine("N" + neuron.InnovationId + "[shape=circle, label=N" + neuron.InnovationId + "_" + activationType + ", fillcolor=gray]"); break; } } foreach (ConnectionGene gene in genome.ConnectionGeneList) { SW.Write("N" + gene.SourceNeuronId + " -> N" + gene.TargetNeuronId + " "); if (gene.Weight > 0) { SW.WriteLine("[color=black] "); } else if (gene.Weight < -0) { SW.WriteLine("[color=red] [arrowType=inv]"); } } foreach (ModuleGene mg in genome.ModuleGeneList) { foreach (uint sourceID in mg.InputIds) { foreach (uint targetID in mg.OutputIds) { SW.Write("N" + sourceID + " -> N" + targetID + " "); SW.WriteLine("[color=gray]"); } } } SW.WriteLine(" { rank=same; "); foreach (NeuronGene neuron in genome.NeuronGeneList) { if (neuron.NeuronType == NeuronType.Output) { SW.WriteLine("N" + neuron.InnovationId); } } SW.WriteLine(" } "); SW.WriteLine(" { rank=same; "); foreach (NeuronGene neuron in genome.NeuronGeneList) { if (neuron.NeuronType == NeuronType.Input) { SW.Write("N" + neuron.InnovationId + " ->"); } } //Also the bias neuron on the same level SW.WriteLine("N0 [style=invis]"); SW.WriteLine(" } "); SW.WriteLine("}"); SW.Close(); }