Esempio n. 1
0
        public NeatGenome(uint genomeId,
                NeuronGeneList neuronGeneList,
                List<ModuleGene> moduleGeneList,
                ConnectionGeneList connectionGeneList,
                int inputNeuronCount,
                int outputNeuronCount)
        {
			this.genomeId = genomeId;

			this.neuronGeneList = neuronGeneList;
            this.moduleGeneList = moduleGeneList;
			this.connectionGeneList = connectionGeneList;

			this.inputNeuronCount = inputNeuronCount;
			this.inputAndBiasNeuronCount = inputNeuronCount+1;
			this.outputNeuronCount = outputNeuronCount;
			this.inputBiasOutputNeuronCount = inputAndBiasNeuronCount + outputNeuronCount;
			this.inputBiasOutputNeuronCountMinus2 = inputBiasOutputNeuronCount-2;

            //justin
            objectives = new double[6];
            nearestNeighbors = 0;
            localGenomeNovelty = 0;
            competition = 0;
            geneticDiversity = 0;
            locality = 0;
            Fitness = 0;
            RealFitness = 0;

			Debug.Assert(connectionGeneList.IsSorted(), "ConnectionGeneList is not sorted by innovation ID");
		}
Esempio n. 2
0
        public NeatGenome(long genomeId,
                NeuronGeneList neuronGeneList,
                List<ModuleGene> moduleGeneList,
                ConnectionGeneList connectionGeneList,
                int inputNeuronCount,
                int outputNeuronCount)
        {
            this.genomeId = genomeId;

            this.neuronGeneList = neuronGeneList;
            this.moduleGeneList = moduleGeneList;
            this.connectionGeneList = connectionGeneList;

            this.inputNeuronCount = inputNeuronCount;
            this.inputAndBiasNeuronCount = inputNeuronCount+1;
            this.outputNeuronCount = outputNeuronCount;
            this.inputBiasOutputNeuronCount = inputAndBiasNeuronCount + outputNeuronCount;
            this.inputBiasOutputNeuronCountMinus2 = inputBiasOutputNeuronCount-2;

            //all genomes must be catalogued by the evolution manager
            EvolutionManager.SharedEvolutionManager.GenomeCreated(this);

            if (!connectionGeneList.IsSorted())
            {
                connectionGeneList.IsSorted();
            }

            Debug.Assert(connectionGeneList.IsSorted(), "ConnectionGeneList is not sorted by innovation ID");
        }
Esempio n. 3
0
 // Schrum: Added
 public NeatGenome(uint genomeId,
                 NeuronGeneList neuronGeneList,
                 ConnectionGeneList connectionGeneList,
                 int inputNeuronCount,
                 int outputNeuronCount,
                 int outputsPerPolicy) // Schrum: Added required parameter
     : this(genomeId, neuronGeneList, new List<ModuleGene>(), connectionGeneList, inputNeuronCount, outputNeuronCount, outputsPerPolicy) { }
Esempio n. 4
0
        public Substrate(uint input, uint output, uint hidden, IActivationFunction function)
        {
            weightRange = HyperNEATParameters.weightRange;
            threshold = HyperNEATParameters.threshold;

            inputCount = input;
            outputCount = output;
            hiddenCount = hidden;
            activationFunction = function;

            inputDelta = 2.0f / (inputCount);
            if (hiddenCount != 0)
                hiddenDelta = 2.0f / (hiddenCount);
            else
                hiddenDelta = 0;
            outputDelta = 2.0f / (outputCount);

            //SharpNEAT requires that the neuronlist be input|bias|output|hidden
            neurons=new NeuronGeneList((int)(inputCount + outputCount+ hiddenCount));
            //setup the inputs
            for (uint a = 0; a < inputCount; a++)
            {
                neurons.Add(new NeuronGene(a, NeuronType.Input, activationFunction));
            }

            //setup the outputs
            for (uint a = 0; a < outputCount; a++)
            {
                neurons.Add(new NeuronGene(a + inputCount, NeuronType.Output, activationFunction));
            }
            for (uint a = 0; a < hiddenCount; a++)
            {
                neurons.Add(new NeuronGene(a + inputCount+outputCount, NeuronType.Hidden, activationFunction));
            }
        }
Esempio n. 5
0
 public NeatGenome(uint genomeId,
                 NeuronGeneList neuronGeneList,
                 ConnectionGeneList connectionGeneList,
                 int inputNeuronCount,
                 int outputNeuronCount) 
     : this(genomeId, neuronGeneList, new List<ModuleGene>(), connectionGeneList, inputNeuronCount, 
     // Schrum: Added new constructor that assumes there is only one output module (default NEAT), so total outputs = outputs per policy
     outputNeuronCount, outputNeuronCount) { }
Esempio n. 6
0
 public NeatGenome(long genomeId,
                 NeuronGeneList neuronGeneList,
                 ConnectionGeneList connectionGeneList,
                 int inputNeuronCount,
                 int outputNeuronCount)
     : this(genomeId, neuronGeneList, new List<ModuleGene>(), connectionGeneList, inputNeuronCount, outputNeuronCount)
 {
 }
		public static NeatGenome Read(XmlElement xmlGenome)
		{
			int inputNeuronCount=0;
			int outputNeuronCount=0;

			uint id = uint.Parse(XmlUtilities.GetAttributeValue(xmlGenome, "id"));

			//--- Read neuron genes into a list.
			NeuronGeneList neuronGeneList = new NeuronGeneList();
			XmlNodeList listNeuronGenes = xmlGenome.SelectNodes("neurons/neuron");
			foreach(XmlElement xmlNeuronGene in listNeuronGenes)
			{
				NeuronGene neuronGene = ReadNeuronGene(xmlNeuronGene);

				// Count the input and output neurons as we go.
				switch(neuronGene.NeuronType)
				{
					case NeuronType.Input:
						inputNeuronCount++;
						break;
					case NeuronType.Output:
						outputNeuronCount++;
						break;
				}

				neuronGeneList.Add(neuronGene);
			}

            //--- Read module genes into a list.
            List<ModuleGene> moduleGeneList = new List<ModuleGene>();
            XmlNodeList listModuleGenes = xmlGenome.SelectNodes("modules/module");
            foreach (XmlElement xmlModuleGene in listModuleGenes) {
                moduleGeneList.Add(ReadModuleGene(xmlModuleGene));
            }

			//--- Read connection genes into a list.
			ConnectionGeneList connectionGeneList = new ConnectionGeneList();
			XmlNodeList listConnectionGenes = xmlGenome.SelectNodes("connections/connection");
			foreach(XmlElement xmlConnectionGene in listConnectionGenes)
				connectionGeneList.Add(ReadConnectionGene(xmlConnectionGene));
			
			//return new NeatGenome(id, neuronGeneList, connectionGeneList, inputNeuronCount, outputNeuronCount);
            NeatGenome g = new NeatGenome(id, neuronGeneList, moduleGeneList, connectionGeneList, inputNeuronCount, outputNeuronCount);
            g.Behavior = ReadBehavior(xmlGenome.SelectSingleNode("behavior"));
            g.Behavior.objectives = new double[6];
            g.objectives = new double[6];


            // JUSTIN: Read grid/trajectory info
            g.GridCoords = ReadGrid(xmlGenome.SelectSingleNode("grid"));
            g.Behavior.trajectory = ReadTrajectory(xmlGenome.SelectSingleNode("trajectory"));

            return g;
		}
 /// <summary>
 /// Create a genome with the provided internal state/definition data/objects.
 /// Overridable method to allow alternative NeatGenome sub-classes to be used.
 /// </summary>
 public override NeatGenome CreateGenome(uint id,
                                        uint birthGeneration,
                                        NeuronGeneList neuronGeneList,
                                        ConnectionGeneList connectionGeneList,
                                        int inputNeuronCount,
                                        int outputNeuronCount,
                                        bool rebuildNeuronGeneConnectionInfo)
 {
     return new NeatGenome(this, id, birthGeneration, neuronGeneList, connectionGeneList,
                           inputNeuronCount, outputNeuronCount, rebuildNeuronGeneConnectionInfo, false);
 }
		public static NeatGenome Read(XmlElement xmlGenome)
		{
			int inputNeuronCount=0;
			int outputNeuronCount=0;

			uint id = uint.Parse(XmlUtilities.GetAttributeValue(xmlGenome, "id"));
            // Schrum: Retrieve this new property, which is saved to xml files now
            int outputsPerPolicy = int.Parse(XmlUtilities.GetAttributeValue(xmlGenome, "outputsperpolicy"));

			//--- Read neuron genes into a list.
			NeuronGeneList neuronGeneList = new NeuronGeneList();
			XmlNodeList listNeuronGenes = xmlGenome.SelectNodes("neurons/neuron");
			foreach(XmlElement xmlNeuronGene in listNeuronGenes)
			{
				NeuronGene neuronGene = ReadNeuronGene(xmlNeuronGene);

				// Count the input and output neurons as we go.
				switch(neuronGene.NeuronType)
				{
					case NeuronType.Input:
						inputNeuronCount++;
						break;
					case NeuronType.Output:
						outputNeuronCount++;
						break;
				}

				neuronGeneList.Add(neuronGene);
			}

            //--- Read module genes into a list.
            List<ModuleGene> moduleGeneList = new List<ModuleGene>();
            XmlNodeList listModuleGenes = xmlGenome.SelectNodes("modules/module");
            foreach (XmlElement xmlModuleGene in listModuleGenes) {
                moduleGeneList.Add(ReadModuleGene(xmlModuleGene));
            }

			//--- Read connection genes into a list.
			ConnectionGeneList connectionGeneList = new ConnectionGeneList();
			XmlNodeList listConnectionGenes = xmlGenome.SelectNodes("connections/connection");
			foreach(XmlElement xmlConnectionGene in listConnectionGenes)
				connectionGeneList.Add(ReadConnectionGene(xmlConnectionGene));
			
			//return new NeatGenome(id, neuronGeneList, connectionGeneList, inputNeuronCount, outputNeuronCount);
            //return new NeatGenome(id, neuronGeneList, moduleGeneList, connectionGeneList, inputNeuronCount, outputNeuronCount);
            // Schrum: Changed to include the outputs per policy
            return new NeatGenome(id, neuronGeneList, moduleGeneList, connectionGeneList, inputNeuronCount, outputNeuronCount, outputsPerPolicy);
        }
Esempio n. 10
0
        /// <summary>
        /// Copy constructor.
        /// </summary>
        /// <param name="copyFrom"></param>
        public NeatGenome(NeatGenome copyFrom, uint genomeId)
        {
            this.genomeId = genomeId;

            // No need to loop the arrays to clone each element because NeuronGene and ConnectionGene are
            // value data types (structs).
            neuronGeneList = new NeuronGeneList(copyFrom.neuronGeneList);
            connectionGeneList = new ConnectionGeneList(copyFrom.connectionGeneList);

            inputNeuronCount = copyFrom.inputNeuronCount;
            inputAndBiasNeuronCount = copyFrom.inputNeuronCount+1;
            outputNeuronCount = copyFrom.outputNeuronCount;
            inputBiasOutputNeuronCount = copyFrom.inputBiasOutputNeuronCount;
            inputBiasOutputNeuronCountMinus2 = copyFrom.inputBiasOutputNeuronCountMinus2;

            Debug.Assert(connectionGeneList.IsSorted(), "ConnectionGeneList is not sorted by innovation ID");
        }
Esempio n. 11
0
        /// <summary>
        /// Default constructor.
        /// </summary>
        public NeatGenome(	uint genomeId, 
            NeuronGeneList neuronGeneList,
            ConnectionGeneList connectionGeneList,
            int inputNeuronCount,
            int outputNeuronCount)
        {
            this.genomeId = genomeId;

            this.neuronGeneList = neuronGeneList;
            this.connectionGeneList = connectionGeneList;

            this.inputNeuronCount = inputNeuronCount;
            this.inputAndBiasNeuronCount = inputNeuronCount+1;
            this.outputNeuronCount = outputNeuronCount;
            this.inputBiasOutputNeuronCount = inputAndBiasNeuronCount + outputNeuronCount;
            this.inputBiasOutputNeuronCountMinus2 = inputBiasOutputNeuronCount-2;

            Debug.Assert(connectionGeneList.IsSorted(), "ConnectionGeneList is not sorted by innovation ID");
        }
Esempio n. 12
0
        public Substrate(uint biasCount, uint inputCount, uint outputCount, uint hiddenCount, IActivationFunction function)
        {
            this.biasCount = biasCount;
            this.inputCount = inputCount;
            this.outputCount = outputCount;
            this.hiddenCount = hiddenCount;
            this.activationFunction = function;

            weightRange = HyperNEATParameters.weightRange;
            threshold = HyperNEATParameters.threshold;

            if (inputCount != 0)
                inputDelta = 2.0f / (inputCount);
            if (hiddenCount != 0)
                hiddenDelta = 2.0f / (hiddenCount);
            if (outputCount != 0)
                outputDelta = 2.0f / (outputCount);

            // SharpNEAT requires that the neuron list be in this order: bias|input|output|hidden
            neurons = new NeuronGeneList((int)(inputCount + outputCount + hiddenCount));

            // set up the bias nodes
            for (uint a = 0; a < biasCount; a++) {
                neurons.Add(new NeuronGene(a, NeuronType.Bias, ActivationFunctionFactory.GetActivationFunction("NullFn")));
            }

            // set up the input nodes
            for (uint a = 0; a < inputCount; a++) {
                neurons.Add(new NeuronGene(a + biasCount, NeuronType.Input, ActivationFunctionFactory.GetActivationFunction("NullFn")));
            }

            // set up the output nodes
            for (uint a = 0; a < outputCount; a++) {
                neurons.Add(new NeuronGene(a + biasCount + inputCount, NeuronType.Output, activationFunction));
            }

            // set up the hidden nodes
            for (uint a = 0; a < hiddenCount; a++) {
                neurons.Add(new NeuronGene(a + biasCount + inputCount + outputCount, NeuronType.Hidden, activationFunction));
            }
        }
        public static NeatGenome Read(XmlElement xmlGenome)
        {
            int inputNeuronCount=0;
            int outputNeuronCount=0;

            uint id = uint.Parse(XmlUtilities.GetAttributeValue(xmlGenome, "id"));

            //--- Read neuron genes into a list.
            NeuronGeneList neuronGeneList = new NeuronGeneList();
            XmlNodeList listNeuronGenes = xmlGenome.SelectNodes("neurons/neuron");
            foreach(XmlElement xmlNeuronGene in listNeuronGenes)
            {
                NeuronGene neuronGene = ReadNeuronGene(xmlNeuronGene);

                // Count the input and output neurons as we go.
                switch(neuronGene.NeuronType)
                {
                    case NeuronType.Input:
                        inputNeuronCount++;
                        break;
                    case NeuronType.Output:
                        outputNeuronCount++;
                        break;
                }

                neuronGeneList.Add(neuronGene);
            }

            //--- Read connection genes into a list.
            ConnectionGeneList connectionGeneList = new ConnectionGeneList();
            XmlNodeList listConnectionGenes = xmlGenome.SelectNodes("connections/connection");
            foreach(XmlElement xmlConnectionGene in listConnectionGenes)
                connectionGeneList.Add(ReadConnectionGene(xmlConnectionGene));

            return new NeatGenome(id, neuronGeneList, connectionGeneList, inputNeuronCount, outputNeuronCount);
        }
Esempio n. 14
0
		public override IGenome CreateOffspring_Sexual(EvolutionAlgorithm ea, IGenome parent)
		{
            NeatGenome otherParent = parent as NeatGenome;
            if (otherParent == null)
                return null;
            
            // Build a list of connections in either this genome or the other parent.
			CorrelationResults correlationResults = CorrelateConnectionGeneLists(connectionGeneList, otherParent.connectionGeneList);			
			Debug.Assert(correlationResults.PerformIntegrityCheck(), "CorrelationResults failed integrity check.");

			//----- Connection Genes.
			// We will temporarily store the offspring's genes in newConnectionGeneList and keeping track of which genes
			// exist with newConnectionGeneTable. Here we ensure these objects are created, and if they already existed
			// then ensure they are cleared. Clearing existing objects is more efficient that creating new ones because
			// allocated memory can be re-used.

            // Key = connection key, value = index in newConnectionGeneList.
			if(newConnectionGeneTable==null)
			{	// Provide a capacity figure to the new Hashtable. The offspring will be the same length (or thereabouts).
				newConnectionGeneTable = new Hashtable(connectionGeneList.Count);
			}
			else
			{
				newConnectionGeneTable.Clear();
			}
			//TODO: No 'capacity' constructor on CollectionBase. Create modified/custom CollectionBase.
			// newConnectionGeneList must be constructed on each call because it is passed to a new NeatGenome 
			// at construction time and a permanent reference to the list is kept.
            newConnectionGeneList = new ConnectionGeneList(ConnectionGeneList.Count);

			// A switch that stores which parent is fittest 1 or 2. Chooses randomly if both are equal. More efficient to calculate this just once.
			byte fitSwitch;
			if(Fitness > otherParent.Fitness)
				fitSwitch = 1;
			else if(Fitness < otherParent.Fitness)
				fitSwitch = 2;
			else
			{	// Select one of the parents at random to be the 'master' genome during crossover.
				if(Utilities.NextDouble() < 0.5)
					fitSwitch = 1;
				else
					fitSwitch = 2;
			}

			bool combineDisjointExcessFlag = Utilities.NextDouble() < ea.NeatParameters.pDisjointExcessGenesRecombined;

			// Loop through the correlationResults, building a table of ConnectionGenes from the parents that will make it into our 
			// new [single] offspring. We use a table keyed on connection end points to prevent passing connections to the offspring 
			// that may have the same end points but a different innovation number - effectively we filter out duplicate connections.
			int idxBound = correlationResults.CorrelationItemList.Count;
			for(int i=0; i<idxBound; i++)
			{
				CreateOffspring_Sexual_ProcessCorrelationItem((CorrelationItem)correlationResults.CorrelationItemList[i], fitSwitch, combineDisjointExcessFlag, ea.NeatParameters);
			}

			//----- Neuron Genes.
			// Build a neuronGeneList by analysing each connection's neuron end-point IDs.
			// This strategy has the benefit of eliminating neurons that are no longer connected too.
			// Remember to always keep all input, output and bias neurons though!
            NeuronGeneList newNeuronGeneList = new NeuronGeneList(neuronGeneList.Count);

			// Keep a table of the NeuronGene ID's keyed by ID so that we can keep track of which ones have been added.
            // Key = innovation ID, value = null for some reason.
			if(newNeuronGeneTable==null)
				newNeuronGeneTable = new Hashtable(neuronGeneList.Count);
			else
				newNeuronGeneTable.Clear();

			// Get the input/output neurons from this parent. All Genomes share these neurons, they do not change during a run.
			idxBound = neuronGeneList.Count;
			for(int i=0; i<idxBound; i++)
			{
				if(neuronGeneList[i].NeuronType != NeuronType.Hidden)
				{
					newNeuronGeneList.Add(new NeuronGene(neuronGeneList[i]));
					newNeuronGeneTable.Add(neuronGeneList[i].InnovationId, null);
				}
				else
				{	// No more bias, input or output nodes. break the loop.
					break;
				}
			}

			// Now analyse the connections to determine which NeuronGenes are required in the offspring.
            // Loop through every connection in the child, and add to the child those hidden neurons that are sources or targets of the connection.
			idxBound = newConnectionGeneList.Count;
			for(int i=0; i<idxBound; i++)
			{
                NeuronGene neuronGene;
				ConnectionGene connectionGene = newConnectionGeneList[i];
				if(!newNeuronGeneTable.ContainsKey(connectionGene.SourceNeuronId))
				{	
                    //TODO: DAVID proper activation function
					// We can safely assume that any missing NeuronGenes at this point are hidden heurons.
                   neuronGene = this.neuronGeneList.GetNeuronById(connectionGene.SourceNeuronId);
                    if (neuronGene != null)
                        newNeuronGeneList.Add(new NeuronGene(neuronGene));
                    else
                        newNeuronGeneList.Add(new NeuronGene(otherParent.NeuronGeneList.GetNeuronById(connectionGene.SourceNeuronId)));
                    //newNeuronGeneList.Add(new NeuronGene(connectionGene.SourceNeuronId, NeuronType.Hidden, ActivationFunctionFactory.GetActivationFunction("SteepenedSigmoid")));
					newNeuronGeneTable.Add(connectionGene.SourceNeuronId, null);
				}

				if(!newNeuronGeneTable.ContainsKey(connectionGene.TargetNeuronId))
				{	
                    //TODO: DAVID proper activation function
					// We can safely assume that any missing NeuronGenes at this point are hidden heurons.
                    neuronGene = this.neuronGeneList.GetNeuronById(connectionGene.TargetNeuronId);
                    if (neuronGene != null)
                        newNeuronGeneList.Add(new NeuronGene(neuronGene));
                    else
                        newNeuronGeneList.Add(new NeuronGene(otherParent.NeuronGeneList.GetNeuronById(connectionGene.TargetNeuronId)));
                    //newNeuronGeneList.Add(new NeuronGene(connectionGene.TargetNeuronId, NeuronType.Hidden, ActivationFunctionFactory.GetActivationFunction("SteepenedSigmoid")));
					newNeuronGeneTable.Add(connectionGene.TargetNeuronId, null);
				}
			}

            // Determine which modules to pass on to the child in the same way.
            // For each module in this genome or in the other parent, if it was referenced by even one connection add it and all its dummy neurons to the child.
            List<ModuleGene> newModuleGeneList = new List<ModuleGene>();

            // Build a list of modules the child might have, which is a union of the parents' module lists, but they are all copies so we can't just do a union.
            List<ModuleGene> unionParentModules = new List<ModuleGene>(moduleGeneList);
            foreach (ModuleGene moduleGene in otherParent.moduleGeneList) {
                bool alreadySeen = false;
                foreach (ModuleGene match in unionParentModules) {
                    if (moduleGene.InnovationId == match.InnovationId) {
                        alreadySeen = true;
                        break;
                    }
                }
                if (!alreadySeen) {
                    unionParentModules.Add(moduleGene);
                }
            }

            foreach (ModuleGene moduleGene in unionParentModules) {
                // Examine each neuron in the child to determine whether it is part of a module.
                foreach (List<uint> dummyNeuronList in new List<uint>[] { moduleGene.InputIds, moduleGene.OutputIds }) {
                    foreach (uint dummyNeuronId in dummyNeuronList) {
                        if (newNeuronGeneTable.ContainsKey(dummyNeuronId)) {
                            goto childHasModule;
                        }
                    }
                }

                continue; // the child does not contain this module, so continue the loop and check for the next module.
            childHasModule: // the child does contain this module, so make sure the child gets all the nodes the module requires to work.

                // Make sure the child has all the neurons in the given module.
                newModuleGeneList.Add(new ModuleGene(moduleGene));
                foreach (List<uint> dummyNeuronList in new List<uint>[] { moduleGene.InputIds, moduleGene.OutputIds }) {
                    foreach (uint dummyNeuronId in dummyNeuronList) {
                        if (!newNeuronGeneTable.ContainsKey(dummyNeuronId)) {
                            newNeuronGeneTable.Add(dummyNeuronId, null);
                            NeuronGene neuronGene = this.neuronGeneList.GetNeuronById(dummyNeuronId);
                            if (neuronGene != null) {
                                newNeuronGeneList.Add(new NeuronGene(neuronGene));
                            } else {
                                newNeuronGeneList.Add(new NeuronGene(otherParent.NeuronGeneList.GetNeuronById(dummyNeuronId)));
                            }
                        }
                    }
                }
            }

			// TODO: Inefficient code?
			newNeuronGeneList.SortByInnovationId();
            // Schrum: Need to calculate this because of Module Mutation adding extra outputs
            int revisedOutputCount = 0;
            foreach(NeuronGene n in newNeuronGeneList) {
                if (n.NeuronType == NeuronType.Output) 
                    revisedOutputCount++;
            }

			// newConnectionGeneList is already sorted because it was generated by passing over the list returned by
			// CorrelateConnectionGeneLists() - which is always in order.

            // Schrum: Modified to add outputsPerPolicy as a parameter, and use revisedOutputCount
			return new NeatGenome(ea.NextGenomeId, newNeuronGeneList, newModuleGeneList, newConnectionGeneList, inputNeuronCount, revisedOutputCount, outputsPerPolicy);
		}
        // MPS NOT supported by this method
        private NeatGenome.NeatGenome generateHomogeneousGenomeES(INetwork network, bool normalizeWeights, bool adaptiveNetwork, bool modulatoryNet)
        {
            if (useMultiPlaneSubstrate) throw new Exception("MPS not implemented for these parameters");
            //CHECK TO SEE IF HIDDEN NEURONS ARE OUTPUT NEURONS
            List<PointF> hiddenNeuronPositions = new List<PointF>();

            IActivationFunction activationFunction = HyperNEATParameters.substrateActivationFunction;
            ConnectionGeneList connections = new ConnectionGeneList();//(int)((InputCount * HiddenCount) + (HiddenCount * OutputCount)));

            List<PointF> outputNeuronPositions = getNeuronGroupByType(1);
            List<PointF> inputNeuronPositions = getNeuronGroupByType(0);


            SubstrateEvolution se = new SubstrateEvolution();

            se.generateConnections(inputNeuronPositions, outputNeuronPositions, network,
                SubstrateEvolution.SAMPLE_WIDTH,
                SubstrateEvolution.SAMPLE_TRESHOLD,
                SubstrateEvolution.NEIGHBOR_LEVEL,
                SubstrateEvolution.INCREASE_RESSOLUTION_THRESHOLD,
                SubstrateEvolution.MIN_DISTANCE,
                SubstrateEvolution.CONNECTION_TRESHOLD, //0.4. ConnectionThreshold
                InputCount, OutputCount, -1.0f, -1.0f, 1.0f, 1.0f, ref connections, ref hiddenNeuronPositions);

            HiddenCount = (uint)hiddenNeuronPositions.Count;

            float[] coordinates = new float[5];
            uint connectionCounter = (uint)connections.Count;

            NeuronGeneList neurons;
            // SharpNEAT requires that the neuron list be in this order: bias|input|output|hidden
            neurons = new NeuronGeneList((int)(InputCount + OutputCount + HiddenCount));

            // set up the input nodes
            for (uint a = 0; a < InputCount; a++)
            {
                neurons.Add(new NeuronGene(a, NeuronType.Input, ActivationFunctionFactory.GetActivationFunction("NullFn")));
            }

            // set up the output nodes
            for (uint a = 0; a < OutputCount; a++)
            {

                neurons.Add(new NeuronGene(a + InputCount, NeuronType.Output, activationFunction));
                
            }
            // set up the hidden nodes
            for (uint a = 0; a < HiddenCount; a++)
            {
                neurons.Add(new NeuronGene(a + InputCount + OutputCount, NeuronType.Hidden, activationFunction));
            }


            uint sourceID = uint.MaxValue, targetID = uint.MaxValue;
            NeuronGroup connectedNG;
            uint c1, c2;

            float delta = 0.15f;//2.0f / InputCount;
            float minDistance, dist, sourceX = -1, sourceY = -1, targetX = -1, targetY = -1;
            uint closestNodeIndex;
            //   int index, hiddenCount;

            //Connections to input nodes    
            // hiddenCount = 0;

            //TEST??????????????????????????????

            double tolerance = 0.1;
            //bool[] taken = new bool[hiddenNeuronGroup.NeuronPositions.Count];
            closestNodeIndex = 0;
            int ccc;

            //CONNECT FROM INPUT NODES
            // ConnectionGeneList addConnections = new ConnectionGeneList();
            targetID = 0;
            bool[] visited = new bool[neurons.Count];
            List<uint> nodeList = new List<uint>();
            bool[] connectedToInput = new bool[neurons.Count];

            //From hidden to output
            //taken = new bool[hiddenNeuronGroup.NeuronPositions.Count];
            // float targetX=-1.0f, targetY=-1.0f;
            targetID = 0;
            //  bool outputConnectedToInput;

            bool[] isOutput = new bool[neurons.Count];
            //float output, weight;
            //bool[] connectedToInput = new bool[neurons.Count];

            //bool connectToHidden;

            float totalConnectionDist = 0.0f;
            //Add connections between Hidden Neurons
            // addConnections.AddRange(connections);

            bool danglingConnection = true;

            while (danglingConnection)
            {
                bool[] hasIncomming = new bool[neurons.Count];

                foreach (ConnectionGene co in connections)
                {
                    //  if (co.SourceNeuronId != co.TargetNeuronId)
                    // {
                    hasIncomming[co.TargetNeuronId] = true;
                    // }
                }
                for (int i = 0; i < InputCount; i++)
                    hasIncomming[i] = true;

                bool[] hasOutgoing = new bool[neurons.Count];
                foreach (ConnectionGene co in connections)
                {
                    //  if (co.TargetNeuronId != co.SourceNeuronId)
                    //  {
                    if (co.TargetNeuronId != co.SourceNeuronId)  //neurons that only connect to themselfs don't count
                    {
                        hasOutgoing[co.SourceNeuronId] = true;
                    }
                    //  }
                }

                //Keep  output neurons
                for (int i = 0; i < OutputCount; i++)
                    hasOutgoing[i + InputCount] = true;


                danglingConnection = false;
                //Check if there are still dangling connections
                foreach (ConnectionGene co in connections)
                {
                    if (!hasOutgoing[co.TargetNeuronId] || !hasIncomming[co.SourceNeuronId])
                    {
                        danglingConnection = true;
                        break;
                    }
                }

                connections.RemoveAll(delegate(ConnectionGene m) { return (!hasIncomming[m.SourceNeuronId]); });
                connections.RemoveAll(delegate(ConnectionGene m) { return (!hasOutgoing[m.TargetNeuronId]); });
            }

            if (normalizeWeights)
            {
                normalizeWeightConnections(ref connections, neurons.Count);
            }

            SharpNeatLib.NeatGenome.NeatGenome gn = new SharpNeatLib.NeatGenome.NeatGenome(0, neurons, connections, (int)(InputCount), (int)(OutputCount));
        //     SharpNeatLib.NeatGenome.NeatGenome sng = new SharpNeatLib.NeatGenome.NeatGenome(0, neurons, connections, (int)(totalInputCount), (int)(totalOutputCount));

            gn.networkAdaptable = adaptiveNetwork;
            gn.networkModulatory = modulatoryNet;
       
            return gn;
        }
Esempio n. 16
0
		/// <summary>
		/// Copy constructor.
		/// </summary>
		/// <param name="copyFrom"></param>
		public NeatGenome(NeatGenome copyFrom, uint genomeId)
		{
			this.genomeId = genomeId;
            this.parent = copyFrom;

			// No need to loop the arrays to clone each element because NeuronGene and ConnectionGene are 
			// value data types (structs).
			neuronGeneList = new NeuronGeneList(copyFrom.neuronGeneList);
            moduleGeneList = new List<ModuleGene>(copyFrom.moduleGeneList);
			connectionGeneList = new ConnectionGeneList(copyFrom.connectionGeneList);

            //joel
            if(copyFrom.Behavior!=null)
            Behavior = new SharpNeatLib.BehaviorType(copyFrom.Behavior);
            
			inputNeuronCount = copyFrom.inputNeuronCount;
            // Schrum: Removed (not used)
			//inputAndBiasNeuronCount = copyFrom.inputNeuronCount+1;
			outputNeuronCount = copyFrom.outputNeuronCount;
            // Schrum: removed (not used)
			//inputBiasOutputNeuronCount = copyFrom.inputBiasOutputNeuronCount;
			//inputBiasOutputNeuronCountMinus2 = copyFrom.inputBiasOutputNeuronCountMinus2;
            // Schrum: Added
            outputsPerPolicy = copyFrom.outputsPerPolicy;

			Debug.Assert(connectionGeneList.IsSorted(), "ConnectionGeneList is not sorted by innovation ID");
		}
Esempio n. 17
0
		private void Mutate_AddConnection(EvolutionAlgorithm ea)
		{
			// We are always guaranteed to have enough neurons to form connections - because the input/output neurons are
			// fixed. Any domain that doesn't require input/outputs is a bit nonsensical!

			// Make a fixed number of attempts at finding a suitable connection to add. 
			
			if(neuronGeneList.Count>1)
			{	// At least 2 neurons, so we have a chance at creating a connection.

				for(int attempts=0; attempts<5; attempts++)
				{
					// Select candidate source and target neurons. Any neuron can be used as the source. Input neurons 
					// should not be used as a target
					int srcNeuronIdx; 
					int tgtNeuronIdx;
				
					/* Here's some code for adding connections that attempts to avoid any recursive conenctions
					 * within a network by only linking to neurons with innovation id's greater than the source neuron.
					 * Unfortunately this doesn't work because new neurons with large innovations ID's are inserted 
					 * randomly through a network's topology! Hence this code remains here in readyness to be resurrected
					 * as part of some future work to support feedforward nets.
//					if(ea.NeatParameters.feedForwardOnly)
//					{
//						/* We can ensure that all networks are feedforward only by only adding feedforward connections here.
//						 * Feed forward connections fall into one of the following categories.  All references to indexes 
//						 * are indexes within this genome's neuronGeneList:
//						 * 1) Source neuron is an input or hidden node, target is an output node.
//						 * 2) Source is an input or hidden node, target is a hidden node with an index greater than the source node's index.
//						 * 3) Source is an output node, target is an output node with an index greater than the source node's index.
//						 * 
//						 * These rules are easier to understand if you understand how the different types if neuron are arranged within
//						 * the neuronGeneList array. Neurons are arranged in the following order:
//						 * 
//						 * 1) A single bias neuron is always first.
//						 * 2) Experiment specific input neurons.
//						 * 3) Output neurons.
//						 * 4) Hidden neurons.
//						 * 
//						 * The quantity and innovationID of all neurons within the first 3 categories remains fixed throughout the life
//						 * of an experiment, hence we always know where to find the bias, input and output nodes. The number of hidden nodes
//						 * can vary as ne nodes are created, pruned away or perhaps dropped during crossover, however they are always arranged
//						 * newest to oldest, or in other words sorted by innovation idea, lowest ID first. 
//						 * 
//						 * If output neurons were at the end of the list with hidden nodes in the middle then generating feedforward 
//						 * connections would be as easy as selecting a target neuron with a higher index than the source neuron. However, that
//						 * type of arrangement is not conducive to the operation of other routines, hence this routine is a little bit more
//						 * complicated as a result.
//						 */
//					
//						// Ok, for a source neuron we can pick any neuron except the last output neuron.
//						int neuronIdxCount = neuronGeneList.Count;
//						int neuronIdxBound = neuronIdxCount-1;
//
//						// Generate count-1 possibilities and avoid the last output neuron's idx.
//						srcNeuronIdx = (int)Math.Floor(Utilities.NextDouble() * neuronIdxBound);
//						if(srcNeuronIdx>inputBiasOutputNeuronCountMinus2) srcNeuronIdx++;
//						
//
//						// Now generate a target idx depending on what type of neuron srcNeuronIdx is pointing to.
//						if(srcNeuronIdx<inputAndBiasNeuronCount)
//						{	// Source is a bias or input neuron. Target can be any output or hidden neuron.
//							tgtNeuronIdx = inputAndBiasNeuronCount + (int)Math.Floor(Utilities.NextDouble() * (neuronIdxCount-inputAndBiasNeuronCount));
//						}
//						else if(srcNeuronIdx<inputBiasOutputNeuronCount)
//						{	// Source is an output neuron, but not the last output neuron. Target can be any output neuron with an index
//							// greater than srcNeuronIdx.
//							tgtNeuronIdx = (inputAndBiasNeuronCount+1) + (int)Math.Floor(Utilities.NextDouble() * ((inputBiasOutputNeuronCount-1)-srcNeuronIdx));
//						}
//						else 
//						{	// Source is a hidden neuron. Target can be any hidden neuron after srcNeuronIdx or any output neuron.
//							tgtNeuronIdx = (int)Math.Floor(Utilities.NextDouble() * ((neuronIdxBound-srcNeuronIdx)+outputNeuronCount));
//
//							if(tgtNeuronIdx<outputNeuronCount)
//							{	// Map to an output neuron idx.
//								tgtNeuronIdx += inputAndBiasNeuronCount;
//							}
//							else
//							{
//								// Map to one of the hidden neurons after srcNeuronIdx.
//								tgtNeuronIdx = (tgtNeuronIdx-outputNeuronCount)+srcNeuronIdx+1;
//							}
//						}
//					}

//					// Source neuron can by any neuron. Target neuron is any neuron except input neurons.
//					srcNeuronIdx = (int)Math.Floor(Utilities.NextDouble() * neuronGeneList.Count);
//					tgtNeuronIdx = inputAndBiasNeuronCount + (int)Math.Floor(Utilities.NextDouble() * (neuronGeneList.Count-inputAndBiasNeuronCount));
//
//                  NeuronGene sourceNeuron = neuronGeneList[srcNeuronIdx];
//                  NeuronGene targetNeuron = neuronGeneList[tgtNeuronIdx];

                    // Find all potential inputs, or quit if there are not enough. 
                    // Neurons cannot be inputs if they are dummy input nodes of a module.
                    NeuronGeneList potentialInputs = new NeuronGeneList();
                    foreach (NeuronGene n in neuronGeneList) {
                        if (!(n.ActivationFunction is ModuleInputNeuron)) {
                            potentialInputs.Add(n);
                        }
                    }
                    if (potentialInputs.Count < 1)
                        return;

                    // Find all potential outputs, or quit if there are not enough.
                    // Neurons cannot be outputs if they are dummy input or output nodes of a module, or network input or bias nodes.
                    NeuronGeneList potentialOutputs = new NeuronGeneList();
                    foreach (NeuronGene n in neuronGeneList) {
                        if (n.NeuronType != NeuronType.Bias && n.NeuronType != NeuronType.Input
                                && !(n.ActivationFunction is ModuleInputNeuron)
                                && !(n.ActivationFunction is ModuleOutputNeuron)) {
                            potentialOutputs.Add(n);
                        }
                    }
                    if (potentialOutputs.Count < 1)
                        return;

                    NeuronGene sourceNeuron = potentialInputs[Utilities.Next(potentialInputs.Count)];
                    NeuronGene targetNeuron = potentialOutputs[Utilities.Next(potentialOutputs.Count)];

					// Check if a connection already exists between these two neurons.
					uint sourceId = sourceNeuron.InnovationId;
					uint targetId = targetNeuron.InnovationId;

					if(!TestForExistingConnection(sourceId, targetId))
					{
						// Check if a matching mutation has already occured on another genome. 
						// If so then re-use the connection ID.
						ConnectionEndpointsStruct connectionKey = new ConnectionEndpointsStruct(sourceId, targetId);
						ConnectionGene existingConnection = (ConnectionGene)ea.NewConnectionGeneTable[connectionKey];
						ConnectionGene newConnectionGene;
						if(existingConnection==null)
						{	// Create a new connection with a new ID and add it to the Genome.
							newConnectionGene = new ConnectionGene(ea.NextInnovationId, sourceId, targetId,
								(Utilities.NextDouble() * ea.NeatParameters.connectionWeightRange/4.0) - ea.NeatParameters.connectionWeightRange/8.0);

							// Register the new connection with NewConnectionGeneTable.
							ea.NewConnectionGeneTable.Add(connectionKey, newConnectionGene);

							// Add the new gene to this genome. We have a new ID so we can safely append the gene to the end 
							// of the list without risk of breaking the innovation ID order.
							connectionGeneList.Add(newConnectionGene);
						}
						else
						{	// Create a new connection, re-using the ID from existingConnection, and add it to the Genome.
							newConnectionGene = new ConnectionGene(existingConnection.InnovationId, sourceId, targetId,
								(Utilities.NextDouble() * ea.NeatParameters.connectionWeightRange/4.0) - ea.NeatParameters.connectionWeightRange/8.0);

							// Add the new gene to this genome. We are re-using an ID so we must ensure the connection gene is
							// inserted into the correct position (sorted by innovation ID).
							connectionGeneList.InsertIntoPosition(newConnectionGene);
						}
					
						return;
					}
				}
			}

			// We couldn't find a valid connection to create. Instead of doing nothing lets perform connection
			// weight mutation.
			Mutate_ConnectionWeights(ea);
		}
        // NOTE: Multi-Plane Substrates ARE supported by this method!
        private NeatGenome.NeatGenome generateHiveBrainGenomeStack(INetwork network, List<float> stackCoordinates, bool normalizeWeights, bool adaptiveNetwork, bool modulatoryNet,bool ct)
        {
            //bool relativeCoordinate = false;
            bool oneWay = false;
            bool homogeneous = false ;
            Dictionary<String, float> weights = new Dictionary<String, float>();
            float timeConstantMin = 0.1f;
            float timeConstantMax = 2.0f;

            uint numberOfAgents = (uint)stackCoordinates.Count;
            IActivationFunction activationFunction = HyperNEATParameters.substrateActivationFunction;
            ConnectionGeneList connections = new ConnectionGeneList((int)(numberOfAgents * (InputCount * HiddenCount) + numberOfAgents * (HiddenCount * OutputCount))); // TODO: Perhaps get an exact count of connections in the constructor and use that value here?
            float[] coordinates = new float[5]; //JUSTIN: Used to be 6 coordinates, zstack was duplicated for relativeCoordinate hyjinx. fixed it. // Inputs to the CPPN: [srcX, srcY, tgX, tgY, zstack]
            float output;
            uint connectionCounter = 0;
            float agentDelta = 2.0f / (numberOfAgents - 1);
            int iterations = 2 * (network.TotalNeuronCount - (network.InputNeuronCount + network.OutputNeuronCount)) + 1;

            uint totalOutputCount = OutputCount * numberOfAgents;
            uint totalInputCount = InputCount * numberOfAgents;
            uint totalHiddenCount = HiddenCount * numberOfAgents;

            uint sourceCount, targetCout;
            double weightRange = HyperNEATParameters.weightRange;
            double threshold = HyperNEATParameters.threshold;

            NeuronGeneList neurons;
            // SharpNEAT requires that the neuron list be in this order: bias|input|output|hidden
            neurons = new NeuronGeneList((int)(InputCount * numberOfAgents + OutputCount * numberOfAgents + HiddenCount * numberOfAgents));

            // set up the input nodes
            for (uint a = 0; a < totalInputCount; a++)
            {
                neurons.Add(new NeuronGene(a, NeuronType.Input, ActivationFunctionFactory.GetActivationFunction("NullFn")));
            }
            // set up the output nodes
            for (uint a = 0; a < totalOutputCount; a++)
            {

                neurons.Add(new NeuronGene(a + InputCount * numberOfAgents, NeuronType.Output, activationFunction));
            }
            // set up the hidden nodes
            for (uint a = 0; a < totalHiddenCount; a++)
            {
                neurons.Add(new NeuronGene(a + InputCount * numberOfAgents + OutputCount * numberOfAgents, NeuronType.Hidden, activationFunction));
            }

            uint agent = 0;
            float A = 0.0f, B = 0.0f, C = 0.0f, D = 0.0f, learningRate = 0.0f, modConnection;

            // CPPN Outputs: [ Weights ] [ Biases ]
            // When using multi-plane substrates, there will be multiple Weight and Bias outputs.
            // There is a Weight output for every plane-to-plane connection (including a plane connected to itself, as in regular substrates)
            // There is a Bias output for every plane
            // Since "regular substrates" only have 1 plane, they only have 1 Weight and 1 Bias output. MP substrates have more. :)
            int numPlanes = planes.Count;
            int numPlaneConnections = planesConnected.Count;
            int computedIndex;

            foreach (float stackCoordinate in stackCoordinates)
            {
                coordinates[4] = stackCoordinate;
                //coordinates[4] = homogeneous ? 0 : stackCoordinate;//-1 ? -1 : 0;//0;//stackCoordinate;
                //coordinates[5] = stackCoordinate;
                uint sourceID = uint.MaxValue, targetID = uint.MaxValue;
                NeuronGroup connectedNG;

                foreach (NeuronGroup ng in neuronGroups)
                {
                    foreach (uint connectedTo in ng.ConnectedTo)
                    {
                        /*if (!relativeCoordinate)
                            coordinates[5] = stackCoordinate;
                        else //USE RELATIVE
                            coordinates[5] = 0;//*/

                        connectedNG = getNeuronGroup(connectedTo);

                        sourceCount = 0;
                        foreach (PointF source in ng.NeuronPositions)
                        {

                            //-----------------Get the bias of the source node
                           /* switch (ng.GroupType)
                            {
                                case 0: sourceID = (agent * InputCount) + ng.GlobalID + sourceCount; break;                             //Input
                                case 1: sourceID = totalInputCount + (agent * OutputCount) + ng.GlobalID + sourceCount; break;                //Output
                                case 2: sourceID = totalInputCount + totalOutputCount + (agent * HiddenCount) + ng.GlobalID + sourceCount; break;  //Hidden
                            }
                            coordinates[0] = source.X; coordinates[1] = source.Y; coordinates[2] = 0.0f; coordinates[3] = 0.0f;

                            network.ClearSignals();
                            network.SetInputSignals(coordinates);
                            network.RecursiveActivation();//network.MultipleSteps(iterations);

                            neurons[(int)sourceID].Bias = (float)(network.GetOutputSignal(1) * weightRange);
                            if (ct)
                            {
                                neurons[(int)sourceID].TimeConstant = 0.01f + ((((float)network.GetOutputSignal(2) + 1.0f) / 2.0f) * .05f);
                                System.Diagnostics.Debug.Assert(neurons[(int)sourceID].TimeConstant > 0);
                            }*/
                            //----------------------------

                            targetCout = 0;
                            foreach (PointF target in connectedNG.NeuronPositions)
                            {
                                switch (ng.GroupType)
                                {
                                    case 0: sourceID = (agent * InputCount) + ng.GlobalID + sourceCount; break;                             //Input
                                    case 1: sourceID = totalInputCount + (agent * OutputCount) + ng.GlobalID + sourceCount; break;                //Output
                                    case 2: sourceID = totalInputCount + totalOutputCount + (agent * HiddenCount) + ng.GlobalID + sourceCount; break;  //Hidden
                                }

                                switch (connectedNG.GroupType)
                                {
                                    case 0: targetID = (agent * InputCount) + connectedNG.GlobalID + targetCout; break;
                                    case 1: targetID = totalInputCount + (agent * OutputCount) + connectedNG.GlobalID + targetCout; break;
                                    case 2: targetID = totalInputCount + totalOutputCount + (agent * HiddenCount) + connectedNG.GlobalID + targetCout; break;
                                }

                                //-----------------Get the bias of the target node
                                   coordinates[0] = target.X; coordinates[1] = target.Y; coordinates[2] = 0.0f; coordinates[3] = 0.0f;
                                   //String s = arrayToString(coordinates);
                                   //if (weights.ContainsKey(s))
                                   //    neurons[(int)targetID].Bias = weights[s];
                                   //else
                                   {
                                       network.ClearSignals();
                                       network.SetInputSignals(coordinates);
                                       network.RecursiveActivation();//network.MultipleSteps(iterations);
                                       computedIndex = numPlaneConnections + planes.IndexOf(connectedNG.Plane);
                                       //neurons[(int)targetID].Bias = (float)(network.GetOutputSignal(1) * weightRange);
                                       neurons[(int)targetID].Bias = (float)(network.GetOutputSignal(computedIndex) * weightRange);
                                       //weights.Add(s,neurons[(int)targetID].Bias);
                                   }
                                   if (ct)
                                   {
                                       neurons[(int)targetID].TimeConstant = timeConstantMin + ((((float)network.GetOutputSignal(2) + 1.0f) / 2.0f) * (timeConstantMax - timeConstantMin));
                                       System.Diagnostics.Debug.Assert(neurons[(int)targetID].TimeConstant > 0);
                                   }
                                //----------------------------

                                coordinates[0] = source.X;
                                coordinates[1] = source.Y;
                                coordinates[2] = target.X;
                                coordinates[3] = target.Y;
                                //Console.WriteLine(arrayToString(coordinates));
                                
                                //if(weights.ContainsKey(s))
                                //    output = weights[s];
                                //else
                                {
                                    network.ClearSignals();
                                    network.SetInputSignals(coordinates);
                                    network.RecursiveActivation();//network.MultipleSteps(iterations);
                                    computedIndex = indexOfPlaneConnection(ng.Plane, connectedNG.Plane);
                                    //output = network.GetOutputSignal(0);
                                    output = network.GetOutputSignal(computedIndex);
                                    //weights.Add(s, output);
                                }
                                double leo = 0.0;

                                if (adaptiveNetwork)
                                {
                                    A = network.GetOutputSignal(2);
                                    B = network.GetOutputSignal(3);
                                    C = network.GetOutputSignal(4);
                                    D = network.GetOutputSignal(5);
                                    learningRate = network.GetOutputSignal(6);
                                }

                                if (modulatoryNet)
                                {
                                    modConnection = network.GetOutputSignal(7);
                                }
                                else
                                {
                                    modConnection = 0.0f;
                                }

                                if (useLeo)
                                {
                                    threshold = 0.0;
                                    leo = network.GetOutputSignal(2);
                                }

                                if (!useLeo || leo > 0.0)
                                    if (Math.Abs(output) > threshold)
                                    {
                                        float weight = (float)(((Math.Abs(output) - (threshold)) / (1 - threshold)) * weightRange * Math.Sign(output));
                                        //if (adaptiveNetwork)
                                        //{
                                        //    //If adaptive network set weight to small value
                                        //    weight = 0.1f;
                                        //}
                                        connections.Add(new ConnectionGene(connectionCounter++, sourceID, targetID, weight, ref coordinates));
                                    }
                                //else
                                //{
                                //    Console.WriteLine("Not connected");
                                //}
                                targetCout++;
                            }
                            sourceCount++;
                        }
                    }

                    foreach (uint connectedTo in ng.HiveConnectedTo)
                    {
                        bool wrapAround = true;

                        for (uint agentConnect = 0; agentConnect < stackCoordinates.Count; agentConnect++)
                        {
                            //Make sure we're not making a recurrent connection on the same agent
                            //if (agentConnect == agent)
                            //    continue;
                           // else if ((agent == stackCoordinates.Count - 1 && agentConnect == 0) || (agent == 0 && agentConnect == stackCoordinates.Count - 1))
                           //     ;//agentConnect = 0;
                            if (agent != 0 && agent != stackCoordinates.Count - 1)
                                continue;

                            //if (agent == 1)
                            //    continue;

                            //if (agentConnect != 0 )
                            //    continue;

                            //Limits connections to only neighbors.  Good?
                            //if (!((agent == 0 || agentConnect >= agent - 1) && agentConnect <= agent + 1))
                            //    continue;
                            //if (agentConnect > agent + 1 || agentConnect < agent - 1)
                            //    continue;

                            if (oneWay)
                            {
                                //ONE-WAY
                                if (agentConnect > agent + 1 || agentConnect < agent)
                                    continue;
                            }

                            /*if (!relativeCoordinate)
                                //USE THE Z COORDINATE
                                coordinates[5] = stackCoordinates[(int)agentConnect];
                            else
                                //USE THE RELATIVE COORDINATE
                                coordinates[5] = agentConnect > agent ? 1 : -1;
                            //*/
                            //WRAP AROUND
                            /*if (agent == stackCoordinates.Count - 1 && agentConnect == 0)
                                coordinates[5] = 1;
                            else if (agent == 0 && agentConnect == stackCoordinates.Count - 1)
                                coordinates[5] = -1;
                             */

                            connectedNG = getNeuronGroup(connectedTo);

                            sourceCount = 0;
                            foreach (PointF source in ng.NeuronPositions)
                            {

                                //-----------------Get the bias of the source node
                               /* switch (ng.GroupType)
                                {
                                    case 0: sourceID = (agent * InputCount) + ng.GlobalID + sourceCount; break;                             //Input
                                    case 1: sourceID = totalInputCount + (agent * OutputCount) + ng.GlobalID + sourceCount; break;                //Output
                                    case 2: sourceID = totalInputCount + totalOutputCount + (agent * HiddenCount) + ng.GlobalID + sourceCount; break;  //Hidden
                                }
                                coordinates[0] = source.X; coordinates[1] = source.Y; coordinates[2] = 0.0f; coordinates[3] = 0.0f;

                                network.ClearSignals();
                                network.SetInputSignals(coordinates);
                                network.RecursiveActivation();//network.MultipleSteps(iterations);

                                neurons[(int)sourceID].Bias = (float)(network.GetOutputSignal(1) * weightRange);
                                if (ct)
                                {
                                    neurons[(int)sourceID].TimeConstant = 0.01f + ((((float)network.GetOutputSignal(2) + 1.0f) / 2.0f) * .05f);
                                    System.Diagnostics.Debug.Assert(neurons[(int)sourceID].TimeConstant > 0);
                                }*/
                                //----------------------------

                                targetCout = 0;
                                foreach (PointF target in connectedNG.NeuronPositions)
                                {
                                    /*if ((source.X != target.X))
                                    {
                                        targetCout++;
                                        continue;
                                    }*/
                                    if (/*source.X!= target.X ||*/ target.X != coordinates[4])// || source.X!= coordinates[4])
                                    {
                                        targetCout++;
                                        continue;
                                    }
                                   /* if (agent != 0 && agent != stackCoordinates.Count - 1)
                                    { 
                                        if(agentConnect != 0 && agentConnect != stackCoordinates.Count - 1)
                                        {
                                            targetCout++;
                                            continue;
                                        }
                                    }*/
                                    switch (ng.GroupType)
                                    {
                                        case 0: sourceID = (agent * InputCount) + ng.GlobalID + sourceCount; break;                             //Input
                                        case 1: sourceID = totalInputCount + (agent * OutputCount) + ng.GlobalID + sourceCount; break;                //Output
                                        case 2: sourceID = totalInputCount + totalOutputCount + (agent * HiddenCount) + ng.GlobalID + sourceCount; break;  //Hidden
                                    }

                                    switch (connectedNG.GroupType)
                                    {
                                        case 0: targetID = (agentConnect * InputCount) + connectedNG.GlobalID + targetCout; break;
                                        case 1: targetID = totalInputCount + (agentConnect * OutputCount) + connectedNG.GlobalID + targetCout; break;
                                        case 2: targetID = totalInputCount + totalOutputCount + (agentConnect * HiddenCount) + connectedNG.GlobalID + targetCout; break;
                                    }

                                    //-----------------Get the bias of the target node
                                    coordinates[0] = target.X; coordinates[1] = target.Y; coordinates[2] = 0.0f; coordinates[3] = 0.0f;
                                    //String s = arrayToString(coordinates);
                                    //if (weights.ContainsKey(s))
                                    //    neurons[(int)targetID].Bias = weights[s];
                                    //else
                                    {
                                        network.ClearSignals();
                                        network.SetInputSignals(coordinates);
                                        network.RecursiveActivation();//network.MultipleSteps(iterations);
                                        computedIndex = numPlaneConnections + planes.IndexOf(connectedNG.Plane);
                                        //neurons[(int)targetID].Bias = (float)(network.GetOutputSignal(1) * weightRange);
                                        neurons[(int)targetID].Bias = (float)(network.GetOutputSignal(computedIndex) * weightRange);
                                       // weights.Add(s, neurons[(int)targetID].Bias);
                                    }
                                    if (ct)
                                    {
                                        neurons[(int)targetID].TimeConstant = timeConstantMin + ((((float)network.GetOutputSignal(2) + 1.0f) / 2.0f) * (timeConstantMax - timeConstantMin));
                                        System.Diagnostics.Debug.Assert(neurons[(int)targetID].TimeConstant > 0);
                                    }
                                    //----------------------------

                                    coordinates[0] = source.X;
                                    coordinates[1] = source.Y;
                                    coordinates[2] = target.X;
                                    coordinates[3] = target.Y;
                                    //s = arrayToString(coordinates);
                                    //if (weights.ContainsKey(s))
                                    //    output = weights[s];
                                    //else
                                    {
                                        network.ClearSignals();
                                        network.SetInputSignals(coordinates);
                                        network.RecursiveActivation();//network.MultipleSteps(iterations);
                                        computedIndex = indexOfPlaneConnection(ng.Plane, connectedNG.Plane);
                                        //output = network.GetOutputSignal(0);
                                        output = network.GetOutputSignal(computedIndex);
                                      //  weights.Add(s, output);
                                    }

                                    double leo = 0.0;

                                    if (adaptiveNetwork)
                                    {
                                        A = network.GetOutputSignal(2);
                                        B = network.GetOutputSignal(3);
                                        C = network.GetOutputSignal(4);
                                        D = network.GetOutputSignal(5);
                                        learningRate = network.GetOutputSignal(6);
                                    }

                                    if (modulatoryNet)
                                    {
                                        modConnection = network.GetOutputSignal(7);
                                    }
                                    else
                                    {
                                        modConnection = 0.0f;
                                    }

                                    if (useLeo)
                                    {
                                        threshold = 0.0;
                                        leo = network.GetOutputSignal(2);
                                    }

                                    if (!useLeo || leo > 0.0)
                                        if (Math.Abs(output) > threshold)
                                        {
                                            float weight = (float)(((Math.Abs(output) - (threshold)) / (1 - threshold)) * weightRange * Math.Sign(output));
                                            //if (adaptiveNetwork)
                                            //{
                                            //    //If adaptive network set weight to small value
                                            //    weight = 0.1f;
                                            //}
                                            connections.Add(new ConnectionGene(connectionCounter++, sourceID, targetID, weight, ref coordinates, true));
                                        }
                                    //else
                                    //{
                                    //    Console.WriteLine("Not connected");
                                    //}
                                    targetCout++;
                                }
                                sourceCount++;
                            }
                        }
                    }
                }
                agent++;
            }
            if (normalizeWeights)
            {
                normalizeWeightConnections(ref connections, neurons.Count);
            }
            SharpNeatLib.NeatGenome.NeatGenome sng = new SharpNeatLib.NeatGenome.NeatGenome(0, neurons, connections, (int)(totalInputCount), (int)(totalOutputCount));
            sng.networkAdaptable = adaptiveNetwork;
            sng.networkModulatory = modulatoryNet;
            return sng;
        }
Esempio n. 19
0
        private void Mutate_AddModule(EvolutionAlgorithm ea)
        {
            // Find all potential inputs, or quit if there are not enough. 
            // Neurons cannot be inputs if they are dummy input nodes created for another module.
            NeuronGeneList potentialInputs = new NeuronGeneList();
            foreach (NeuronGene n in neuronGeneList) {
                if (!(n.ActivationFunction is ModuleInputNeuron)) {
                    potentialInputs.Add(n);
                }
            }
            if (potentialInputs.Count < 1)
                return;

            // Find all potential outputs, or quit if there are not enough.
            // Neurons cannot be outputs if they are dummy input or output nodes created for another module, or network input or bias nodes.
            NeuronGeneList potentialOutputs = new NeuronGeneList();
            foreach (NeuronGene n in neuronGeneList) {
                if (n.NeuronType != NeuronType.Bias && n.NeuronType != NeuronType.Input
                        && !(n.ActivationFunction is ModuleInputNeuron)
                        && !(n.ActivationFunction is ModuleOutputNeuron)) {
                    potentialOutputs.Add(n);
                }
            }
            if (potentialOutputs.Count < 1)
                return;

            // Pick a new function for the new module.
            IModule func = ModuleFactory.GetRandom();

            // Choose inputs uniformly at random, with replacement.
            // Create dummy neurons to represent the module's inputs.
            // Create connections between the input nodes and the dummy neurons.
            IActivationFunction inputFunction = ActivationFunctionFactory.GetActivationFunction("ModuleInputNeuron");
            List<uint> inputDummies = new List<uint>(func.InputCount);
            for (int i = 0; i < func.InputCount; i++) {
                NeuronGene newNeuronGene = new NeuronGene(ea.NextInnovationId, NeuronType.Hidden, inputFunction);
                neuronGeneList.Add(newNeuronGene);

                uint sourceId = potentialInputs[Utilities.Next(potentialInputs.Count)].InnovationId;
                uint targetId = newNeuronGene.InnovationId;

                inputDummies.Add(targetId);

                // Create a new connection with a new ID and add it to the Genome.
                ConnectionGene newConnectionGene = new ConnectionGene(ea.NextInnovationId, sourceId, targetId,
                    (Utilities.NextDouble() * ea.NeatParameters.connectionWeightRange) - ea.NeatParameters.connectionWeightRange / 2.0);

                // Register the new connection with NewConnectionGeneTable.
                ConnectionEndpointsStruct connectionKey = new ConnectionEndpointsStruct(sourceId, targetId);
                ea.NewConnectionGeneTable.Add(connectionKey, newConnectionGene);

                // Add the new gene to this genome. We have a new ID so we can safely append the gene to the end 
                // of the list without risk of breaking the innovation ID order.
                connectionGeneList.Add(newConnectionGene);
            }

            // Choose outputs uniformly at random, with replacement.
            // Create dummy neurons to represent the module's outputs.
            // Create connections between the output nodes and the dummy neurons.
            IActivationFunction outputFunction = ActivationFunctionFactory.GetActivationFunction("ModuleOutputNeuron");
            List<uint> outputDummies = new List<uint>(func.OutputCount);
            for (int i = 0; i < func.OutputCount; i++) {
                NeuronGene newNeuronGene = new NeuronGene(ea.NextInnovationId, NeuronType.Hidden, outputFunction);
                neuronGeneList.Add(newNeuronGene);

                uint sourceId = newNeuronGene.InnovationId;
                uint targetId = potentialOutputs[Utilities.Next(potentialOutputs.Count)].InnovationId;

                outputDummies.Add(sourceId);

                // Create a new connection with a new ID and add it to the Genome.
                ConnectionGene newConnectionGene = new ConnectionGene(ea.NextInnovationId, sourceId, targetId,
                    (Utilities.NextDouble() * ea.NeatParameters.connectionWeightRange) - ea.NeatParameters.connectionWeightRange / 2.0);

                // Register the new connection with NewConnectionGeneTable.
                ConnectionEndpointsStruct connectionKey = new ConnectionEndpointsStruct(sourceId, targetId);
                ea.NewConnectionGeneTable.Add(connectionKey, newConnectionGene);

                // Add the new gene to this genome. We have a new ID so we can safely append the gene to the end 
                // of the list without risk of breaking the innovation ID order.
                connectionGeneList.Add(newConnectionGene);
            }

            // Pick a new ID for the new module and create it.
            // Modules do not participate in history comparisons, so we will always create a new innovation ID.
            // We can change this here if it becomes a problem.
            ModuleGene newModule = new ModuleGene(ea.NextInnovationId, func, inputDummies, outputDummies);
            moduleGeneList.Add(newModule);
        }
Esempio n. 20
0
        public static IGenome CreateGenomePreserveID(NeatParameters neatParameters, IdGenerator idGenerator, int inputNeuronCount, int outputNeuronCount, float connectionProportion)
        {
            IActivationFunction actFunct;
            NeuronGene neuronGene; // temp variable.
            NeuronGeneList inputNeuronGeneList = new NeuronGeneList(); // includes bias neuron.
            NeuronGeneList outputNeuronGeneList = new NeuronGeneList();
            NeuronGeneList neuronGeneList = new NeuronGeneList();
            ConnectionGeneList connectionGeneList = new ConnectionGeneList();

            int nodeCount = 0;

            WINManager win = WINManager.SharedWIN;

            // IMPORTANT NOTE: The neurons must all be created prior to any connections. That way all of the genomes
            // will obtain the same innovation ID's for the bias,input and output nodes in the initial population.
            // Create a single bias neuron.
            //TODO: DAVID proper activation function change to NULL?
            actFunct = ActivationFunctionFactory.GetActivationFunction("NullFn");
            //neuronGene = new NeuronGene(idGenerator.NextInnovationId, NeuronType.Bias, actFunct);
            WINNode neuronNode = win.findOrInsertNodeWithProperties(idGenerator,
                WINNode.NodeWithProperties(nodeCount++, NeuronType.Bias)
                );

            neuronGene = new NeuronGene(null, neuronNode.UniqueID, NeuronGene.INPUT_LAYER, NeuronType.Bias, actFunct);
            inputNeuronGeneList.Add(neuronGene);
            neuronGeneList.Add(neuronGene);

            // Create input neuron genes.
            actFunct = ActivationFunctionFactory.GetActivationFunction("NullFn");
            for (int i = 0; i < inputNeuronCount; i++)
            {
                //TODO: DAVID proper activation function change to NULL?
                //neuronGene = new NeuronGene(idGenerator.NextInnovationId, NeuronType.Input, actFunct);
                neuronNode = win.findOrInsertNodeWithProperties(idGenerator, WINNode.NodeWithProperties(nodeCount++, NeuronType.Input));

                neuronGene = new NeuronGene(null, neuronNode.UniqueID, NeuronGene.INPUT_LAYER, NeuronType.Input, actFunct);
                inputNeuronGeneList.Add(neuronGene);
                neuronGeneList.Add(neuronGene);
            }

            // Create output neuron genes.
            //actFunct = ActivationFunctionFactory.GetActivationFunction("NullFn");
            for (int i = 0; i < outputNeuronCount; i++)
            {
                actFunct = ActivationFunctionFactory.GetActivationFunction("BipolarSigmoid");
                //actFunct = ActivationFunctionFactory.GetRandomActivationFunction(neatParameters);
                //TODO: DAVID proper activation function
                //neuronGene = new NeuronGene(idGenerator.NextInnovationId, NeuronType.Output, actFunct);
                neuronNode = win.findOrInsertNodeWithProperties(idGenerator, WINNode.NodeWithProperties(nodeCount++, NeuronType.Output));

                neuronGene = new NeuronGene(null, neuronNode.UniqueID, NeuronGene.OUTPUT_LAYER, NeuronType.Output, actFunct);
                outputNeuronGeneList.Add(neuronGene);
                neuronGeneList.Add(neuronGene);
            }

            int currentConnCount = 0;
            WINConnection winConn;
            // Loop over all possible connections from input to output nodes and create a number of connections based upon
            // connectionProportion.
            foreach (NeuronGene targetNeuronGene in outputNeuronGeneList)
            {
                foreach (NeuronGene sourceNeuronGene in inputNeuronGeneList)
                {
                    // Always generate an ID even if we aren't going to use it. This is necessary to ensure connections
                    // between the same neurons always have the same ID throughout the generated population.
                    //PAUL NOTE:
                    //instead of generating and not using and id, we use the target and connection properties to uniquely identify a connection in WIN
                    //uint connectionInnovationId = idGenerator.NextInnovationId;

                    if (Utilities.NextDouble() < connectionProportion)
                    {
                        // Ok lets create a connection.
                        //first we search or create the winconnection object
                        winConn = win.findOrInsertConnectionWithProperties(idGenerator,
                            WINConnection.ConnectionWithProperties(currentConnCount, sourceNeuronGene.InnovationId, targetNeuronGene.InnovationId));

                        //our winconn will have our innovationID, and our weight like normal
                        //this will also respect the idgenerator, since it gets sent in as well, for legacy purposes
                        connectionGeneList.Add(new ConnectionGene(winConn.UniqueID,
                            sourceNeuronGene.InnovationId,
                            targetNeuronGene.InnovationId,
                            (Utilities.NextDouble() * neatParameters.connectionWeightRange) - neatParameters.connectionWeightRange / 2.0)
                            );
                            //(Utilities.NextDouble() * neatParameters.connectionWeightRange) - neatParameters.connectionWeightRange / 2.0));  // Weight 0 +-5
                    }

                    currentConnCount++;

                }
            }
            //WIN will eventually be in control of all the genomes that are created as well, but not quite yet!
            //TODO: WIN should be generating genomeIDs explicitly

            // Don't create any hidden nodes at this point. Fundamental to the NEAT way is to start minimally!
            return new NeatGenome(idGenerator.NextGenomeId, neuronGeneList, connectionGeneList, inputNeuronCount, outputNeuronCount);
        }
        // MPS support on the Hive methods only
        #region Generate heterogenous genomes with z-stack

        // MPS NOT supported by this method
        private NeatGenome.NeatGenome generateMultiGenomeStack(INetwork network, List<float> stackCoordinates, bool normalizeWeights, bool adaptiveNetwork, bool modulatoryNet)
        {
            if (useMultiPlaneSubstrate) throw new Exception("MPS not implemented for these parameters");
            uint numberOfAgents = (uint)stackCoordinates.Count;
            IActivationFunction activationFunction = HyperNEATParameters.substrateActivationFunction;
            ConnectionGeneList connections = new ConnectionGeneList((int)(numberOfAgents * (InputCount * HiddenCount) + numberOfAgents * (HiddenCount * OutputCount)));
            float[] coordinates = new float[5];
            float output;
            uint connectionCounter = 0;
            float agentDelta = 2.0f / (numberOfAgents - 1);
            int iterations = 2 * (network.TotalNeuronCount - (network.InputNeuronCount + network.OutputNeuronCount)) + 1;

            uint totalOutputCount = OutputCount * numberOfAgents;
            uint totalInputCount = InputCount * numberOfAgents;
            uint totalHiddenCount = HiddenCount * numberOfAgents;

            uint sourceCount, targetCout;
            double weightRange = HyperNEATParameters.weightRange;
            double threshold = HyperNEATParameters.threshold;

            NeuronGeneList neurons;
            // SharpNEAT requires that the neuron list be in this order: bias|input|output|hidden
            neurons = new NeuronGeneList((int)(InputCount * numberOfAgents + OutputCount * numberOfAgents + HiddenCount * numberOfAgents));

            // set up the input nodes
            for (uint a = 0; a < totalInputCount; a++)
            {
                neurons.Add(new NeuronGene(a, NeuronType.Input, ActivationFunctionFactory.GetActivationFunction("NullFn")));
            }
            // set up the output nodes
            for (uint a = 0; a < totalOutputCount; a++)
            {

                neurons.Add(new NeuronGene(a + InputCount * numberOfAgents, NeuronType.Output, activationFunction));
            }
            // set up the hidden nodes
            for (uint a = 0; a < totalHiddenCount; a++)
            {
                neurons.Add(new NeuronGene(a + InputCount * numberOfAgents + OutputCount * numberOfAgents, NeuronType.Hidden, activationFunction));
            }

            uint agent = 0;
            float A = 0.0f, B = 0.0f, C = 0.0f, D = 0.0f, learningRate = 0.0f, modConnection;

            foreach (float stackCoordinate in stackCoordinates)
            {
                coordinates[4] = stackCoordinate;
                uint sourceID = uint.MaxValue, targetID = uint.MaxValue;
                NeuronGroup connectedNG;

                foreach (NeuronGroup ng in neuronGroups)
                {
                    foreach (uint connectedTo in ng.ConnectedTo)
                    {
                        connectedNG = getNeuronGroup(connectedTo);

                        sourceCount = 0;
                        foreach (PointF source in ng.NeuronPositions)
                        {

                            //-----------------Get the bias of the source node
                            switch (ng.GroupType)
                            {
                                case 0: sourceID = (agent * InputCount) + ng.GlobalID + sourceCount; break;                             //Input
                                case 1: sourceID = totalInputCount + (agent * OutputCount) + ng.GlobalID + sourceCount; break;                //Output
                                case 2: sourceID = totalInputCount + totalOutputCount + (agent * HiddenCount) + ng.GlobalID + sourceCount; break;  //Hidden
                            }
                            coordinates[0] = source.X; coordinates[1] = source.Y; coordinates[2] = 0.0f; coordinates[3] = 0.0f;

                            network.ClearSignals();
                            network.SetInputSignals(coordinates);
                            network.RecursiveActivation();//network.MultipleSteps(iterations);

                            neurons[(int)sourceID].Bias = (float)(network.GetOutputSignal(1) * weightRange);
                            //----------------------------

                            targetCout = 0;
                            foreach (PointF target in connectedNG.NeuronPositions)
                            {
                                switch (ng.GroupType)
                                {
                                    case 0: sourceID = (agent * InputCount) + ng.GlobalID + sourceCount; break;                             //Input
                                    case 1: sourceID = totalInputCount + (agent * OutputCount) + ng.GlobalID + sourceCount; break;                //Output
                                    case 2: sourceID = totalInputCount + totalOutputCount + (agent * HiddenCount) + ng.GlobalID + sourceCount; break;  //Hidden
                                }

                                switch (connectedNG.GroupType)
                                {
                                    case 0: targetID = (agent * InputCount) + connectedNG.GlobalID + targetCout; break;
                                    case 1: targetID = totalInputCount + (agent * OutputCount) + connectedNG.GlobalID + targetCout; break;
                                    case 2: targetID = totalInputCount + totalOutputCount + (agent * HiddenCount) + connectedNG.GlobalID + targetCout; break;
                                }

                                coordinates[0] = source.X;
                                coordinates[1] = source.Y;
                                coordinates[2] = target.X;
                                coordinates[3] = target.Y;

                                network.ClearSignals();
                                network.SetInputSignals(coordinates);
                                network.RecursiveActivation();//network.MultipleSteps(iterations);
                                output = network.GetOutputSignal(0);

                                double leo = 0.0;

                                if (adaptiveNetwork)
                                {
                                    A = network.GetOutputSignal(2);
                                    B = network.GetOutputSignal(3);
                                    C = network.GetOutputSignal(4);
                                    D = network.GetOutputSignal(5);
                                    learningRate = network.GetOutputSignal(6);
                                }

                                if (modulatoryNet)
                                {
                                    modConnection = network.GetOutputSignal(7);
                                }
                                else
                                {
                                    modConnection = 0.0f;
                                }

                                if (useLeo)
                                {
                                    threshold = 0.0;
                                    leo = network.GetOutputSignal(2);
                                }

                                if (!useLeo || leo > 0.0)
                                    if (Math.Abs(output) > threshold)
                                    {
                                        float weight = (float)(((Math.Abs(output) - (threshold)) / (1 - threshold)) * weightRange * Math.Sign(output));
                                        //if (adaptiveNetwork)
                                        //{
                                        //    //If adaptive network set weight to small value
                                        //    weight = 0.1f;
                                        //}
                                        connections.Add(new ConnectionGene(connectionCounter++, sourceID, targetID, weight, ref coordinates));
                                    }
                                //else
                                //{
                                //    Console.WriteLine("Not connected");
                                //}
                                targetCout++;
                            }
                            sourceCount++;
                        }
                    }
                }
                agent++;
            }
            if (normalizeWeights)
            {
                normalizeWeightConnections(ref connections, neurons.Count);
            }
            SharpNeatLib.NeatGenome.NeatGenome sng = new SharpNeatLib.NeatGenome.NeatGenome(0, neurons, connections, (int)(totalInputCount), (int)(totalOutputCount));
            sng.networkAdaptable = adaptiveNetwork;
            sng.networkModulatory = modulatoryNet;
            return sng;
        }
Esempio n. 22
0
    void QueryConnection(INetwork network, ConnectionGeneList connections, uint connectionCounter, uint neuron1id, uint neuron2id, int moduleI, NeuronGeneList newNeurons)
    {
        int iterations = 2 * (network.TotalNeuronCount - (network.InputNeuronCount + network.OutputNeuronCount)) + 1;

        network.ClearSignals();
        //network.SetInputSignal(0, 1);
        network.SetInputSignal(0, newNeurons[(int)neuron1id].XValue);
        network.SetInputSignal(1, newNeurons[(int)neuron1id].YValue);
        network.SetInputSignal(2, newNeurons[(int)neuron2id].XValue);
        network.SetInputSignal(3, newNeurons[(int)neuron2id].YValue);
        network.SetInputSignal(4, 1);
        network.MultipleSteps(iterations);

        float output = network.GetOutputSignal(moduleI);

        if (Math.Abs(output) > threshold)
        {
            float weight = (float)(((Math.Abs(output) - (threshold)) / (1 - threshold)) * weightRange * Math.Sign(output));
            connections.Add(new ConnectionGene(connectionCounter, neuron1id, neuron2id, weight));
        }
    }
Esempio n. 23
0
    public NeatGenome MakeGenome(INetwork network, int moduleI)
    {
        // copy the neuron list to a new list and update the x/y values
        NeuronGeneList newNeurons = new NeuronGeneList(neurons);

        // set the x and y value of the SUPGs
        foreach (NeuronGene neuron in newNeurons)
        {
            Point point = GetCustomPos(neuron.InnovationId);
            neuron.XValue = point.X;
            neuron.YValue = point.Y;

            /*if (neuron.NeuronType != NeuronType.Input) {
             *  neuron.ActivationFunction = new SteepenedSigmoid();
             * }*/
            //neuron.TimeConstant = 1;
            neuron.NeuronBias = GetNeuronBias(network, neuron, moduleI + 1);
        }

        ConnectionGeneList connections = new ConnectionGeneList((int)((inputCount * hiddenCount) + (hiddenCount * outputCount)));

        float[] coordinates = new float[5];
        float   output;
        uint    connectionCounter = 0;
        int     iterations        = 2 * (network.TotalNeuronCount - (network.InputNeuronCount + network.OutputNeuronCount)) + 1;

        // Connections from input to hidden
        for (uint source = 0; source < inputCount; source++)
        {
            QueryConnection(network, connections, connectionCounter++, source, 11, moduleI, newNeurons);
            QueryConnection(network, connections, connectionCounter++, source, 12, moduleI, newNeurons);
            QueryConnection(network, connections, connectionCounter++, source, 13, moduleI, newNeurons);
            QueryConnection(network, connections, connectionCounter++, source, 14, moduleI, newNeurons);
            QueryConnection(network, connections, connectionCounter++, source, 15, moduleI, newNeurons);
            QueryConnection(network, connections, connectionCounter++, source, 16, moduleI, newNeurons);

            // output

            /*QueryConnection(network, connections, connectionCounter++, source, 6, moduleI, newNeurons);
            *  QueryConnection(network, connections, connectionCounter++, source, 7, moduleI, newNeurons);
            *  QueryConnection(network, connections, connectionCounter++, source, 8, moduleI, newNeurons);
            *  QueryConnection(network, connections, connectionCounter++, source, 9, moduleI, newNeurons);*/

            // Special Output
            //QueryConnection(network, connections, connectionCounter++, source, 10, moduleI+2, newNeurons);
        }
        //QueryConnection(network, connections, connectionCounter++, 0, 10, 2, newNeurons);
        //QueryConnection(network, connections, connectionCounter++, 5, 10, 2, newNeurons);
        // Connection from input to output

        /*QueryConnection(network, connections, connectionCounter++, 5, 6, newNeurons);
        *  QueryConnection(network, connections, connectionCounter++, 5, 7, newNeurons);*/
        // Connections from hidden to output
        for (uint source = 0; source < hiddenCount; source++)
        {
            uint tmpSource = source + inputCount + outputCount;
            QueryConnection(network, connections, connectionCounter++, tmpSource, 6, moduleI, newNeurons);
            QueryConnection(network, connections, connectionCounter++, tmpSource, 7, moduleI, newNeurons);
            QueryConnection(network, connections, connectionCounter++, tmpSource, 8, moduleI, newNeurons);
            QueryConnection(network, connections, connectionCounter++, tmpSource, 9, moduleI, newNeurons);

            // Special Output
            //QueryConnection(network, connections, connectionCounter++, tmpSource, 10, moduleI + 2, newNeurons);
        }
        return(new SharpNeatLib.NeatGenome.NeatGenome(0, newNeurons, connections, (int)inputCount, (int)outputCount));
    }
        private NeatGenome.NeatGenome generateHomogeneousGenome(INetwork network, bool normalizeWeights, bool adaptiveNetwork, bool modulatoryNet)
        {
            IActivationFunction activationFunction = HyperNEATParameters.substrateActivationFunction;
            ConnectionGeneList connections = new ConnectionGeneList((int)((InputCount * HiddenCount) + (HiddenCount * OutputCount)));
            float[] coordinates = new float[4];
            float output;
            uint connectionCounter = 0;
            int iterations = 2 * (network.TotalNeuronCount - (network.InputNeuronCount + network.OutputNeuronCount)) + 1;

            uint totalOutputCount = OutputCount;
            uint totalInputCount = InputCount;
            uint totalHiddenCount = HiddenCount;

            uint sourceCount, targetCout;
            double weightRange = HyperNEATParameters.weightRange;
            double threshold = HyperNEATParameters.threshold;

            NeuronGeneList neurons;
            // SharpNEAT requires that the neuron list be in this order: bias|input|output|hidden
            neurons = new NeuronGeneList((int)(InputCount + OutputCount + HiddenCount));

            // set up the input nodes
            for (uint a = 0; a < totalInputCount; a++)
            {
                neurons.Add(new NeuronGene(a, NeuronType.Input, ActivationFunctionFactory.GetActivationFunction("NullFn")));
            }
            // set up the output nodes
            for (uint a = 0; a < totalOutputCount; a++)
            {

                neurons.Add(new NeuronGene(a + InputCount, NeuronType.Output, activationFunction));
            }
            // set up the hidden nodes
            for (uint a = 0; a < totalHiddenCount; a++)
            {
                neurons.Add(new NeuronGene(a + InputCount + OutputCount, NeuronType.Hidden, activationFunction));
            }

            bool[] biasCalculated = new bool[totalHiddenCount + totalOutputCount + totalInputCount];

            uint sourceID = uint.MaxValue, targetID = uint.MaxValue;
            NeuronGroup connectedNG;

            foreach (NeuronGroup ng in neuronGroups)
            {
                foreach (uint connectedTo in ng.ConnectedTo)
                {
                    connectedNG = getNeuronGroup(connectedTo);

                    sourceCount = 0;
                    foreach (PointF source in ng.NeuronPositions)
                    {

                        targetCout = 0;
                        foreach (PointF target in connectedNG.NeuronPositions)
                        {
                            switch (ng.GroupType)
                            {
                                case 0: sourceID = ng.GlobalID + sourceCount; break;                             //Input
                                case 1: sourceID = totalInputCount + ng.GlobalID + sourceCount; break;                //Output
                                case 2: sourceID = totalInputCount + totalOutputCount + ng.GlobalID + sourceCount; break;  //Hidden
                            }

                            switch (connectedNG.GroupType)
                            {
                                case 0: targetID = connectedNG.GlobalID + targetCout; break;
                                case 1: targetID = totalInputCount + connectedNG.GlobalID + targetCout; break;
                                case 2: targetID = totalInputCount + totalOutputCount + connectedNG.GlobalID + targetCout; break;
                            }

                            //calculate bias of target node
                            if (!biasCalculated[targetID])
                            {
                                coordinates[0] = 0.0f; coordinates[1] = 0.0f; coordinates[2] = target.X; coordinates[3] = target.Y;

                                network.ClearSignals();
                                network.SetInputSignals(coordinates);
                                ((ModularNetwork)network).RecursiveActivation();
                                neurons[(int)targetID].Bias = (float)(network.GetOutputSignal(1) * weightRange);
                                biasCalculated[targetID] = true;
                            }

                            coordinates[0] = source.X;
                            coordinates[1] = source.Y;
                            coordinates[2] = target.X;
                            coordinates[3] = target.Y;

                            network.ClearSignals();
                            network.SetInputSignals(coordinates);
                            ((ModularNetwork)network).RecursiveActivation();
                            //network.MultipleSteps(iterations);
                            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(connectionCounter++, sourceID, targetID, weight, ref coordinates, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
                            }
                            //else
                            //{
                            //    Console.WriteLine("Not connected");
                            //}
                            targetCout++;
                        }
                        sourceCount++;
                    }
                }
            }
            if (normalizeWeights)
            {
                normalizeWeightConnections(ref connections, neurons.Count);
            }
            NeatGenome.NeatGenome gn = new SharpNeatLib.NeatGenome.NeatGenome(0, neurons, connections, (int)(totalInputCount), (int)(totalOutputCount));

            gn.networkAdaptable = adaptiveNetwork;
            gn.networkModulatory = modulatoryNet;
            return gn;
        }
Esempio n. 25
0
        public NeatGenome(uint genomeId,
                NeuronGeneList neuronGeneList,
                List<ModuleGene> moduleGeneList,
                ConnectionGeneList connectionGeneList,
                int inputNeuronCount,
                int outputNeuronCount,
                int outputsPerPolicy) // Schrum: Added
        {
			this.genomeId = genomeId;

			this.neuronGeneList = neuronGeneList;
            this.moduleGeneList = moduleGeneList;
			this.connectionGeneList = connectionGeneList;

			this.inputNeuronCount = inputNeuronCount;
            // Schrum: Removed (not used)
			//this.inputAndBiasNeuronCount = inputNeuronCount+1;
			this.outputNeuronCount = outputNeuronCount;
			
            // Schrum: Removed (not used)
            //this.inputBiasOutputNeuronCount = inputAndBiasNeuronCount + outputNeuronCount;
			//this.inputBiasOutputNeuronCountMinus2 = inputBiasOutputNeuronCount-2;
            
            // Schrum: Added
            this.outputsPerPolicy = outputsPerPolicy;

			Debug.Assert(connectionGeneList.IsSorted(), "ConnectionGeneList is not sorted by innovation ID");
		}
        /// <summary>
        ///     TODO
        /// </summary>
        /// <param name="birthGeneration">
        ///     The current evolution algorithm generation.
        ///     Assigned to the new genome as its birth generation.
        /// </param>
        public override NeatGenome CreateGenome(uint birthGeneration)
        {
            NeuronGeneList neuronGeneList = new NeuronGeneList(_inputNeuronCount + _outputNeuronCount);
            NeuronGeneList inputNeuronGeneList = new NeuronGeneList(_inputNeuronCount); // includes single bias neuron.
            NeuronGeneList outputNeuronGeneList = new NeuronGeneList(_outputNeuronCount);

            // Create a single bias neuron.
            uint biasNeuronId = _innovationIdGenerator.NextId;
            if (0 != biasNeuronId)
            {   // The ID generator must be reset before calling this method so that all generated genomes use the
                // same innovation ID for matching neurons and structures.
                throw new SharpNeatException("IdGenerator must be reset before calling CreateGenome(uint)");
            }

            // Note. Genes within nGeneList must always be arranged according to the following layout plan.
            //   Bias - single neuron. Innovation ID = 0
            //   Input neurons.
            //   Output neurons.
            //   Hidden neurons.
            NeuronGene neuronGene = CreateNeuronGene(biasNeuronId, NodeType.Bias);
            inputNeuronGeneList.Add(neuronGene);
            neuronGeneList.Add(neuronGene);

            // Create input neuron genes.
            for (int i = 0; i < _inputNeuronCount; i++)
            {
                neuronGene = CreateNeuronGene(_innovationIdGenerator.NextId, NodeType.Input);
                inputNeuronGeneList.Add(neuronGene);
                neuronGeneList.Add(neuronGene);
            }

            // Create output neuron genes.
            for (int i = 0; i < _outputNeuronCount; i++)
            {
                neuronGene = CreateNeuronGene(_innovationIdGenerator.NextId, NodeType.Output);
                outputNeuronGeneList.Add(neuronGene);
                neuronGeneList.Add(neuronGene);
            }

            // Define all possible connections between the input and output neurons (fully interconnected).
            int srcCount = inputNeuronGeneList.Count;
            int tgtCount = outputNeuronGeneList.Count;
            ConnectionDefinition[] connectionDefArr = new ConnectionDefinition[srcCount * tgtCount];

            for (int srcIdx = 0, i = 0; srcIdx < srcCount; srcIdx++)
            {
                for (int tgtIdx = 0; tgtIdx < tgtCount; tgtIdx++)
                {
                    connectionDefArr[i++] = new ConnectionDefinition(_innovationIdGenerator.NextId, srcIdx, tgtIdx);
                }
            }

            // Shuffle the array of possible connections.
            Utilities.Shuffle(connectionDefArr, _rng);

            // Select connection definitions from the head of the list and convert them to real connections.
            // We want some proportion of all possible connections but at least one (Connectionless genomes are not allowed).
            int connectionCount = (int)Utilities.ProbabilisticRound(
                (double)connectionDefArr.Length * _neatGenomeParamsComplexifying.InitialInterconnectionsProportion,
                _rng);
            connectionCount = Math.Max(1, connectionCount);

            // Create the connection gene list and populate it.
            ConnectionGeneList connectionGeneList = new ConnectionGeneList(connectionCount);

            #region Add connection to bisas short connections
            NeuronGene srcNeuronGeneACBias = inputNeuronGeneList[0];
            if (!srcNeuronGeneACBias.TargetNeurons.Contains(outputNeuronGeneList[2].InnovationId))
            {
                NeuronGene tgtNeuronGeneAC = outputNeuronGeneList[2];
                ConnectionGene biasGene = new ConnectionGene(_innovationIdGenerator.NextId,
                                                            srcNeuronGeneACBias.InnovationId,
                                                            tgtNeuronGeneAC.InnovationId,
                                                            Math.Abs(GenerateRandomConnectionWeight()));
                connectionGeneList.Add(biasGene);

                // Register connection with endpoint neurons.
                srcNeuronGeneACBias.TargetNeurons.Add(biasGene.TargetNodeId);
                tgtNeuronGeneAC.SourceNeurons.Add(biasGene.SourceNodeId);
            }
            double conW = GenerateRandomConnectionWeight();
            for (int i = 5; i <= 6; i++)
            {
                NeuronGene srcNeuronGeneAC = inputNeuronGeneList[i];
                if (!srcNeuronGeneAC.TargetNeurons.Contains(outputNeuronGeneList[2].InnovationId))
                {
                    NeuronGene tgtNeuronGeneAC = outputNeuronGeneList[2];
                    ConnectionGene biasGene = new ConnectionGene(_innovationIdGenerator.NextId,
                                                                srcNeuronGeneAC.InnovationId,
                                                                tgtNeuronGeneAC.InnovationId,
                                                                -Math.Abs(conW));
                    connectionGeneList.Add(biasGene);

                    // Register connection with endpoint neurons.
                    srcNeuronGeneAC.TargetNeurons.Add(biasGene.TargetNodeId);
                    tgtNeuronGeneAC.SourceNeurons.Add(biasGene.SourceNodeId);
                }

                srcNeuronGeneAC = inputNeuronGeneList[i];
                if (!srcNeuronGeneAC.TargetNeurons.Contains(outputNeuronGeneList[5].InnovationId))
                {
                    NeuronGene tgtNeuronGeneAC = outputNeuronGeneList[5];
                    ConnectionGene biasGene = new ConnectionGene(_innovationIdGenerator.NextId,
                                                                srcNeuronGeneAC.InnovationId,
                                                                tgtNeuronGeneAC.InnovationId,
                                                                -Math.Abs(conW));
                    connectionGeneList.Add(biasGene);

                    // Register connection with endpoint neurons.
                    srcNeuronGeneAC.TargetNeurons.Add(biasGene.TargetNodeId);
                    tgtNeuronGeneAC.SourceNeurons.Add(biasGene.SourceNodeId);
                }
            }
            #endregion

            #region Add connection to bisas connection strength based on distance
            for (int i = 5; i <= 6; i++)
            {
                NeuronGene srcNeuronGeneAC = inputNeuronGeneList[i];
                if (!srcNeuronGeneAC.TargetNeurons.Contains(outputNeuronGeneList[0].InnovationId))
                {
                    NeuronGene tgtNeuronGeneAC = outputNeuronGeneList[0];
                    ConnectionGene biasGene = new ConnectionGene(_innovationIdGenerator.NextId,
                                                                srcNeuronGeneAC.InnovationId,
                                                                tgtNeuronGeneAC.InnovationId,
                                                                Math.Abs(GenerateRandomConnectionWeight()));
                    connectionGeneList.Add(biasGene);

                    // Register connection with endpoint neurons.
                    srcNeuronGeneAC.TargetNeurons.Add(biasGene.TargetNodeId);
                    tgtNeuronGeneAC.SourceNeurons.Add(biasGene.SourceNodeId);
                }
            }
            #endregion
            for (int i = 0; i < connectionCount; i++)
            {
                ConnectionDefinition def = connectionDefArr[i];
                NeuronGene srcNeuronGene = inputNeuronGeneList[def._sourceNeuronIdx];
                NeuronGene tgtNeuronGene = outputNeuronGeneList[def._targetNeuronIdx];

                ConnectionGene cGene = new ConnectionGene(def._innovationId,
                                                        srcNeuronGene.InnovationId,
                                                        tgtNeuronGene.InnovationId,
                                                        GenerateRandomConnectionWeight());
                if (!srcNeuronGene.TargetNeurons.Contains(cGene.TargetNodeId))
                {
                    connectionGeneList.Add(cGene);

                    // Register connection with endpoint neurons.
                    srcNeuronGene.TargetNeurons.Add(cGene.TargetNodeId);
                    tgtNeuronGene.SourceNeurons.Add(cGene.SourceNodeId);
                }
            }

            // Ensure connections are sorted.
            connectionGeneList.SortByInnovationId();

            // Create and return the completed genome object.
            return CreateGenome(_genomeIdGenerator.NextId, birthGeneration,
                                neuronGeneList, connectionGeneList,
                                _inputNeuronCount, _outputNeuronCount, false);
        }
Esempio n. 27
0
 // Schrum: Added this intermediate constructor to lead to my modified one below
 public NeatGenome(uint genomeId,
                 NeuronGeneList neuronGeneList,
                 List<ModuleGene> moduleGeneList,
                 ConnectionGeneList connectionGeneList,
                 int inputNeuronCount,
                 int outputNeuronCount)
     : this(genomeId, neuronGeneList, moduleGeneList, connectionGeneList, inputNeuronCount, outputNeuronCount, outputNeuronCount) { }
        // NOTE: Multi-Plane Substrates ARE MAYBE supported by this method!
        private NeatGenome.NeatGenome generateHomogeneousGenome(INetwork network, bool normalizeWeights, bool  adaptiveNetwork,bool  modulatoryNet)
        {
            IActivationFunction activationFunction = HyperNEATParameters.substrateActivationFunction;
            ConnectionGeneList connections = new ConnectionGeneList((int)((InputCount * HiddenCount) + (HiddenCount * OutputCount)));
            float[] coordinates = new float[4]; //JUSTIN: CHANGE THIS BACK TO [4]!!!
            float output;
            uint connectionCounter = 0;
            int iterations = 2 * (network.TotalNeuronCount - (network.InputNeuronCount + network.OutputNeuronCount)) + 1;

            uint totalOutputCount = OutputCount;
            uint totalInputCount = InputCount;
            uint totalHiddenCount = HiddenCount;

            uint sourceCount, targetCout;
            double weightRange = HyperNEATParameters.weightRange;
            double threshold = HyperNEATParameters.threshold;

            NeuronGeneList neurons;
            // SharpNEAT requires that the neuron list be in this order: bias|input|output|hidden
            neurons = new NeuronGeneList((int)(InputCount + OutputCount + HiddenCount));

            // set up the input nodes
            for (uint a = 0; a < totalInputCount; a++)
            {
                neurons.Add(new NeuronGene(a, NeuronType.Input, ActivationFunctionFactory.GetActivationFunction("NullFn")));
            }
            // set up the output nodes
            for (uint a = 0; a < totalOutputCount; a++)
            {

                neurons.Add(new NeuronGene(a + InputCount, NeuronType.Output, activationFunction));
            }
            // set up the hidden nodes
            for (uint a = 0; a < totalHiddenCount; a++)
            {
                neurons.Add(new NeuronGene(a + InputCount + OutputCount, NeuronType.Hidden, activationFunction));
            }

            // CPPN Outputs: [ Weights ] [ Biases ]
            // When using multi-plane substrates, there will be multiple Weight and Bias outputs.
            // There is a Weight output for every plane-to-plane connection (including a plane connected to itself, as in regular substrates)
            // There is a Bias output for every plane
            // Since "regular substrates" only have 1 plane, they only have 1 Weight and 1 Bias output. MP substrates have more. :)
            int numPlanes = planes.Count;
            int numPlaneConnections = planesConnected.Count;
            int computedIndex;

            uint sourceID = uint.MaxValue, targetID = uint.MaxValue;
            NeuronGroup connectedNG;

            foreach (NeuronGroup ng in neuronGroups)
            {
                foreach (uint connectedTo in ng.ConnectedTo)
                {
                    connectedNG = getNeuronGroup(connectedTo);

                    sourceCount = 0;
                    foreach (PointF source in ng.NeuronPositions)
                    {

                        //-----------------Get the bias of the source node
                        /*switch (ng.GroupType)
                        {
                            case 0: sourceID = ng.GlobalID + sourceCount; break;                             //Input
                            case 1: sourceID = totalInputCount + ng.GlobalID + sourceCount; break;                //Output
                            case 2: sourceID = totalInputCount + totalOutputCount + ng.GlobalID + sourceCount; break;  //Hidden
                        }
                        coordinates[0] = source.X; coordinates[1] = source.Y; coordinates[2] = 0.0f; coordinates[3] = 0.0f;

                        network.ClearSignals();
                        network.SetInputSignals(coordinates);
                        network.RecursiveActivation();//network.MultipleSteps(iterations);

                        neurons[(int)sourceID].Bias = (float)(network.GetOutputSignal(1) * weightRange);
                        //*///----------------------------

                        targetCout = 0;
                        foreach (PointF target in connectedNG.NeuronPositions)
                        {
                            switch (ng.GroupType)
                            {
                                case 0: sourceID = ng.GlobalID + sourceCount; break;                             //Input
                                case 1: sourceID = totalInputCount + ng.GlobalID + sourceCount; break;                //Output
                                case 2: sourceID = totalInputCount + totalOutputCount + ng.GlobalID + sourceCount; break;  //Hidden
                            }

                            switch (connectedNG.GroupType)
                            {
                                case 0: targetID = connectedNG.GlobalID + targetCout; break;
                                case 1: targetID = totalInputCount + connectedNG.GlobalID + targetCout; break;
                                case 2: targetID = totalInputCount + totalOutputCount + connectedNG.GlobalID + targetCout; break;
                            }

                            //-----------------Get the bias of the target node
                            coordinates[0] = target.X; coordinates[1] = target.Y; coordinates[2] = 0.0f; coordinates[3] = 0.0f;
                            //coordinates[4] = 0.0f; coordinates[5] = 0.0f; //JUSTIN: REMOVE THIS!!!
                            //String s = arrayToString(coordinates);
                            //if (weights.ContainsKey(s))
                            //    neurons[(int)targetID].Bias = weights[s];
                            //else
                            {
                                network.ClearSignals();
                                network.SetInputSignals(coordinates);
                                network.RecursiveActivation();//network.MultipleSteps(iterations);
                                computedIndex = numPlaneConnections + planes.IndexOf(connectedNG.Plane);
                                //neurons[(int)targetID].Bias = (float)(network.GetOutputSignal(1) * weightRange);
                                neurons[(int)targetID].Bias = (float)(network.GetOutputSignal(computedIndex) * weightRange);
                                //weights.Add(s,neurons[(int)targetID].Bias);
                            }
                            //----------------------------

                            coordinates[0] = source.X;
                            coordinates[1] = source.Y;
                            coordinates[2] = target.X;
                            coordinates[3] = target.Y;
                            //coordinates[4] = source.X - target.X; coordinates[5] = source.Y - target.Y; //JUSTIN: REMOVE THIS!!!

                            network.ClearSignals();
                            network.SetInputSignals(coordinates);
                            network.RecursiveActivation();//network.MultipleSteps(iterations);
                            computedIndex = indexOfPlaneConnection(ng.Plane, connectedNG.Plane);
                            //output = network.GetOutputSignal(0);
                            output = network.GetOutputSignal(computedIndex);

                            if (Math.Abs(output) > threshold)
                            {
                                float weight = (float)(((Math.Abs(output) - (threshold)) / (1 - threshold)) * weightRange * Math.Sign(output));
                                connections.Add(new ConnectionGene(connectionCounter++, sourceID, targetID, weight, ref coordinates));
                            }
                            //else
                            //{
                            //    Console.WriteLine("Not connected");
                            //}
                            targetCout++;
                        }
                        sourceCount++;
                    }
                }
            }
            if (normalizeWeights)
            {
                normalizeWeightConnections(ref connections, neurons.Count);
            }
            NeatGenome.NeatGenome gn = new SharpNeatLib.NeatGenome.NeatGenome(0, neurons, connections, (int)(totalInputCount), (int)(totalOutputCount));

            gn.networkAdaptable = adaptiveNetwork;
            gn.networkModulatory = modulatoryNet;
            return gn;
        }
        public NeatGenome.NeatGenome generateMultiGenomeStack(INetwork network, List<float> stackCoordinates, bool normalizeWeights, bool adaptiveNetwork, bool modulatoryNet, bool dirComm)
        {
            uint numberOfAgents = (uint)stackCoordinates.Count;
            IActivationFunction activationFunction = HyperNEATParameters.substrateActivationFunction;
            ConnectionGeneList connections = new ConnectionGeneList((int)(numberOfAgents * (InputCount * HiddenCount) + numberOfAgents * (HiddenCount * OutputCount) +
                numberOfAgents * (ReceiveCount * HiddenCount) + numberOfAgents * (HiddenCount * TransCount)));
            float[] coordinates = new float[5];
            float output;
            uint connectionCounter = 0;
            float agentDelta = 2.0f / (numberOfAgents - 1);
            int iterations = 2 * (network.TotalNeuronCount - (network.InputNeuronCount + network.OutputNeuronCount)) + 1;

            uint totalOutputCount = OutputCount * numberOfAgents;
            uint totalInputCount = InputCount * numberOfAgents;
            uint totalHiddenCount = HiddenCount * numberOfAgents;
            uint totalTransCount = TransCount * numberOfAgents;
            uint totalReceiveCount = ReceiveCount * numberOfAgents;

            uint sourceCount, targetCout;
            double weightRange = HyperNEATParameters.weightRange;
            double threshold = HyperNEATParameters.threshold;

            NeuronGeneList neurons;
            // SharpNEAT requires that the neuron list be in this order: bias|input|output|hidden|receive|transmit
            neurons = new NeuronGeneList((int)(InputCount * numberOfAgents + OutputCount * numberOfAgents + HiddenCount * numberOfAgents + ReceiveCount * numberOfAgents + TransCount * numberOfAgents));

            // set up the input nodes
            for (uint a = 0; a < totalInputCount; a++)
            {
                neurons.Add(new NeuronGene(a, NeuronType.Input, ActivationFunctionFactory.GetActivationFunction("NullFn")));
            }
            // set up the output nodes
            for (uint a = 0; a < totalOutputCount; a++)
            {

                neurons.Add(new NeuronGene(a + InputCount * numberOfAgents, NeuronType.Output, activationFunction));
            }
            // set up the hidden nodes
            for (uint a = 0; a < totalHiddenCount; a++)
            {
                neurons.Add(new NeuronGene(a + InputCount * numberOfAgents + OutputCount * numberOfAgents, NeuronType.Hidden, activationFunction));
            }
            // set up the receive nodes
            for (uint a = 0; a < totalReceiveCount; a++)
            {
                neurons.Add(new NeuronGene(a + InputCount * numberOfAgents + OutputCount * numberOfAgents + HiddenCount * numberOfAgents, NeuronType.Receive, ActivationFunctionFactory.GetActivationFunction("NullFn")));
            }
            // set up the transmit nodes
            for (uint a = 0; a < totalTransCount; a++)
            {
                neurons.Add(new NeuronGene(a + InputCount * numberOfAgents + OutputCount * numberOfAgents + HiddenCount * numberOfAgents + ReceiveCount * numberOfAgents, NeuronType.Transmit, activationFunction));
            }

            bool[] biasCalculated = new bool[totalHiddenCount + totalOutputCount + totalInputCount + totalReceiveCount + totalTransCount];

            uint agent = 0;
            float A = 0.0f, B = 0.0f, C = 0.0f, D = 0.0f, learningRate = 0.0f, modConnection;

            foreach (float stackCoordinate in stackCoordinates)
            {
                coordinates[4] = stackCoordinate;
                uint sourceID = uint.MaxValue, targetID = uint.MaxValue;
                NeuronGroup connectedNG;

                foreach (NeuronGroup ng in neuronGroups)
                {
                    foreach (uint connectedTo in ng.ConnectedTo)
                    {
                        connectedNG = getNeuronGroup(connectedTo);

                        sourceCount = 0;
                        foreach (PointF source in ng.NeuronPositions)
                        {

                            targetCout = 0;
                            foreach (PointF target in connectedNG.NeuronPositions)
                            {
                                switch (ng.GroupType)
                                {
                                    case 0: sourceID = (agent * InputCount) + ng.GlobalID + sourceCount; break;                             //Input
                                    case 1: sourceID = totalInputCount + (agent * OutputCount) + ng.GlobalID + sourceCount; break;                //Output
                                    case 2: sourceID = totalInputCount + totalOutputCount + (agent * HiddenCount) + ng.GlobalID + sourceCount; break;  //Hidden
                                    case 3: sourceID = totalInputCount + totalOutputCount + totalHiddenCount + (agent * ReceiveCount) + ng.GlobalID + sourceCount; break; //Receive
                                    case 4: sourceID = totalInputCount + totalOutputCount + totalHiddenCount + totalReceiveCount + (agent * TransCount) + ng.GlobalID + sourceCount; break; //Transmit
                                }

                                switch (connectedNG.GroupType)
                                {
                                    case 0: targetID = (agent * InputCount) + connectedNG.GlobalID + targetCout; break;
                                    case 1: targetID = totalInputCount + (agent * OutputCount) + connectedNG.GlobalID + targetCout; break;
                                    case 2: targetID = totalInputCount + totalOutputCount + (agent * HiddenCount) + connectedNG.GlobalID + targetCout; break;
                                    case 3: targetID = totalInputCount + totalOutputCount + totalHiddenCount + (agent * ReceiveCount) + connectedNG.GlobalID + targetCout; break;
                                    case 4: targetID = totalInputCount + totalOutputCount + totalHiddenCount + totalReceiveCount + (agent * TransCount) + connectedNG.GlobalID + targetCout; break;
                                }

                                //target node bias
                                if (!biasCalculated[targetID])
                                {
                                    coordinates[0] = 0.0f; coordinates[1] = 0.0f; coordinates[2] = target.X; coordinates[3] = target.Y;

                                    network.ClearSignals();
                                    network.SetInputSignals(coordinates);
                                    ((ModularNetwork)network).RecursiveActivation();
                                    neurons[(int)targetID].Bias = (float)(network.GetOutputSignal(1) * weightRange);
                                    biasCalculated[targetID] = true;
                                }

                                coordinates[0] = source.X;
                                coordinates[1] = source.Y;
                                coordinates[2] = target.X;
                                coordinates[3] = target.Y;

                                network.ClearSignals();
                                network.SetInputSignals(coordinates);
                                ((ModularNetwork)network).RecursiveActivation();
                                //network.MultipleSteps(iterations);
                                output = network.GetOutputSignal(0);

                                double leo = 0.0;

                                if (adaptiveNetwork)
                                {
                                    A = network.GetOutputSignal(2);
                                    B = network.GetOutputSignal(3);
                                    C = network.GetOutputSignal(4);
                                    D = network.GetOutputSignal(5);
                                    learningRate = network.GetOutputSignal(6);
                                }

                                if (modulatoryNet)
                                {
                                    modConnection = network.GetOutputSignal(7);
                                }
                                else
                                {
                                    modConnection = 0.0f;
                                }

                                if (useLeo)
                                {
                                    threshold = 0.0;
                                    leo = network.GetOutputSignal(2);
                                }

                                if (!useLeo || leo > 0.0)
                                    if (Math.Abs(output) > threshold)
                                    {
                                        float weight = (float)(((Math.Abs(output) - (threshold)) / (1 - threshold)) * weightRange * Math.Sign(output));
                                        //if (adaptiveNetwork)
                                        //{
                                        //    //If adaptive network set weight to small value
                                        //    weight = 0.1f;
                                        //}
                                        connections.Add(new ConnectionGene(connectionCounter++, sourceID, targetID, weight, ref coordinates, A, B, C, D, modConnection, learningRate));
                                    }
                                //else
                                //{
                                //    Console.WriteLine("Not connected");
                                //}
                                targetCout++;
                            }
                            sourceCount++;
                        }
                    }
                }
                agent++;
            }

            if (normalizeWeights)
            {
                normalizeWeightConnections(ref connections, neurons.Count);
            }

            //Add Direct Communication connections
            if (dirComm)
            {
                uint numConnected = ReceiveCount / TransCount;
                agent = 0;

                foreach (float stackCoordinate in stackCoordinates)
                {
                    SortedList<float, uint> closestAgents = new SortedList<float, uint>();
                    uint i = 0;
                    foreach (float otherCoordinate in stackCoordinates)
                    {
                        if (i == agent) continue;
                        float delta = Math.Abs(stackCoordinate - otherCoordinate);
                        closestAgents.Add(delta, i);
                        i++;
                    }
                    uint[] orderedAgents = new uint[numberOfAgents];
                    closestAgents.Values.CopyTo(orderedAgents, 0);
                    uint[] connectedAgents = new uint[numConnected];
                    for (uint j = 0; j < numConnected; j++)
                    {
                        connectedAgents[j] = orderedAgents[j];
                    }

                    foreach (NeuronGroup ng in neuronGroups)
                    {
                        if (ng.GroupType != 4) continue;
                        sourceCount = 0;
                        foreach (PointF source in ng.NeuronPositions)
                        {
                            uint sourceID = totalInputCount + totalOutputCount + totalHiddenCount + totalReceiveCount + (agent * TransCount) + ng.GlobalID + sourceCount;

                            foreach (uint connectedAgent in connectedAgents)
                            {
                                uint targetID = totalInputCount + totalOutputCount + totalHiddenCount + (connectedAgent * ReceiveCount) + (ng.GlobalID * numConnected) + agent;

                                connections.Add(new ConnectionGene(connectionCounter++, sourceID, targetID, 1.0));
                            }

                            sourceCount++;
                        }
                    }

                    agent++;
                }

            }

            SharpNeatLib.NeatGenome.NeatGenome sng = new SharpNeatLib.NeatGenome.NeatGenome(0, neurons, connections, (int)(totalInputCount), (int)(totalOutputCount));
            sng.networkAdaptable = adaptiveNetwork;
            sng.networkModulatory = modulatoryNet;
            return sng;
        }
Esempio n. 30
0
		/// <summary>
		/// Create a default minimal genome that describes a NN with the given number of inputs and outputs.
		/// </summary>
		/// <returns></returns>
		public static IGenome CreateGenome(NeatParameters neatParameters, IdGenerator idGenerator, int inputNeuronCount, int outputNeuronCount, int outputsPerPolicy, float connectionProportion)
		{
            IActivationFunction actFunct;
			NeuronGene neuronGene; // temp variable.
			NeuronGeneList inputNeuronGeneList = new NeuronGeneList(); // includes bias neuron.
			NeuronGeneList outputNeuronGeneList = new NeuronGeneList();
			NeuronGeneList neuronGeneList = new NeuronGeneList();
			ConnectionGeneList connectionGeneList = new ConnectionGeneList();

			// IMPORTANT NOTE: The neurons must all be created prior to any connections. That way all of the genomes
			// will obtain the same innovation ID's for the bias,input and output nodes in the initial population.
			// Create a single bias neuron.
            //TODO: DAVID proper activation function change to NULL?
            actFunct = ActivationFunctionFactory.GetActivationFunction("NullFn");
            //neuronGene = new NeuronGene(idGenerator.NextInnovationId, NeuronType.Bias, actFunct);
            neuronGene = new NeuronGene(null, idGenerator.NextInnovationId, NeuronGene.INPUT_LAYER, NeuronType.Bias, actFunct);
			inputNeuronGeneList.Add(neuronGene);
			neuronGeneList.Add(neuronGene);

			// Create input neuron genes.
            actFunct = ActivationFunctionFactory.GetActivationFunction("NullFn");
			for(int i=0; i<inputNeuronCount; i++)
			{
                //TODO: DAVID proper activation function change to NULL?
                //neuronGene = new NeuronGene(idGenerator.NextInnovationId, NeuronType.Input, actFunct);
                neuronGene = new NeuronGene(null, idGenerator.NextInnovationId, NeuronGene.INPUT_LAYER, NeuronType.Input, actFunct);
				inputNeuronGeneList.Add(neuronGene);
				neuronGeneList.Add(neuronGene);
			}

			// Create output neuron genes. 
            //actFunct = ActivationFunctionFactory.GetActivationFunction("NullFn");
			for(int i=0; i<outputNeuronCount; i++)
			{
                actFunct = ActivationFunctionFactory.GetActivationFunction("BipolarSigmoid");
                //actFunct = ActivationFunctionFactory.GetRandomActivationFunction(neatParameters);
                //TODO: DAVID proper activation function
                //neuronGene = new NeuronGene(idGenerator.NextInnovationId, NeuronType.Output, actFunct);
                neuronGene = new NeuronGene(null, idGenerator.NextInnovationId, NeuronGene.OUTPUT_LAYER, NeuronType.Output, actFunct);
				outputNeuronGeneList.Add(neuronGene);
				neuronGeneList.Add(neuronGene);
			}

			// Loop over all possible connections from input to output nodes and create a number of connections based upon
			// connectionProportion.
			foreach(NeuronGene targetNeuronGene in outputNeuronGeneList)
			{
				foreach(NeuronGene sourceNeuronGene in inputNeuronGeneList)
				{
					// Always generate an ID even if we aren't going to use it. This is necessary to ensure connections
					// between the same neurons always have the same ID throughout the generated population.
					uint connectionInnovationId = idGenerator.NextInnovationId;

					if(Utilities.NextDouble() < connectionProportion)
					{	// Ok lets create a connection.
						connectionGeneList.Add(	new ConnectionGene(connectionInnovationId, 
							sourceNeuronGene.InnovationId,
							targetNeuronGene.InnovationId,
							(Utilities.NextDouble() * neatParameters.connectionWeightRange ) - neatParameters.connectionWeightRange/2.0));  // Weight 0 +-5
					}
				}
			}

            // Don't create any hidden nodes at this point. Fundamental to the NEAT way is to start minimally!
            // Schrum: Added outputsPerPolicy: If outputsPerPolicy == outputNeuronCount, then behaves like default NEAT
            return new NeatGenome(idGenerator.NextGenomeId, neuronGeneList, connectionGeneList, inputNeuronCount, outputNeuronCount, outputsPerPolicy);
		}
        private NeatGenome.NeatGenome generateHomogeneousGenomeES(INetwork network, bool normalizeWeights, bool adaptiveNetwork, bool modulatoryNet)
        {
            List<PointF> hiddenNeuronPositions = new List<PointF>();

            IActivationFunction activationFunction = HyperNEATParameters.substrateActivationFunction;
            ConnectionGeneList connections = new ConnectionGeneList();//(int)((InputCount * HiddenCount) + (HiddenCount * OutputCount)));

            List<PointF> outputNeuronPositions = getNeuronGroupByType(1);
            List<PointF> inputNeuronPositions = getNeuronGroupByType(0);

            EvolvableSubstrate se = new EvolvableSubstrate();

            se.generateConnections(inputNeuronPositions, outputNeuronPositions, network,
                HyperNEATParameters.initialRes,
                (float)HyperNEATParameters.varianceThreshold,
                (float)HyperNEATParameters.bandingThreshold,
                (int)HyperNEATParameters.ESIterations,
                (float)HyperNEATParameters.divisionThreshold,
                HyperNEATParameters.maximumRes,
                InputCount, OutputCount, -1.0f, -1.0f, 1.0f, 1.0f, ref connections, ref hiddenNeuronPositions);

            HiddenCount = (uint)hiddenNeuronPositions.Count;

            float[] coordinates = new float[5];
            uint connectionCounter = (uint)connections.Count;

            NeuronGeneList neurons;
            // SharpNEAT requires that the neuron list be in this order: bias|input|output|hidden
            neurons = new NeuronGeneList((int)(InputCount + OutputCount + HiddenCount));

            // set up the input nodes
            for (uint a = 0; a < InputCount; a++)
            {
                neurons.Add(new NeuronGene(a, NeuronType.Input, ActivationFunctionFactory.GetActivationFunction("NullFn")));
            }

            // set up the output nodes
            for (uint a = 0; a < OutputCount; a++)
            {

                neurons.Add(new NeuronGene(a + InputCount, NeuronType.Output, activationFunction));

            }
            // set up the hidden nodes
            for (uint a = 0; a < HiddenCount; a++)
            {
                neurons.Add(new NeuronGene(a + InputCount + OutputCount, NeuronType.Hidden, activationFunction));
            }

            bool[] visited = new bool[neurons.Count];
            List<uint> nodeList = new List<uint>();
            bool[] connectedToInput = new bool[neurons.Count];

            bool[] isOutput = new bool[neurons.Count];

            bool danglingConnection = true;

            while (danglingConnection)
            {
                bool[] hasIncomming = new bool[neurons.Count];

                foreach (ConnectionGene co in connections)
                {
                    //  if (co.SourceNeuronId != co.TargetNeuronId)
                    // {
                    hasIncomming[co.TargetNeuronId] = true;
                    // }
                }
                for (int i = 0; i < InputCount; i++)
                    hasIncomming[i] = true;

                bool[] hasOutgoing = new bool[neurons.Count];
                foreach (ConnectionGene co in connections)
                {
                    //  if (co.TargetNeuronId != co.SourceNeuronId)
                    //  {
                    if (co.TargetNeuronId != co.SourceNeuronId)  //neurons that only connect to themselfs don't count
                    {
                        hasOutgoing[co.SourceNeuronId] = true;
                    }
                    //  }
                }

                //Keep  output neurons
                for (int i = 0; i < OutputCount; i++)
                    hasOutgoing[i + InputCount] = true;

                danglingConnection = false;
                //Check if there are still dangling connections
                foreach (ConnectionGene co in connections)
                {
                    if (!hasOutgoing[co.TargetNeuronId] || !hasIncomming[co.SourceNeuronId])
                    {
                        danglingConnection = true;
                        break;
                    }
                }

                connections.RemoveAll(delegate(ConnectionGene m) { return (!hasIncomming[m.SourceNeuronId]); });
                connections.RemoveAll(delegate(ConnectionGene m) { return (!hasOutgoing[m.TargetNeuronId]); });
            }

            if (normalizeWeights)
            {
                normalizeWeightConnections(ref connections, neurons.Count);
            }

            SharpNeatLib.NeatGenome.NeatGenome gn = new SharpNeatLib.NeatGenome.NeatGenome(0, neurons, connections, (int)(InputCount), (int)(OutputCount));
            //     SharpNeatLib.NeatGenome.NeatGenome sng = new SharpNeatLib.NeatGenome.NeatGenome(0, neurons, connections, (int)(totalInputCount), (int)(totalOutputCount));

            gn.networkAdaptable = adaptiveNetwork;
            gn.networkModulatory = modulatoryNet;

            return gn;
        }
        // MPS NOT supported by this method
        private NeatGenome.NeatGenome generateMultiGenomeStackES(INetwork network, List<float> stackCoordinates, bool normalizeWeights, bool adaptiveNetwork, bool modulatoryNet)
        {
            if (useMultiPlaneSubstrate) throw new Exception("MPS not implemented for these parameters");
            uint numberOfAgents = (uint)stackCoordinates.Count;
            IActivationFunction activationFunction = HyperNEATParameters.substrateActivationFunction;
            ConnectionGeneList connections = new ConnectionGeneList((int)(numberOfAgents * (InputCount * HiddenCount) + numberOfAgents * (HiddenCount * OutputCount)));
            float[] coordinates = new float[5];
            float output;
            uint connectionCounter = 0;
            float agentDelta = 2.0f / (numberOfAgents - 1);
            int iterations = 2 * (network.TotalNeuronCount - (network.InputNeuronCount + network.OutputNeuronCount)) + 1;

            uint totalOutputCount = OutputCount * numberOfAgents;
            uint totalInputCount = InputCount * numberOfAgents;
            uint totalHiddenCount = HiddenCount * numberOfAgents;

            uint sourceCount, targetCout;
            double weightRange = HyperNEATParameters.weightRange;
            double threshold = HyperNEATParameters.threshold;

            NeuronGeneList neurons;
            // SharpNEAT requires that the neuron list be in this order: bias|input|output|hidden
            neurons = new NeuronGeneList((int)(InputCount * numberOfAgents + OutputCount * numberOfAgents + HiddenCount * numberOfAgents));

            // set up the input nodes
            for (uint a = 0; a < totalInputCount; a++)
            {
                neurons.Add(new NeuronGene(a, NeuronType.Input, ActivationFunctionFactory.GetActivationFunction("NullFn")));
            }
            // set up the output nodes
            for (uint a = 0; a < totalOutputCount; a++)
            {

                neurons.Add(new NeuronGene(a + InputCount * numberOfAgents, NeuronType.Output, activationFunction));
            }


            uint agent = 0;
            float A = 0.0f, B = 0.0f, C = 0.0f, D = 0.0f, learningRate = 0.0f, modConnection;


            List<PointF> outputNeuronPositions = getNeuronGroupByType(1);
            List<PointF> inputNeuronPositions = getNeuronGroupByType(0);

            uint hiddenCount = 0;

            foreach (float stackCoordinate in stackCoordinates)
            {
                List<PointF> hiddenNeuronPositions = new List<PointF>();
                ConnectionGeneList con = new ConnectionGeneList();
                SubstrateEvolution se = new SubstrateEvolution();
                se.generateConnections(inputNeuronPositions, outputNeuronPositions, network,
                    SubstrateEvolution.SAMPLE_WIDTH,
                    SubstrateEvolution.SAMPLE_TRESHOLD,
                    SubstrateEvolution.NEIGHBOR_LEVEL,
                    SubstrateEvolution.INCREASE_RESSOLUTION_THRESHOLD,
                    SubstrateEvolution.MIN_DISTANCE,
                    SubstrateEvolution.CONNECTION_TRESHOLD, //0.4. ConnectionThreshold
                    InputCount, OutputCount, -1.0f, -1.0f, 1.0f, 1.0f, ref con, ref hiddenNeuronPositions, stackCoordinate);

                // set up the hidden nodes
                for (uint a = 0; a < hiddenNeuronPositions.Count; a++)
                {
                    neurons.Add(new NeuronGene(hiddenCount + a + totalInputCount + totalOutputCount, NeuronType.Hidden, activationFunction));
                }



                foreach (ConnectionGene c in con)
                {
                    if (c.SourceNeuronId < InputCount)
                    {
                        c.SourceNeuronId += agent * InputCount;
                    }
                    else if (c.SourceNeuronId < InputCount + OutputCount)
                    {
                        c.SourceNeuronId = (c.SourceNeuronId - InputCount) + totalInputCount + agent * OutputCount;
                    }
                    else
                    {
                        c.SourceNeuronId = (uint)((c.SourceNeuronId - InputCount - OutputCount) + totalInputCount + totalOutputCount + hiddenCount);
                    }

                    if (c.TargetNeuronId < InputCount)
                    {
                        c.TargetNeuronId += agent * InputCount;
                    }
                    else if (c.TargetNeuronId < InputCount + OutputCount)
                    {
                        c.TargetNeuronId = (c.TargetNeuronId - InputCount) + totalInputCount + agent * OutputCount;
                    }
                    else
                    {
                        c.TargetNeuronId = (uint)((c.TargetNeuronId - InputCount - OutputCount) + totalInputCount + totalOutputCount + hiddenCount);
                    }

                    connections.Add(new ConnectionGene(connectionCounter++, c.SourceNeuronId, c.TargetNeuronId, c.Weight, ref c.coordinates));

                }
                hiddenCount += (uint)hiddenNeuronPositions.Count;
                agent++;

            }
            if (normalizeWeights)
            {
                normalizeWeightConnections(ref connections, neurons.Count);
            }
            SharpNeatLib.NeatGenome.NeatGenome sng = new SharpNeatLib.NeatGenome.NeatGenome(0, neurons, connections, (int)(totalInputCount), (int)(totalOutputCount));
            sng.networkAdaptable = adaptiveNetwork;
            sng.networkModulatory = modulatoryNet;
            return sng;
        }