public double threadSafeEvaluateNetwork(INetwork network, Semaphore sem) { double fitness = 0; INetwork tempNet = null; NeatGenome.NeatGenome tempGenome = null; int count = network.InputNeuronCount; if (!SkirmishExperiment.multiple) { tempGenome = substrate.GenerateGenome(network); } else { tempGenome = substrate.generateMultiGenomeModulus(network, numAgents); } //Currently decoding genomes is NOT thread safe, so we have to do that single file sem.WaitOne(); tempNet = tempGenome.Decode(null); sem.Release(); if (!SkirmishExperiment.multiple) { fitness += doEvaluation(tempNet); } else { fitness += doEvaluationMulti(tempNet); } return(fitness); }
private void loadNetworkToolStripMenuItem_Click(object sender, EventArgs e) { string filename; OpenFileDialog oDialog = new OpenFileDialog(); oDialog.AddExtension = true; oDialog.DefaultExt = "xml"; oDialog.Title = "Load Seed Genome"; oDialog.RestoreDirectory = true; // Show Open Dialog and Respond to OK if (oDialog.ShowDialog() == DialogResult.OK) { filename = oDialog.FileName; } else { return; } NeatGenome.NeatGenome seedGenome = null; try { XmlDocument doc = new XmlDocument(); doc.Load(filename); seedGenome = XmlNeatGenomeReaderStatic.Read(doc); } catch (Exception ex) { MessageBox.Show("Problem loading genome. \n" + ex.Message); return; } currentBest = GenomeDecoder.DecodeToFloatFastConcurrentNetwork(seedGenome, null); }
static public INetwork DecodeToConcurrentNetwork(NeatGenome.NeatGenome g, IActivationFunction activationFn) { //----- Loop the neuronGenes. Create Neuron for each one. // Store a table of neurons keyed by their id. Hashtable neuronTable = new Hashtable(g.NeuronGeneList.Count); NeuronList neuronList = new NeuronList(); foreach (NeuronGene neuronGene in g.NeuronGeneList) { Neuron newNeuron = new Neuron(activationFn, neuronGene.NeuronType, neuronGene.InnovationId); neuronTable.Add(newNeuron.Id, newNeuron); neuronList.Add(newNeuron); } //----- Loop the connection genes. Create a Connection for each one and bind them to the relevant Neurons. foreach (ConnectionGene connectionGene in g.ConnectionGeneList) { Connection newConnection = new Connection(connectionGene.SourceNeuronId, connectionGene.TargetNeuronId, connectionGene.Weight); // Bind the connection to it's source neuron. newConnection.SetSourceNeuron((Neuron)neuronTable[connectionGene.SourceNeuronId]); // Store the new connection against it's target neuron. ((Neuron)(neuronTable[connectionGene.TargetNeuronId])).ConnectionList.Add(newConnection); } return(new ConcurrentNetwork(neuronList)); }
//function to check whether genome x dominates genome y, usually defined as being no worse on all //objectives, and better at at least one public bool dominates(NeatGenome.NeatGenome x, NeatGenome.NeatGenome y) { bool better = false; double[] objx = x.objectives, objy = y.objectives; int sz = objx.Length; //if x is ever worse than y, it cannot dominate y //also check if x is better on at least one for (int i = 0; i < sz - 1; i++) { if (objx[i] < objy[i]) { return(false); } if (objx[i] > objy[i]) { better = true; } } //genomic novelty check, disabled for now double thresh = 0.1; if ((objx[sz - 1] + thresh) < (objy[sz - 1])) { return(false); } if ((objx[sz - 1] > (objy[sz - 1] + thresh))) { better = true; } return(better); }
public bool measureAgainstArchive(NeatGenome.NeatGenome neatgenome, bool addToPending) { foreach (IGenome genome in archive) { double dist = BehaviorDistance.Distance(neatgenome.Behavior, ((NeatGenome.NeatGenome)genome).Behavior); if (dist > maxDistSeen) { maxDistSeen = dist; Console.WriteLine("Most novel distance: " + maxDistSeen); } if (dist < archive_threshold) { return(false); } } if (addToPending) { pending_addition.Add(neatgenome); } return(true); }
//add an existing population from hypersharpNEAT to the multiobjective population maintained in //this class, step taken before evaluating multiobjective population through the rank function public void addPopulation(Population p) { for (int i = 0; i < p.GenomeList.Count; i++) { bool blacklist = false; for (int j = 0; j < population.Count; j++) { if (distance(p.GenomeList[i].objectives, population[j].objectives) < 0.0001) { //JUSTIN: Changed from 0.001 (doesn't seem to help) blacklist = true; //reject a genome if it is very similar to existing genomes in pop //Console.Write("Blacklisting: "); //foreach (double bla in p.GenomeList[i].objectives) Console.Write(bla + " "); //Console.Write("vs "); //foreach (double bla in population[j].objectives) Console.Write(bla + " "); //Console.WriteLine(); break; } } if (!blacklist) //add genome if it is unique //we might not need to make copies { NeatGenome.NeatGenome copy = new NeatGenome.NeatGenome((NeatGenome.NeatGenome)p.GenomeList[i], 0); //copy.objectives = (double[])p.GenomeList[i].objectives.Clone(); //JUSTIN: Moved this to the NeatGenome copy constructor... population.Add(copy); } } }
public void addGenome(NeatGenome.NeatGenome genome) { if (quickReferenceIntervals.ContainsKey(genome)) { return; } try { long date = DateTime.Now.Ticks; //we'll note when we added this genome object Interval <NeatGenome.NeatGenome, long> genomeInterval = new Interval <NeatGenome.NeatGenome, long>(date, date, genome); //genomes for this particular fitness List <NeatGenome.NeatGenome> genomesForFitness; if (!sortedGenomes.TryGetValue(genome.Fitness, out genomesForFitness)) { genomesForFitness = new List <NeatGenome.NeatGenome>(); sortedGenomes.Add(genome.Fitness, genomesForFitness); } if (!genomesForFitness.Contains(genome)) { genomesForFitness.Add(genome); } quickReferenceIntervals.Add(genome, genomeInterval); } catch (Exception e) { Console.WriteLine(e.StackTrace); } }
//public static void Write(XmlNode parentNode, ModularNetwork network, IActivationFunction activationFn) //{ // //----- Start writing. Create document root node. // XmlElement xmlNetwork = XmlUtilities.AddElement(parentNode, "network"); // if (activationFn != null) // { // XmlUtilities.AddAttribute(xmlNetwork, "activation-fn-id", activationFn.FunctionId); // } // //----- Write neurons. // XmlElement xmlNeurons = XmlUtilities.AddElement(xmlNetwork, "neurons"); // foreach (NeuronGene neuronGene in genome.NeuronGeneList) // WriteNeuron(xmlNeurons, neuronGene); // //----- Write Connections. // XmlElement xmlConnections = XmlUtilities.AddElement(xmlNetwork, "connections"); // foreach (FloatFastConnection connectionGene in network.connections) // WriteConnection(xmlConnections, connectionGene); //} public static void Write(XmlNode parentNode, NeatGenome.NeatGenome genome, IActivationFunction activationFn) { //----- Start writing. Create document root node. XmlElement xmlNetwork = XmlUtilities.AddElement(parentNode, "network"); if (activationFn != null) { XmlUtilities.AddAttribute(xmlNetwork, "activation-fn-id", activationFn.FunctionId); XmlUtilities.AddAttribute(xmlNetwork, "adaptable", "false"); } //----- Write neurons. XmlElement xmlNeurons = XmlUtilities.AddElement(xmlNetwork, "neurons"); foreach (NeuronGene neuronGene in genome.NeuronGeneList) { WriteNeuron(xmlNeurons, neuronGene); } //----- Write Connections. XmlElement xmlConnections = XmlUtilities.AddElement(xmlNetwork, "connections"); foreach (ConnectionGene connectionGene in genome.ConnectionGeneList) { WriteConnection(xmlConnections, connectionGene); } }
public int Compare(IGenome x, IGenome y) { NeatGenome.NeatGenome X = (NeatGenome.NeatGenome)x; NeatGenome.NeatGenome Y = (NeatGenome.NeatGenome)y; double fitnessDelta = Y.Fitness - X.Fitness; if (fitnessDelta < 0.0D) { return(-1); } else if (fitnessDelta > 0.0D) { return(1); } long sizeDelta = (X.NeuronGeneList.Count + X.ConnectionGeneList.Count) - (Y.NeuronGeneList.Count + Y.ConnectionGeneList.Count); // Convert result to an int. if (sizeDelta < 0) { return(-1); } else if (sizeDelta == 0) { return(0); } else { return(1); } }
static public NetworkModel DecodeToNetworkModel(NeatGenome.NeatGenome g) { ModelNeuronList masterNeuronList = new ModelNeuronList(); // loop all neurons and build a table keyed on id. HybridDictionary neuronTable = new HybridDictionary(g.NeuronGeneList.Count); foreach (NeuronGene neuronGene in g.NeuronGeneList) { ModelNeuron modelNeuron = new ModelNeuron(neuronGene.NeuronType, neuronGene.InnovationId, neuronGene.ActivationFunction); neuronTable.Add(modelNeuron.Id, modelNeuron); masterNeuronList.Add(modelNeuron); } // Loop through all of the connections. // Now we have a neuron table keyed on id we can attach the connections // to their source and target neurons. foreach (ConnectionGene connectionGene in g.ConnectionGeneList) { ModelConnection modelConnection = new ModelConnection(); modelConnection.Weight = connectionGene.Weight; modelConnection.SourceNeuron = (ModelNeuron)neuronTable[connectionGene.SourceNeuronId]; modelConnection.TargetNeuron = (ModelNeuron)neuronTable[connectionGene.TargetNeuronId]; modelConnection.SourceNeuron.OutConnectionList.Add(modelConnection); modelConnection.TargetNeuron.InConnectionList.Add(modelConnection); } return(new NetworkModel(masterNeuronList)); }
//if genome x dominates y, increment y's dominated count, add y to x's dominated list public void update_domination(NeatGenome.NeatGenome x, NeatGenome.NeatGenome y, RankInformation r1, RankInformation r2) { if (dominates(x, y)) { r1.dominates.Add(r2); r2.domination_count++; } }
public void loadSeed(string seedGenomeFile) { XmlDocument doc = new XmlDocument(); doc.Load(seedGenomeFile); officialSeedGenome = XmlNeatGenomeReaderStatic.Read(doc); //since idgen is still in control of genomeIDs, we have to increment it //for now... soon win will be in charge. You'll see, things will be different. idgen.mostRecentGenomeID(officialSeedGenome.GenomeId); }
public void removeGenome(NeatGenome.NeatGenome genome) { //got to go through our intervalgenomes and delete that genomes information var gInterval = quickReferenceIntervals[genome]; //will handle deleting the interval intervalGenomes.RemoveInterval(gInterval); //will remove from our quick refernce list quickReferenceIntervals.Remove(genome); }
/// <summary> /// Speciates the genomes in genomeList into the provided specieList. It is assumed that /// the genomeList represents all of the required genomes and that the species are currently empty. /// /// This method can be used for initialization or completely respeciating an existing genome population. /// </summary> public void SpeciateGenomes(List <IGenome> genomeList, List <Species> specieList) { Debug.Assert(genomeList.Count >= specieList.Count, string.Format("SpeciateGenomes(IList<TGenome>,IList<Species<TGenome>>). Species count [{0}] is greater than genome count [{1}].", specieList.Count, genomeList.Count)); // Randomly allocate the first k genomes to their own specie. Because there is only one genome in these // species each genome effectively represents a specie centroid. This is necessary to ensure we get k species. // If we randomly assign all genomes to species from the outset and then calculate centroids then typically some // of the species become empty. // This approach ensures that each species will have at least one genome - because that genome is the specie // centroid and therefore has distance of zero from the centroid (itself). int specieCount = specieList.Count; for (int i = 0; i < specieCount; i++) { Species specie = specieList[i]; genomeList[i].SpeciesId = specie.SpeciesId; specie.Members.Add(genomeList[i]); // Just set the specie centroid directly. // The centroid is a dictionary keyed on connection innovation IDs containing the weights as values NeatGenome.NeatGenome g = genomeList[i] as NeatGenome.NeatGenome; foreach (ConnectionGene cg in g.ConnectionGeneList) { if (specie.Centroid.ContainsKey(cg.InnovationId)) { Console.WriteLine("[!] Duplicate Innovation ID detected within same genome!"); // JUSTIN: DEBUG: This shouldn't happen, so remove it once we are sure that it doesn't. } specie.Centroid[cg.InnovationId] = cg.Weight; } } // Now allocate the remaining genomes based on their distance from the centroids. int genomeCount = genomeList.Count; for (int i = specieCount; i < genomeCount; i++) { IGenome genome = genomeList[i]; Species closestSpecie = FindClosestSpecie(genome, specieList); genome.SpeciesId = closestSpecie.SpeciesId; closestSpecie.Members.Add(genome); } // Recalculate each specie's centroid. foreach (Species specie in specieList) { specie.Centroid = CalculateSpecieCentroid(specie); } // Perform the main k-means loop until convergence. SpeciateUntilConvergence(genomeList, specieList); }
public double EvaluateNetwork(INetwork network) { INetwork tempNet = null; NeatGenome.NeatGenome tempGenome = null; tempGenome = substrate.generateGenome(network); tempNet = tempGenome.Decode(null); SharpNeatExperiments.Pacman.MyForm1.neatGenome = tempGenome; SharpNeatExperiments.Pacman.MyForm1.network = tempNet; double retries = 5; double totalFitness = 0; for (int i = 0; i < retries; i++) { var pacman = new PacmanAINeural.NeuralPacmanSUPG(); //pacman.SetBrain(network); pacman.SetBrain(tempNet, true, tempGenome, network, substrate.getSUPGMap()); var simplePacmanController = new PacmanAINeural.SimplePacmanController(); simplePacmanController.SetBrain(tempNet, true, tempGenome, network, substrate.getSUPGMap()); Visualizer visualizer = null; SharpNeatExperiments.Pacman.SimplePacman simplePacman = null; Thread visualizerThread; visualizerThread = new System.Threading.Thread(delegate() { bool fastNoDraw = false; simplePacman = new SharpNeatExperiments.Pacman.SimplePacman(simplePacmanController, fastNoDraw); if (!fastNoDraw) { System.Windows.Forms.Application.Run(simplePacman); } //visualizer = new Visualizer(pacman); //System.Windows.Forms.Application.Run(visualizer); }); visualizerThread.Start(); visualizerThread.Join(); totalFitness += simplePacman.returnGameScore;// visualizer.returnGameState; } double avgFitness = totalFitness / retries; return(avgFitness); /*int time = visualizer.returnGameState; * return (double)time;//fitness;*/ }
private void adHocAnalysisToolStripMenuItem_Click(object sender, EventArgs e) { string filename; StreamWriter sw; NeatGenome.NeatGenome seedGenome = null; Stats currentStats = new Stats(); for (FoodGatherParams.resolution = 8; FoodGatherParams.resolution <= 128; FoodGatherParams.resolution *= 2) { FoodGatherParams.fillFood(); FoodGatherParams.fillLookups(); sw = new StreamWriter("logfile" + FoodGatherParams.resolution.ToString() + ".txt"); for (int run = 1; run <= 20; run++) { for (int generation = 1; generation <= 500; generation++) { filename = "run" + run.ToString() + @"\genome_" + generation.ToString() + ".xml"; try { XmlDocument doc = new XmlDocument(); doc.Load("run" + run.ToString() + "\\genome_" + generation.ToString() + ".xml"); seedGenome = XmlNeatGenomeReaderStatic.Read(doc); } catch (Exception ex) { //MessageBox.Show(generation.ToString()); currentStats.generation = generation; currentStats.run = run; writeStats(sw, currentStats); continue; //do some output } currentStats = FoodGathererNetworkEvaluator.postHocAnalyzer(seedGenome); currentStats.CPPNconnections = seedGenome.ConnectionGeneList.Count; currentStats.CPPNneurons = seedGenome.NeuronGeneList.Count; currentStats.generation = generation; currentStats.run = run; writeStats(sw, currentStats); //break; } // sw.Flush(); } sw.Close(); } }
public double[] EvaluateNetworkMultipleObjective(INetwork network) { INetwork tempNet = null; NeatGenome.NeatGenome tempGenome = null; tempGenome = substrate.generateGenome(network); tempNet = tempGenome.Decode(null); SharpNeatExperiments.Pacman.MyForm1.neatGenome = tempGenome; SharpNeatExperiments.Pacman.MyForm1.network = tempNet; double retries = 1; double totalFitness = 0; double totalEatScore = 0; double totalLifeScore = 0; for (int i = 0; i < retries; i++) { var pacman = new PacmanAINeural.NeuralPacmanSUPG(); //pacman.SetBrain(network); pacman.SetBrain(tempNet, true, tempGenome, network, substrate.getSUPGMap()); var simplePacmanController = new PacmanAINeural.SimplePacmanController(); simplePacmanController.SetBrain(tempNet, true, tempGenome, network, substrate.getSUPGMap()); Visualizer visualizer = null; SharpNeatExperiments.Pacman.SimplePacman simplePacman = null; Thread visualizerThread; visualizerThread = new System.Threading.Thread(delegate() { simplePacman = new SharpNeatExperiments.Pacman.SimplePacman(simplePacmanController, false); System.Windows.Forms.Application.Run(simplePacman); //visualizer = new Visualizer(pacman); //System.Windows.Forms.Application.Run(visualizer); }); visualizerThread.Start(); visualizerThread.Join(); totalFitness += simplePacman.returnGameScore; totalEatScore += simplePacman.returnEatScore; totalLifeScore += simplePacman.returnLifeScore; } double avgFitness = totalFitness / retries; double avgEatScore = totalEatScore / retries; double avgLifeScore = totalLifeScore / retries; return(new double[] { avgFitness, avgEatScore, avgLifeScore }); }
public NeatGenome.NeatGenome generatePerceptronCircle(INetwork network, bool distance) { ConnectionGeneList connections = new ConnectionGeneList((int)(inputCount * outputCount)); double[] inputs; if (distance)//|| angle) { inputs = new double[5]; } else { inputs = new double[4]; } double output; uint counter = 0; double inputAngleDelta = (2 * Math.PI) / inputCount; double outputAngleDelta = (2 * Math.PI) / outputCount; double angleFrom = -3 * Math.PI / 4; for (uint neuronFrom = 0; neuronFrom < inputCount; neuronFrom++, angleFrom += inputAngleDelta) { inputs[0] = .5 * Math.Cos(angleFrom + (inputAngleDelta / 2.0)); inputs[1] = .5 * Math.Sin(angleFrom + (inputAngleDelta / 2.0)); double angleTo = -3 * Math.PI / 4; for (uint neuronTo = 0; neuronTo < outputCount; neuronTo++, angleTo += outputAngleDelta) { inputs[2] = Math.Cos(angleTo + (outputAngleDelta / 2.0)); inputs[3] = Math.Sin(angleTo + (outputAngleDelta / 2.0)); //if(angle) //inputs[4] = Math.Abs(angleFrom - angleTo); if (distance) { inputs[4] = ((Math.Sqrt(Math.Pow(inputs[0] - inputs[2], 2) + Math.Pow(inputs[1] - inputs[3], 2)) / (2 * sqrt2))); } network.ClearSignals(); network.SetInputSignals(inputs); network.MultipleSteps(5); output = network.GetOutputSignal(0); if (Math.Abs(output) > threshold) { float weight = (float)(((Math.Abs(output) - (threshold)) / (1 - threshold)) * weightRange * Math.Sign(output)); connections.Add(new ConnectionGene(counter++, neuronFrom, neuronTo + inputCount, weight)); } } } NeatGenome.NeatGenome g = new NeatGenome.NeatGenome(0, neurons, connections, (int)inputCount, (int)outputCount); return(g); }
public bool measureAgainstArchive(NeatGenome.NeatGenome neatgenome, bool addToPending) { foreach (IGenome genome in archive) { if (BehaviorDistance.Distance(neatgenome.Behavior, ((NeatGenome.NeatGenome)genome).Behavior) < archive_threshold) { return(false); } } if (addToPending) { pending_addition.Add(neatgenome); } return(true); }
public bool probabalisticMeasureAgainstArchive(NeatGenome.NeatGenome neatgenome) { double roll = archiveAddingRNG.NextDouble(); double prob = archiveAddingProbability; if (probTournament) { prob = prob * 2; // Double the chance of adding to pending_addition if there is a tournament (because half of them won't actually be added) } if (roll < prob) { pending_addition.Add(neatgenome); return(true); } return(false); }
//measure the novelty of an organism against the fixed population public double measureNovelty(NeatGenome.NeatGenome neatgenome) { double sum = 0.0; if (!initialized) { return(Double.MinValue); } List <Pair <double, NeatGenome.NeatGenome> > noveltyList = new List <Pair <double, NeatGenome.NeatGenome> >(); foreach (IGenome genome in measure_against) { noveltyList.Add(new Pair <double, NeatGenome.NeatGenome>(BehaviorDistance.Distance(((NeatGenome.NeatGenome)genome).Behavior, neatgenome.Behavior), ((NeatGenome.NeatGenome)genome))); } foreach (IGenome genome in archive) { noveltyList.Add(new Pair <double, NeatGenome.NeatGenome>(BehaviorDistance.Distance(((NeatGenome.NeatGenome)genome).Behavior, neatgenome.Behavior), ((NeatGenome.NeatGenome)genome))); // noveltyList.Add(BehaviorDistance.Distance(((NeatGenome.NeatGenome)genome).Behavior,neatgenome.Behavior)); } //see if we should add this genome to the archive measureAgainstArchive(neatgenome, true); noveltyList.Sort(); int nn = nearest_neighbors; if (noveltyList.Count < nearest_neighbors) { nn = noveltyList.Count; } for (int x = 0; x < nn; x++) { sum += noveltyList[x].First; if (neatgenome.RealFitness > noveltyList[x].Second.RealFitness) { neatgenome.competition += 1; } noveltyList[x].Second.locality += 1; // sum+=10000.0; //was 100 } return(Math.Max(sum, EvolutionAlgorithm.MIN_GENOME_FITNESS)); }
//currently not used, calculates genomic novelty objective for protecting innovation //uses a rough characterization of topology, i.e. number of connections in the genome public void calculateGenomicNovelty(GenomeList measureUs) { double sum = 0.0; int max_conn = 0; foreach (IGenome x in measureUs) { double minDist = 10000000.0; NeatGenome.NeatGenome xx = (NeatGenome.NeatGenome)x; double difference = 0.0; double delta = 0.0; List <double> distances = new List <double>(); if (xx.ConnectionGeneList.Count > max_conn) { max_conn = xx.ConnectionGeneList.Count; } //int ccount=xx.ConnectionGeneList.Count; foreach (IGenome y in measureUs) { if (x == y) { continue; } NeatGenome.NeatGenome yy = (NeatGenome.NeatGenome)y; double d = xx.compat(yy, np); //if(d<minDist) // minDist=d; distances.Add(d); } distances.Sort(); int sz = Math.Min(distances.Count, 10); double diversity = 0.0; for (int i = 0; i < sz; i++) { diversity += distances[i]; } //xx.objectives[xx.objectives.Length-1] = diversity; xx.geneticDiversity = diversity; sum += diversity; } //Console.WriteLine("Diversity: " + sum/population.Count + " " + max_conn); }
//add an existing population from hypersharpNEAT to the multiobjective population maintained in //this class, step taken before evaluating multiobjective population through the rank function public void addPopulation(Population p) { for (int i = 0; i < p.GenomeList.Count; i++) { bool blacklist = false; for (int j = 0; j < population.Count; j++) { if (distance(p.GenomeList[i].Behavior.objectives, population[j].objectives) < 0.01) { blacklist = true; //reject a genome if it is very similar to existing genomes in pop } } if (!blacklist) //add genome if it is unique //we might not need to make copies { NeatGenome.NeatGenome copy = new NeatGenome.NeatGenome((NeatGenome.NeatGenome)p.GenomeList[i], 0); copy.objectives = (double[])p.GenomeList[i].Behavior.objectives.Clone(); population.Add(copy); } } }
public static Stats postHocAnalyzer(NeatGenome.NeatGenome genome) { Stats stats = new Stats(); FloatFastConcurrentNetwork ffcn = GenomeDecoder.DecodeToFloatFastConcurrentNetwork(genome, null); INetwork network; network = substrate.generateNetwork(ffcn); stats.NNconnections = ((FloatFastConcurrentNetwork)network).connectionArray.Length; double avgSpeed = 0; double totalTime = 0; int numFood = 0; double timetaken = 0; for (int i = 0; i < FoodGatherParams.foodLocations.Length; i++) { Board testingArena = new Board(0, 500); Robot tester = new Robot(new PointF(testingArena.Size.Width / 2.0F, testingArena.Size.Height / 2.0F), (int)FoodGatherParams.resolution, network); testingArena.AddRobot(tester); testingArena.AddFood(FoodGatherParams.foodLocations[i]); timetaken = testingArena.game(); if (timetaken < 1000) { numFood++; } totalTime += timetaken; } avgSpeed = totalTime / FoodGatherParams.foodLocations.Length; stats.numFoods = numFood; stats.avgSpeed = avgSpeed; return(stats); }
//add an existing population from hypersharpNEAT to the multiobjective population maintained in //this class, step taken before evaluating multiobjective population through the rank function public void addPopulation(Population p) { for(int i=0;i<p.GenomeList.Count;i++) { bool blacklist=false; for(int j=0;j<population.Count;j++) { if(distance(p.GenomeList[i].Behavior.objectives,population[j].objectives) < 0.01) blacklist=true; //reject a genome if it is very similar to existing genomes in pop } if(!blacklist) { //add genome if it is unique //we might not need to make copies NeatGenome.NeatGenome copy=new NeatGenome.NeatGenome((NeatGenome.NeatGenome)p.GenomeList[i],0); copy.objectives = (double[])p.GenomeList[i].Behavior.objectives.Clone(); population.Add(copy); } } }
public NewConnectionGeneStruct(NeatGenome.NeatGenome owningGenome, ConnectionGene newConnectionGene) { this.OwningGenome = owningGenome; this.NewConnectionGene = newConnectionGene; }
//add an existing population from hypersharpNEAT to the multiobjective population maintained in //this class, step taken before evaluating multiobjective population through the rank function public void addPopulation(Population p) { for(int i=0;i<p.GenomeList.Count;i++) { bool blacklist=false; for(int j=0;j<population.Count;j++) { if (distance(p.GenomeList[i].objectives, population[j].objectives) < 0.0001) {//JUSTIN: Changed from 0.001 (doesn't seem to help) blacklist = true; //reject a genome if it is very similar to existing genomes in pop //Console.Write("Blacklisting: "); //foreach (double bla in p.GenomeList[i].objectives) Console.Write(bla + " "); //Console.Write("vs "); //foreach (double bla in population[j].objectives) Console.Write(bla + " "); //Console.WriteLine(); break; } } if(!blacklist) { //add genome if it is unique //we might not need to make copies NeatGenome.NeatGenome copy=new NeatGenome.NeatGenome((NeatGenome.NeatGenome)p.GenomeList[i],0); //copy.objectives = (double[])p.GenomeList[i].objectives.Clone(); //JUSTIN: Moved this to the NeatGenome copy constructor... population.Add(copy); } } }
static public FastConcurrentMultiplicativeNetwork DecodeToFastConcurrentMultiplicativeNetwork(NeatGenome.NeatGenome g, IActivationFunction activationFn) { int outputNeuronCount = g.OutputNeuronCount; int neuronGeneCount = g.NeuronGeneList.Count; // Slightly inefficient - determine the number of bias nodes. Fortunately there is not actually // any reason to ever have more than one bias node - although there may be 0. int neuronGeneIdx = 0; for (; neuronGeneIdx < neuronGeneCount; neuronGeneIdx++) { if (g.NeuronGeneList[neuronGeneIdx].NeuronType != NeuronType.Bias) { break; } } int biasNodeCount = neuronGeneIdx; int inputNeuronCount = g.InputNeuronCount; // ConnectionGenes point to a neuron ID. We need to map this ID to a 0 based index for // efficiency. To do this we build a table of indexes (ints) keyed on neuron ID. // TODO: An alternative here would be to forgo the building of a table and do a binary // search directly on the NeuronGeneList - probably a good idea to use a heuristic based upon // neuroncount*connectioncount that decides on which technique to use. Small networks will // likely be faster to decode using the binary search. // Actually we can partly achieve the above optimzation by using HybridDictionary instead of Hashtable. // Although creating a table is a bit expensive. HybridDictionary neuronIndexTable = new HybridDictionary(neuronGeneCount); for (int i = 0; i < neuronGeneCount; i++) { neuronIndexTable.Add(g.NeuronGeneList[i].InnovationId, i); } // Count how many of the connections are actually enabled. TODO: make faster - store disable count? int connectionGeneCount = g.ConnectionGeneList.Count; int connectionCount = connectionGeneCount; // for(int i=0; i<connectionGeneCount; i++) // { // if(g.ConnectionGeneList[i].Enabled) // connectionCount++; // } // Now we can build the connection array(s). FloatFastConnection[] connectionArray = new FloatFastConnection[connectionCount]; int connectionIdx = 0; for (int connectionGeneIdx = 0; connectionGeneIdx < connectionCount; connectionGeneIdx++) { ConnectionGene connectionGene = g.ConnectionGeneList[connectionIdx]; connectionArray[connectionIdx].sourceNeuronIdx = (int)neuronIndexTable[connectionGene.SourceNeuronId]; connectionArray[connectionIdx].targetNeuronIdx = (int)neuronIndexTable[connectionGene.TargetNeuronId]; connectionArray[connectionIdx].weight = (float)connectionGene.Weight; connectionIdx++; } // Now sort the connection array on sourceNeuronIdx, secondary sort on targetNeuronIdx. // TODO: custom sort routine to prevent boxing/unboxing required by Array.Sort(ValueType[]) //Array.Sort(connectionArray, fastConnectionComparer); QuickSortFastConnections(0, fastConnectionArray.Length - 1); return(new FastConcurrentMultiplicativeNetwork( biasNodeCount, inputNeuronCount, outputNeuronCount, neuronGeneCount, connectionArray, activationFn)); }
public double EvaluateNetwork(INetwork network) { INetwork tempNet = null; NeatGenome.NeatGenome tempGenome = null; tempGenome = substrate.generateGenome(network); tempNet = tempGenome.Decode(null); SharpNeatExperiments.Pacman.MyForm1.neatGenome = tempGenome; SharpNeatExperiments.Pacman.MyForm1.network = tempNet; double retries = 1; double totalFitness = 0; for (int i = 0; i < retries; i++) { var pacman = new PacmanAINeural.NeuralPacmanSUPG(); //pacman.SetBrain(network); pacman.SetBrain(tempNet, true, tempGenome, network, substrate.getSUPGMap()); var supgonlyController = new PacmanAINeural.SUPGONLYController(); supgonlyController.SetBrain(tempNet, true, tempGenome, network, substrate.getSUPGMap()); Thread visualizerThread; visualizerThread = new System.Threading.Thread(delegate() { int tmpCounter = 0; while (tmpCounter < 200) { //supgonlyController.dummyMasterFreqValue = (float)Math.Sin(tmpCounter*0.1f); if (tmpCounter % 50 == 0) { supgonlyController.makeAChangeInMasterFreq(); } if (tmpCounter == 80) { //supgonlyController.makeAChangeInMasterFreq(); } supgonlyController.Think(); /*simplePacman = new SharpNeatExperiments.Pacman.SimplePacman(simplePacmanController); * System.Windows.Forms.Application.Run(simplePacman);*/ //visualizer = new Visualizer(pacman); //System.Windows.Forms.Application.Run(visualizer); //Thread.Sleep(50); tmpCounter++; } }); visualizerThread.Start(); visualizerThread.Join(); totalFitness += supgonlyController.dummyFitness;//simplePacman.returnGameScore;// visualizer.returnGameState; } double avgFitness = totalFitness / retries; //Console.WriteLine("newEvaluation" + avgFitness); return(avgFitness); /*int time = visualizer.returnGameState; * return (double)time;//fitness;*/ }
static public FloatFastConcurrentNetwork DecodeToFloatFastConcurrentNetwork(NeatGenome.NeatGenome g, IActivationFunction activationFn) { int outputNeuronCount = g.OutputNeuronCount; int neuronGeneCount = g.NeuronGeneList.Count; // Slightly inefficient - determine the number of bias nodes. Fortunately there is not actually // any reason to ever have more than one bias node - although there may be 0. activationFunctionArray = new IActivationFunction[neuronGeneCount]; int neuronGeneIdx = 0; for (; neuronGeneIdx < neuronGeneCount; neuronGeneIdx++) { activationFunctionArray[neuronGeneIdx] = g.NeuronGeneList[neuronGeneIdx].ActivationFunction; if (g.NeuronGeneList[neuronGeneIdx].NeuronType != NeuronType.Bias) { break; } } int biasNodeCount = neuronGeneIdx; int inputNeuronCount = g.InputNeuronCount; for (; neuronGeneIdx < neuronGeneCount; neuronGeneIdx++) { activationFunctionArray[neuronGeneIdx] = g.NeuronGeneList[neuronGeneIdx].ActivationFunction; } // ConnectionGenes point to a neuron ID. We need to map this ID to a 0 based index for // efficiency. // Use a quick heuristic to determine which will be the fastest technique for mapping the connection end points // to neuron indexes. This is heuristic is not 100% perfect but has been found to be very good in in real word // tests. Feel free to perform your own calculation and create a more intelligent heuristic! int connectionCount = g.ConnectionGeneList.Count; if (neuronGeneCount * connectionCount < 45000) { fastConnectionArray = new FloatFastConnection[connectionCount]; int connectionIdx = 0; for (int connectionGeneIdx = 0; connectionGeneIdx < connectionCount; connectionGeneIdx++) { //fastConnectionArray[connectionIdx] = new FloatFastConnection(); //Note. Binary search algorithm assume that neurons are ordered by their innovation Id. ConnectionGene connectionGene = g.ConnectionGeneList[connectionIdx]; fastConnectionArray[connectionIdx].sourceNeuronIdx = (int)g.NeuronGeneList.BinarySearch(connectionGene.SourceNeuronId); fastConnectionArray[connectionIdx].targetNeuronIdx = (int)g.NeuronGeneList.BinarySearch(connectionGene.TargetNeuronId); System.Diagnostics.Debug.Assert(fastConnectionArray[connectionIdx].sourceNeuronIdx >= 0 && fastConnectionArray[connectionIdx].targetNeuronIdx >= 0, "invalid idx"); fastConnectionArray[connectionIdx].weight = (float)connectionGene.Weight; fastConnectionArray[connectionIdx].learningRate = connectionGene.learningRate; fastConnectionArray[connectionIdx].A = connectionGene.A; fastConnectionArray[connectionIdx].B = connectionGene.B; fastConnectionArray[connectionIdx].C = connectionGene.C; connectionIdx++; } } else { // Build a table of indexes (ints) keyed on neuron ID. This approach is faster when dealing with large numbers // of lookups. Hashtable neuronIndexTable = new Hashtable(neuronGeneCount); for (int i = 0; i < neuronGeneCount; i++) { neuronIndexTable.Add(g.NeuronGeneList[i].InnovationId, i); } // Now we can build the connection array(s). //int connectionCount=g.ConnectionGeneList.Count; //FastConnection[] connectionArray = new FastConnection[connectionCount]; fastConnectionArray = new FloatFastConnection[connectionCount]; int connectionIdx = 0; for (int connectionGeneIdx = 0; connectionGeneIdx < connectionCount; connectionGeneIdx++) { ConnectionGene connectionGene = g.ConnectionGeneList[connectionIdx]; fastConnectionArray[connectionIdx].sourceNeuronIdx = (int)neuronIndexTable[connectionGene.SourceNeuronId]; fastConnectionArray[connectionIdx].targetNeuronIdx = (int)neuronIndexTable[connectionGene.TargetNeuronId]; fastConnectionArray[connectionIdx].weight = (float)connectionGene.Weight; fastConnectionArray[connectionIdx].learningRate = connectionGene.learningRate; fastConnectionArray[connectionIdx].A = connectionGene.A; fastConnectionArray[connectionIdx].B = connectionGene.B; fastConnectionArray[connectionIdx].C = connectionGene.C; connectionIdx++; } } // Now sort the connection array on sourceNeuronIdx, secondary sort on targetNeuronIdx. // Using Array.Sort is 10 times slower than the hand-coded sorting routine. See notes on that routine for more // information. Also note that in tests that this sorting did no t actually improve the speed of the network! // However, it may have a benefit for CPUs with small caches or when networks are very large, and since the new // sort takes up hardly any time for even large networks, it seems reasonable to leave in the sort. //Array.Sort(fastConnectionArray, fastConnectionComparer); //if(fastConnectionArray.Length>1) // QuickSortFastConnections(0, fastConnectionArray.Length-1); return(new FloatFastConcurrentNetwork(biasNodeCount, inputNeuronCount, outputNeuronCount, neuronGeneCount, fastConnectionArray, activationFunctionArray)); }
static public ModularNetwork DecodeToModularNetwork(NeatGenome.NeatGenome g) { int inputCount = g.InputNeuronCount; int outputCount = g.OutputNeuronCount; int neuronCount = g.NeuronGeneList.Count; IActivationFunction[] activationFunctions = new IActivationFunction[neuronCount]; float[] biasList = new float[neuronCount]; Dictionary <long, int> neuronLookup = new Dictionary <long, int>(neuronCount); // Create an array of the activation functions for each non-module node node in the genome. // Start with a bias node if there is one in the genome. // The genome's neuron list is assumed to be ordered by type, with the bias node appearing first. int neuronGeneIndex = 0; for (; neuronGeneIndex < neuronCount; neuronGeneIndex++) { if (g.NeuronGeneList[neuronGeneIndex].NeuronType != NeuronType.Bias) { break; } activationFunctions[neuronGeneIndex] = g.NeuronGeneList[neuronGeneIndex].ActivationFunction; neuronLookup.Add(g.NeuronGeneList[neuronGeneIndex].InnovationId, neuronGeneIndex); } int biasCount = neuronGeneIndex; for (; neuronGeneIndex < neuronCount; neuronGeneIndex++) { activationFunctions[neuronGeneIndex] = g.NeuronGeneList[neuronGeneIndex].ActivationFunction; neuronLookup.Add(g.NeuronGeneList[neuronGeneIndex].InnovationId, neuronGeneIndex); biasList[neuronGeneIndex] = g.NeuronGeneList[neuronGeneIndex].Bias; } // Create an array of the activation functions, inputs, and outputs for each module in the genome. ModulePacket[] modules = new ModulePacket[g.ModuleGeneList.Count]; for (int i = g.ModuleGeneList.Count - 1; i >= 0; i--) { modules[i].function = g.ModuleGeneList[i].Function; // Must translate input and output IDs to array locations. modules[i].inputLocations = new int[g.ModuleGeneList[i].InputIds.Count]; for (int j = g.ModuleGeneList[i].InputIds.Count - 1; j >= 0; j--) { modules[i].inputLocations[j] = neuronLookup[g.ModuleGeneList[i].InputIds[j]]; } modules[i].outputLocations = new int[g.ModuleGeneList[i].OutputIds.Count]; for (int j = g.ModuleGeneList[i].OutputIds.Count - 1; j >= 0; j--) { modules[i].outputLocations[j] = neuronLookup[g.ModuleGeneList[i].OutputIds[j]]; } } // ConnectionGenes point to a neuron's innovation ID. Translate this ID to the neuron's index in the neuron array. FloatFastConnection[] connections = new FloatFastConnection[g.ConnectionGeneList.Count]; for (int connectionGeneIndex = g.ConnectionGeneList.Count - 1; connectionGeneIndex >= 0; connectionGeneIndex--) { ConnectionGene connectionGene = g.ConnectionGeneList[connectionGeneIndex]; connections[connectionGeneIndex].sourceNeuronIdx = neuronLookup[connectionGene.SourceNeuronId]; connections[connectionGeneIndex].targetNeuronIdx = neuronLookup[connectionGene.TargetNeuronId]; connections[connectionGeneIndex].weight = (float)connectionGene.Weight; connections[connectionGeneIndex].learningRate = connectionGene.learningRate; connections[connectionGeneIndex].A = connectionGene.A; connections[connectionGeneIndex].B = connectionGene.B; connections[connectionGeneIndex].C = connectionGene.C; connections[connectionGeneIndex].D = connectionGene.D; connections[connectionGeneIndex].modConnection = connectionGene.modConnection; } ModularNetwork mn = new ModularNetwork(biasCount, inputCount, outputCount, neuronCount, connections, biasList, activationFunctions, modules); if (g.networkAdaptable) { mn.adaptable = true; } if (g.networkModulatory) { mn.modulatory = true; } mn.genome = g; return(mn); }
//measure the novelty of an organism against the fixed population public double measureNovelty(NeatGenome.NeatGenome neatgenome) { double sum = 0.0; if (!initialized) { //Console.WriteLine("NOVELTY NOT INITIALIZED"); //JUSTIN: Debug, Remove this! return(Double.MinValue); } List <Pair <double, NeatGenome.NeatGenome> > noveltyList = new List <Pair <double, NeatGenome.NeatGenome> >(); foreach (IGenome genome in measure_against) { noveltyList.Add(new Pair <double, NeatGenome.NeatGenome>(BehaviorDistance.Distance(((NeatGenome.NeatGenome)genome).Behavior, neatgenome.Behavior), ((NeatGenome.NeatGenome)genome))); } /*foreach(IGenome genome in archive) //JUSTIN: Deciding not to use the archive in the neighborhood. Hope this helps? * { * noveltyList.Add(new Pair<double,NeatGenome.NeatGenome>(BehaviorDistance.Distance(((NeatGenome.NeatGenome)genome).Behavior,neatgenome.Behavior),((NeatGenome.NeatGenome)genome))); * // noveltyList.Add(BehaviorDistance.Distance(((NeatGenome.NeatGenome)genome).Behavior,neatgenome.Behavior)); * }//*/ //Console.WriteLine("NOVELTYLIST SIZE: " + noveltyList.Count + " m_a: " + measure_against.Count + " archive: " + archive.Count); //see if we should add this genome to the archive if (usingProbabilisticArchive) { probabalisticMeasureAgainstArchive(neatgenome); } else { measureAgainstArchive(neatgenome, true); } noveltyList.Sort(); int nn = nearest_neighbors; if (noveltyList.Count < nearest_neighbors) { nn = noveltyList.Count; } for (int x = 0; x < nn; x++) { sum += noveltyList[x].First; if (neatgenome.RealFitness == 0 || noveltyList[x].Second.RealFitness == 0) { Console.WriteLine("WARNING! SOMEBODY IS ZERO!"); } if (neatgenome.RealFitness > noveltyList[x].Second.RealFitness) { neatgenome.competition += 1; //Console.WriteLine(neatgenome.RealFitness + " > " + (noveltyList[x].Second).RealFitness + " so incrementing competition"); } //if (neatgenome.objectives[neatgenome.objectives.Length - 1] > noveltyList[x].Second.objectives[neatgenome.objectives.Length - 1]) //neatgenome.localGenomeNovelty += 1; if (neatgenome.geneticDiversity > noveltyList[x].Second.geneticDiversity) { neatgenome.localGenomeNovelty += 1; //Console.WriteLine("localGenomeNovelty: " + neatgenome.geneticDiversity + " > " + noveltyList[x].Second.geneticDiversity); } noveltyList[x].Second.locality += 1; neatgenome.nearestNeighbors++; // sum+=10000.0; //was 100 } return(Math.Max(sum, EvolutionAlgorithm.MIN_GENOME_FITNESS)); }