Beispiel #1
0
    private NEAT BreedChild(int speciesIndex)
    {
        if (NeatEvolverData.species[speciesIndex].networks.Count <= 1)
        {
            return(new NEAT(NeatEvolverData.species[speciesIndex].networks[0]));
        }

        int rand1 = Random.Range(0, NeatEvolverData.species[speciesIndex].networks.Count);
        int rand2 = Random.Range(0, NeatEvolverData.species[speciesIndex].networks.Count);

        while (rand1 == rand2 && NeatEvolverData.species[speciesIndex].networks.Count > 1)
        {
            rand2 = Random.Range(0, NeatEvolverData.species[speciesIndex].networks.Count);
        }

        NEAT parentA = NeatEvolverData.species[speciesIndex].networks[rand1];
        NEAT parentB = NeatEvolverData.species[speciesIndex].networks[rand2];

        if (parentA.GetFitness() >= parentB.GetFitness())
        {
            return(Crossover(parentA, parentB));
        }

        return(Crossover(parentB, parentA));
    }
Beispiel #2
0
    private void MutateGenom(NEAT network)
    {
        float currentRate = linkMutateRate;

        if (Random.Range(0, 100) < currentRate)
        {
            network.LinkMutate();
        }

        currentRate = nodeMutateRate;
        if (Random.Range(0, 100) < currentRate)
        {
            network.NodeMutate();
        }

        currentRate = disableEnableMutateRate;
        if (Random.Range(0, 100) < currentRate)
        {
            network.DisableMutate();
        }

        currentRate = pointMutateAmount;
        while (currentRate > 0)
        {
            if (Random.Range(0, 100) < currentRate)
            {
                network.PointMutate(pointMutateAmount);
            }

            currentRate--;
        }
    }
Beispiel #3
0
 public NEAT(NEAT network)
 {
     genom         = new Genom(network.genom);
     inputLength   = network.inputLength;
     outputsLength = network.outputsLength;
     species       = network.species;
 }
Beispiel #4
0
 private void SetAgent(NEAT network)
 {
     currentAgent.SetNEAT(network);
     uiDrawer.DrawNetwork(network);
     uiData.UpdateSpec(NeatEvolverData.currentSpecies + 1);
     uiData.UpdateGenom(NeatEvolverData.currenGene);
     uiData.UpdateFit(network.GetFitness());
 }
Beispiel #5
0
 public void CheckIfBestNetwork(NEAT network)
 {
     if (network.GetFitness() > NeatEvolverData.bestFitness)
     {
         NeatEvolverData.bestFitness = network.GetFitness();
         NeatEvolverData.currentBest = new NEAT(network);
         uiData.UpdateBestFit(NeatEvolverData.bestFitness);
     }
 }
Beispiel #6
0
        /// <summary>
        /// Constructs a Genome with the given NEAT.
        /// </summary>
        /// <param name="neat">The NEAT this Genome is a part of.</param>
        /// <param name="capacity">The capacity of the Genome.</param>
        public Genome(NEAT neat, int capacity, Random random)
        {
            Connections = new RandomHashSet <ConnectionGene>(capacity);
            Nodes       = new RandomHashSet <NodeGene>(capacity);

            NEAT = neat;

            this.random = random;
        }
Beispiel #7
0
        /// <summary>
        /// Constructs a Genome with the given NEAT.
        /// </summary>
        /// <param name="neat">The NEAT this Genome is a part of.</param>
        public Genome(NEAT neat)
        {
            Connections = new RandomHashSet <ConnectionGene>();
            Nodes       = new RandomHashSet <NodeGene>();

            NEAT = neat;

            random = new Random();
        }
Beispiel #8
0
    public void DrawNetwork(NEAT network)
    {
        List <Node>       nodes       = network.GetNodeGenom();
        List <Connection> connections = network.GetConnetionGenom();

        Dictionary <int, List <Node> > table = new Dictionary <int, List <Node> >();

        linePositions = new Dictionary <LineRenderer, Connection>();
        nodeToTrans   = new Dictionary <int, RectTransform>();

        int lastOrder = CalculateLargestOrder(nodes);

        for (int i = 0; i <= lastOrder; i++)
        {
            table.Add(i, new List <Node>());
        }

        table.Add(lastOrder + 1, new List <Node>());

        foreach (var node in nodes)
        {
            if (node.nodeType != NodeType.Output)
            {
                table[node.order].Add(node);
            }
            else
            {
                table[lastOrder + 1].Add(node);
            }
        }

        for (int i = 0; i < table.Count; i++)
        {
            table[i].Sort(delegate(Node a, Node b) {
                return(a.nodeID.CompareTo(b.nodeID));
            });
        }

        for (int i = 0; i <= lastOrder + 1; i++)
        {
            for (int j = 0; j < table[i].Count; j++)
            {
                CreateNode(new Vector2(i * ((panelBounds.x - bounds.x * 2) / (lastOrder + 1)), j * ((panelBounds.y - bounds.y * 1.5f) / table[i].Count)), table[i][j]);
            }
        }

        foreach (var connection in connections)
        {
            Vector3[] poses = new Vector3[2];
            poses[0] = cam.ScreenToWorldPoint(nodeToTrans[connection.inNode].anchoredPosition);
            poses[1] = cam.ScreenToWorldPoint(nodeToTrans[connection.inNode].anchoredPosition);
            CreateConnection(poses, connection);
        }

        draw = true;
    }
Beispiel #9
0
    public SaveBrain(NEAT neat, Vector2Int gridSize, Vector2 bucketSize, Vector2 offset)
    {
        this.gridSize    = new int[2];
        this.gridSize[0] = gridSize.x;
        this.gridSize[1] = gridSize.y;

        this.bucketSize    = new float[2];
        this.bucketSize[0] = bucketSize.x;
        this.bucketSize[1] = bucketSize.y;

        this.offset    = new float[2];
        this.offset[0] = offset.x;
        this.offset[1] = offset.y;

        innovation = neat.GetInnovation();
        inputs     = neat.GetInputSize();
        outputs    = neat.GetOutputsSize();

        List <float> tempFloatsNodes       = new List <float>();
        List <float> tempFloatsConnections = new List <float>();

        foreach (var node in neat.GetNodeGenom())
        {
            //node vars
            tempFloatsNodes.Add(node.order);
            tempFloatsNodes.Add(node.nodeID);
            tempFloatsNodes.Add((int)node.nodeType);
            tempFloatsNodes.Add(node.activation);
            tempFloatsNodes.Add(node.sum);
        }

        foreach (var connection in neat.GetConnetionGenom())
        {
            //connections vars

            tempFloatsConnections.Add(connection.inNode);
            tempFloatsConnections.Add(connection.outNode);
            tempFloatsConnections.Add(connection.weight);

            if (connection.enabled)
            {
                tempFloatsConnections.Add(1);
            }
            else
            {
                tempFloatsConnections.Add(0);
            }

            tempFloatsConnections.Add(connection.innovation);
        }

        floatNodes       = tempFloatsNodes.ToArray();
        floatConnections = tempFloatsConnections.ToArray();
    }
Beispiel #10
0
    private int CompareGenomToSpecies(NEAT network)
    {
        foreach (var specie in NeatEvolverData.species)
        {
            if (CompareGenes(specie.networks[0], network) <= speciesSepartor)
            {
                return(NeatEvolverData.species.FindIndex(x => x == specie));
            }
        }

        return(-1);
    }
Beispiel #11
0
    private NEAT Crossover(NEAT dominant, NEAT submissive)
    {
        NEAT child = new NEAT(dominant);

        List <Connection> newConnections = new List <Connection>();

        foreach (var connection in child.GetConnetionGenom())
        {
            Connection c = submissive.GetConnetionGenom().Find(x => x.innovation == connection.innovation);

            if (c != null && Random.Range(0f, 1f) > 0.5f)
            {
                Node inNode  = child.GetNodeGenom().Find(n => n.nodeID == c.inNode);
                Node outNode = child.GetNodeGenom().Find(n => n.nodeID == c.outNode);

                if (outNode == null && inNode != null)
                {
                    outNode = new Node(c.outNode, inNode.order + 1, NodeType.Hidden);
                    child.AddNode(outNode);
                }
                else if (outNode == null && inNode == null)
                {
                    outNode = new Node(c.outNode, 1, NodeType.Hidden);
                    child.AddNode(outNode);
                }

                if (inNode == null)
                {
                    inNode = new Node(c.inNode, 0, NodeType.Hidden);
                    child.AddNode(inNode);
                }

                Connection cNew = new Connection(inNode.nodeID, outNode.nodeID, c.weight, c.enabled, c.innovation);

                newConnections.Add(cNew);
            }
        }

        foreach (var connection in newConnections)
        {
            if (!CompareConnection(connection, child))
            {
                if (!LoopSearch(connection, child.GetConnetionGenom()))
                {
                    child.RemoveConnection(child.GetConnetionGenom().Find(n => n.innovation == connection.innovation));
                    child.AddConnection(connection);
                    child.GetNodeGenom().Find(n => n.nodeID == connection.inNode).AddConnection(connection);
                }
            }
        }
        return(child);
    }
Beispiel #12
0
    private bool CompareConnection(Connection connection, NEAT child)
    {
        int size = child.GetConnetionGenom().Count;

        for (int i = 0; i < size; i++)
        {
            if (child.GetConnectionGene(i).CompareConnection(connection.inNode, connection.outNode))
            {
                return(true);
            }
        }

        return(false);
    }
Beispiel #13
0
    private NEAT CompareToGenes(NEAT network)
    {
        for (int i = 0; i < NeatEvolverData.NEATpool.Count; i++)
        {
            if (!NeatEvolverData.NEATpool[i].species && NeatEvolverData.NEATpool[i] != network)
            {
                if (CompareGenes(network, NeatEvolverData.NEATpool[i]) <= speciesSepartor)
                {
                    return(NeatEvolverData.NEATpool[i]);
                }
            }
        }

        return(null);
    }
Beispiel #14
0
    private void AddSpecies()
    {
        for (int i = 0; i < NeatEvolverData.NEATpool.Count; i++)
        {
            NEAT current = NeatEvolverData.NEATpool[i];

            if (current.species)
            {
                continue;
            }

            int speciesMatch = CompareGenomToSpecies(current);

            if (speciesMatch == -1)
            {
                NEAT match = CompareToGenes(current);

                if (match != null)
                {
                    Species s1 = new Species();
                    s1.networks = new List <NEAT> {
                        current, match
                    };
                    NeatEvolverData.species.Add(s1);
                    current.species = true;
                    match.species   = true;
                    continue;
                }

                Species s = new Species();
                s.networks = new List <NEAT> {
                    current
                };
                NeatEvolverData.species.Add(s);
                current.species = true;
                continue;
            }

            NeatEvolverData.species[speciesMatch].networks.Add(current);
            current.species = true;
        }
    }
Beispiel #15
0
    private void Awake()
    {
        if (newNetowrk || brain == null)
        {
            int inputSize = gridSize.x * gridSize.y;
            NEATNetowrk = new NEAT(inputSize, outputs);
        }
        else
        {
            SaveBrain saveBrain = brain.GetNEAT();
            NEATNetowrk = saveBrain.LoadBrain();
            gridSize    = new Vector2Int((int)saveBrain.gridSize[0], (int)saveBrain.gridSize[1]);
            bucketSize  = new Vector2Int((int)saveBrain.bucketSize[0], (int)saveBrain.bucketSize[1]);
            offset      = new Vector2Int((int)saveBrain.offset[0], (int)saveBrain.offset[1]);
            NEATNetowrk.DenugNEAT();
        }

        ///convert all layers to a singel one
        string[] layerNames = new string[MasksToCheck.Length];
        for (int i = 0; i < layerNames.Length; i++)
        {
            int counter      = 0;
            int currentLayer = MasksToCheck[i];

            while (currentLayer > 0)
            {
                counter++;
                currentLayer = currentLayer >> 1;
            }

            layerNames[i] = LayerMask.LayerToName(counter - 1);
        }

        combinedMask = LayerMask.GetMask(layerNames);

        maskTable = new Dictionary <LayerMask, int>();
        for (int i = 0; i < MasksToCheck.Length; i++)
        {
            maskTable.Add(MasksToCheck[i], i);
        }
    }
Beispiel #16
0
    public NEAT GetBestNetwork()
    {
        if (NeatEvolverData.currentBest == null)
        {
            int  fitness = 0;
            NEAT neat    = null;

            foreach (NEAT n in NeatEvolverData.NEATpool)
            {
                if (n.GetFitness() >= fitness)
                {
                    fitness = n.GetFitness();
                    neat    = new NEAT(n);
                }
            }

            return(neat);
        }

        return(NeatEvolverData.currentBest);
    }
Beispiel #17
0
    public NEAT LoadBrain()
    {
        NEAT network = new NEAT(0, 0);

        network.SetSize(inputs, outputs);

        //create all nodes
        for (int i = 0; i < floatNodes.Length; i += 5)
        {
            Node current = new Node((int)floatNodes[i + 1], (int)floatNodes[i], (NodeType)(int)floatNodes[i + 2]);
            current.activation = floatNodes[i + 3];
            current.sum        = floatNodes[i + 4];
            network.AddNode(current);
        }

        //create all connections
        for (int i = 0; i < floatConnections.Length; i += 5)
        {
            bool       enable  = floatConnections[i + 3] == 1 ? true : false;
            Connection current = new Connection((int)floatConnections[i], (int)floatConnections[i + 1], floatConnections[i + 2], enable, (int)floatConnections[i + 4]);
            Debug.Log(current.inNode + "Innode id, " + current.outNode + "outnode id, " + current.weight + "weight, " + current.innovation + "innovation");
            network.AddConnection(current);
        }

        //add all connections to nodes
        foreach (var connection in network.GetConnetionGenom())
        {
            Node currentNode = network.GetNodeGenom().Find(x => x.nodeID == connection.inNode);
            if (currentNode != null)
            {
                currentNode.AddConnection(connection);
            }
        }

        network.SetInnovation(innovation);

        return(network);
    }
Beispiel #18
0
    private void Start()
    {
        if (!currentAgent.newNetowrk)
        {
            gameObject.SetActive(false);
            return;
        }

        if (!NeatEvolverData.hasLoaded)
        {
            NeatEvolverData.NEATpool          = new List <NEAT>();
            NeatEvolverData.species           = new List <Species>();
            NeatEvolverData.bestFitness       = 0;
            NeatEvolverData.currentGeneration = 1;
            NeatEvolverData.timescale         = timeScale;

            for (int i = 0; i < population; i++)
            {
                NEAT newNeat = new NEAT(currentAgent.GetNetwortkInputSize(), currentAgent.GetNetworkOutputSize());
                MutateGenom(newNeat);
                NeatEvolverData.NEATpool.Add(newNeat);
            }

            NeatEvolverData.currentSpecies = 0;
            NeatEvolverData.currenGene     = 0;
            NeatEvolverData.currentBest    = new NEAT(NeatEvolverData.NEATpool[0]);
            NeatEvolverData.hasLoaded      = true;

            AddSpecies();
        }

        uiData.UpdateGen(NeatEvolverData.currentGeneration);
        uiData.UpdateBestFit(NeatEvolverData.bestFitness);

        currentSteps = 0;
        StartCoroutine(Train());
    }
Beispiel #19
0
    private float CompareGenes(NEAT networkA, NEAT networkB)
    {
        if (networkA.GetConnetionGenom().Count == 0 && networkB.GetConnetionGenom().Count == 0)
        {
            return(0);
        }

        List <Connection> connectionsA = networkA.GetConnetionGenom();
        List <Connection> connectionsB = networkB.GetConnetionGenom();

        connectionsA.Sort(delegate(Connection a, Connection b) {
            return(a.innovation.CompareTo(b.innovation));
        });

        connectionsB.Sort(delegate(Connection a, Connection b) {
            return(a.innovation.CompareTo(b.innovation));
        });

        int diff       = 0;
        int counterMax = 0;

        #region
        if (connectionsA.Count == 0 && connectionsB.Count != 0)
        {
            diff       = connectionsB.Count;
            counterMax = connectionsB[connectionsB.Count - 1].innovation;
        }
        else if (connectionsB.Count == 0 && connectionsA.Count != 0)
        {
            diff       = connectionsA.Count;
            counterMax = connectionsA[connectionsA.Count - 1].innovation;
        }
        else if (connectionsA.Count > 0 && connectionsB.Count > 0)
        {
            diff       = connectionsA[connectionsA.Count - 1].innovation - connectionsB[connectionsB.Count - 1].innovation;
            counterMax = diff < 0 ? connectionsA[connectionsA.Count - 1].innovation : connectionsB[connectionsB.Count - 1].innovation;
        }

        #endregion

        int[] result = new int[counterMax];

        for (int i = 1; i < counterMax; i++)
        {
            Connection A = connectionsA.Find(x => x.innovation == i);
            Connection B = connectionsB.Find(x => x.innovation == i);
            if (A != null && B != null)
            {
                result[i] = 1;
                continue;
            }
            result[i] = 0;
        }

        int disjoints = 0;
        foreach (int i in result)
        {
            if (i == 0)
            {
                disjoints++;
            }
        }

        float weigthSum = 0;
        counterMax = diff > 0 ? connectionsA.Count : connectionsB.Count;
        for (int i = 0; i < counterMax; i++)
        {
            float w1 = 0;
            float w2 = 0;

            if (i < connectionsA.Count)
            {
                w1 = connectionsA[i].weight;
            }

            if (i < connectionsB.Count)
            {
                w2 = connectionsB[i].weight;
            }

            weigthSum += Mathf.Abs(w1 - w1);
        }

        weigthSum /= counterMax;

        diff = Mathf.Abs(diff);

        int genomSumA = connectionsA.Count + networkA.GetNodeGenom().Count;
        int genomSumB = connectionsB.Count + networkB.GetNodeGenom().Count;

        if (genomSumA > genomSumB)
        {
            return(((excessFactor * diff) / genomSumA) + ((disjointFactor * disjoints) / genomSumA) + (weigthFactor * weigthSum));
        }

        return(((excessFactor * diff) / genomSumB) + ((disjointFactor * disjoints) / genomSumB) + (weigthFactor * weigthSum));
    }
Beispiel #20
0
    public void SetNEAT(NEAT neat, Vector2Int gridSize, Vector2 bucketSize, Vector2 offset)
    {
        //this.gridSize = new int[2];
        //this.gridSize[0] = gridSize.x;
        //this.gridSize[1] = gridSize.y;

        //this.bucketSize = new int[2];
        //this.bucketSize[0] = bucketSize.x;
        //this.bucketSize[1] = bucketSize.y;

        //this.offset = new int[2];
        //this.offset[0] = offset.x;
        //this.offset[1] = offset.y;

        //innovation = neat.GetInnovation();
        //inputs = neat.GetInputSize();
        //outputs = neat.GetOutputsSize();

        //List<float> tempFloatsNodes = new List<float>();
        //List<float> tempFloatsConnections = new List<float>();

        //foreach(var node in neat.GetNodeGenom()) {

        //    //node vars
        //    tempFloatsNodes.Add(node.order);
        //    tempFloatsNodes.Add(node.nodeID);
        //    tempFloatsNodes.Add((int)node.nodeType);
        //    tempFloatsNodes.Add(node.activation);
        //    tempFloatsNodes.Add(node.sum);

        //    //nodeGenom.Add(new Node(node.nodeID, node.order, (NodeType)(int)node.nodeType));
        //    //Debug.Log("node type " + node.nodeType);
        //}

        //foreach(var connection in neat.GetConnetionGenom()) {

        //    //connections vars

        //    tempFloatsConnections.Add(connection.inNode);
        //    tempFloatsConnections.Add(connection.outNode);
        //    tempFloatsConnections.Add(connection.weight);

        //    if(connection.enabled)
        //        tempFloatsConnections.Add(1);
        //    else
        //        tempFloatsConnections.Add(0);

        //    tempFloatsConnections.Add(connection.innovation);

        //    //Node inNode = nodeGenom.Find(n => n.nodeID == connection.inNode);
        //    //Node outNode = nodeGenom.Find(n => n.nodeID == connection.outNode);
        //    //Connection newC = new Connection(inNode.nodeID, outNode.nodeID, connection.weight, connection.enabled, connection.innovation);
        //    //connectionGenom.Add(newC);
        //    //inNode.AddConnection(newC);
        //}

        //floatNodes = tempFloatsNodes.ToArray();
        //floatConnections = tempFloatsConnections.ToArray();

        SaveBrain save = new SaveBrain(neat, gridSize, bucketSize, offset);

        // 2
        BinaryFormatter bf   = new BinaryFormatter();
        FileStream      file = File.Create(Application.persistentDataPath + "/" + name + ".save");

        bf.Serialize(file, save);
        file.Close();

        Debug.Log("Game Saved");
    }
Beispiel #21
0
 public void SetNEAT(NEAT network)
 {
     NEATNetowrk = network;
 }
    public static NetworkPorts FromGenotype(NEAT.Genotype genotype)
    {
        var neuronGenes = genotype.NeuronGenes.ToList();
        var synapseGenes = genotype.SynapseGenes.ToList();

        var network = new Neural.Network(20ul);

        var upperNeurons = new Dictionary<int, IReceptiveField>();
        var lowerNeurons = new Dictionary<int, IReceptiveField>();
        var positionNeurons = new Dictionary<int, IReceptiveField>();
        var speedNeurons = new Dictionary<int, IReceptiveField>();

        foreach (var neuronGene in neuronGenes) {
          float a = NumberHelper.Scale(neuronGene.a, 0.02f, 0.1f); // 0.1
          float b = NumberHelper.Scale(neuronGene.b, 0.2f, 0.25f); // 0.2
          float c = NumberHelper.Scale(neuronGene.c, -65.0f, -50.0f); // -65.0
          float d = NumberHelper.Scale(neuronGene.d, 0.05f, 8.0f); // 2.0

          try {
          var id = (int)network.AddNeuron(Neural.IzhikevichConfig.Of(a, b, c, d));

        var mean = 0.0f;
        var sigma = 0.0f;
        switch (neuronGene.type) {
          case NeuronType.UpperNeuron:
            mean = NumberHelper.Scale(neuronGene.mean, -180.0f, 180.0f);
            sigma = NumberHelper.Scale(neuronGene.sigma, 0.0f, 180.0f);
            upperNeurons[id] = new SignReceptiveField(mean, sigma);
            break;
          case NeuronType.LowerNeuron:
            mean = NumberHelper.Scale(neuronGene.mean, -180.0f, 180.0f);
            sigma = NumberHelper.Scale(neuronGene.sigma, 0.0f, 180.0f);
            lowerNeurons[id] = new SignReceptiveField(mean, sigma);
            break;
          case NeuronType.PositionNeuron:
            mean = NumberHelper.Scale(neuronGene.mean, -12.0f, 12.0f);
            sigma = NumberHelper.Scale(neuronGene.sigma, 0.0f, 12.0f);
            positionNeurons[id] = new SignReceptiveField(mean, sigma);
            break;
          case NeuronType.SpeedNeuron:
            mean = NumberHelper.Scale(neuronGene.mean, -1.0f, 1.0f);
            sigma = NumberHelper.Scale(neuronGene.sigma, 0.0f, 1000.0f);
            speedNeurons[id] = new MulReceptiveField(mean, sigma);
            break;
        }
          } catch (Exception e) {
        Debug.LogException(e);
          }
        }

        // Connect each input neuron to the output neuron.
        foreach (var synapseGene in synapseGenes) {
          if (!synapseGene.isEnabled) {
        continue;
          }

          var fromNeuronId = neuronGenes.FindIndex(n => n.InnovationId == synapseGene.fromNeuronId);
          var toNeuronId = neuronGenes.FindIndex(n => n.InnovationId == synapseGene.toNeuronId);

          Assert.AreNotEqual(fromNeuronId, -1, "Must find from-neuron id");
          Assert.AreNotEqual(toNeuronId, -1, "Must find to-neuron id");

          float weight = NumberHelper.Scale(synapseGene.weight, -40.0f, 40.0f);

          try {
        network.AddSynapse((ulong)fromNeuronId, (ulong)toNeuronId, Neural.STDPConfig.Of(weight, -40.0f, 40.0f));
          } catch (Exception e) {
        Debug.LogException(e);
          }
        }

        return new NetworkPorts(network, upperNeurons, lowerNeurons, positionNeurons, speedNeurons);
    }