Ejemplo n.º 1
0
    /// <summary>
    /// Randomly place a node in the middle of an existing gene
    /// </summary>
    private void AddMutatedNode()
    {
        if (genes.Count == 0)
        {
            return;
        }

        // 30 attempts to create a node
        for (int i = 0; i < 30; ++i)
        {
            int      geneId = Random.Range(0, genes.Count);
            NeatGene gene   = genes[geneId];

            // Only add node in enabled genes
            if (!gene.isEnabled)
            {
                continue;
            }

            // Add the node
            NeatNode newNode = new NeatNode(nodes.Count, NeatNode.NodeType.Hidden, this);
            nodes.Add(newNode);

            // Disable old gene and add connected genes to new node
            gene.isEnabled = false;
            CreateGene(gene.fromNodeId, newNode.ID).weight = 1.0f;             // Use 1.0 to avoid initial impact of adding the node
            CreateGene(newNode.ID, gene.toNodeId).weight   = gene.weight;
            return;
        }
    }
Ejemplo n.º 2
0
    /// <summary>
    /// Update this visualisation
    /// </summary>
    /// <param name="from">Visual node connecting from</param>
    /// <param name="to">Visual node connecting to</param>
    /// <param name="gene">The gene this is a visualisation for</param>
    public void SetVisualisation(NetworkNode from, NetworkNode to, NeatGene gene)
    {
        visual = GetComponent <RawImage>();

        fromNode = from;
        toNode   = to;
        netGene  = gene;

        visual.enabled = gene.isEnabled;
    }
Ejemplo n.º 3
0
    /// <summary>
    /// Create a gene between 2 nodes
    /// </summary>
    /// <param name="inNodeId">The index of the node for the gene to leave from</param>
    /// <param name="outNode">The index of the node for the gene to enter</param>
    /// <returns>The newly created gene object</returns>
    private NeatGene CreateGene(int fromNodeId, int toNodeId)
    {
        Vector2Int key = new Vector2Int(fromNodeId, toNodeId);

        // Check gene doesn't alreay exist (DEBUG)
        if (geneTable.ContainsKey(key))
        {
            Debug.LogError("Gene from (" + fromNodeId + "->" + toNodeId + ") already exists in this genome");
        }

        NeatGene gene = new NeatGene(controller.FetchInnovationId(fromNodeId, toNodeId), fromNodeId, toNodeId, Random.Range(-1.0f, 1.0f));

        genes.Add(gene);
        geneTable[key] = gene;

        nodes[fromNodeId].outputGenes.Add(gene);
        nodes[toNodeId].inputGenes.Add(gene);
        return(gene);
    }
Ejemplo n.º 4
0
    /// <summary>
    /// Read in the xml for a specfic generation
    /// </summary>
    /// <param name="writer"></param>
    public void ReadXML(XmlElement entry)
    {
        fitness         = float.Parse(entry.GetAttribute("fitness"));
        previousFitness = float.Parse(entry.GetAttribute("previousFitness"));
        age             = int.Parse(entry.GetAttribute("age"));


        foreach (XmlElement child in entry.ChildNodes)
        {
            // Parse nodes
            if (child.Name == "Nodes")
            {
                nodes = new List <NeatNode>();

                inputCount  = int.Parse(child.GetAttribute("inputCount"));
                outputCount = int.Parse(child.GetAttribute("outputCount"));
                int totalCount = int.Parse(child.GetAttribute("totalCount"));

                // Create nodes
                for (int i = 0; i < totalCount; ++i)
                {
                    if (i < inputCount)
                    {
                        nodes.Add(new NeatNode(nodes.Count, NeatNode.NodeType.Input, this));
                    }
                    else if (i < inputCount + outputCount)
                    {
                        nodes.Add(new NeatNode(nodes.Count, NeatNode.NodeType.Output, this));
                    }
                    else
                    {
                        nodes.Add(new NeatNode(nodes.Count, NeatNode.NodeType.Hidden, this));
                    }
                }
            }

            // Parse genes
            else if (child.Name == "Genes")
            {
                genes     = new List <NeatGene>();
                geneTable = new Dictionary <Vector2Int, NeatGene>();

                foreach (XmlElement gene in child.ChildNodes)
                {
                    if (gene.Name != "Gene")
                    {
                        continue;
                    }

                    int toId   = int.Parse(gene.GetAttribute("to"));
                    int fromId = int.Parse(gene.GetAttribute("from"));

                    NeatGene newGene = CreateGene(fromId, toId);
                    newGene.isEnabled = bool.Parse(gene.GetAttribute("isEnabled"));
                    newGene.weight    = float.Parse(gene.GetAttribute("weight"));
                }
            }
        }


        // Fetch assigned species from this
        if (entry.HasAttribute("speciesGuid"))
        {
            System.Guid guid = new System.Guid(entry.GetAttribute("speciesGuid"));

            // Fetch species
            foreach (var species in controller.activeSpecies)
            {
                if (species.guid == guid)
                {
                    if (!species.AttemptAdd(this))
                    {
                        Debug.LogWarning("Couldn't assign network desired species");
                    }
                    break;
                }
            }
        }
    }
Ejemplo n.º 5
0
    /// <summary>
    /// Perform matching on 2 networks to breed them
    /// </summary>
    /// <returns>The new child network</returns>
    public static NeatNetwork Breed(NeatNetwork networkA, NeatNetwork networkB)
    {
        // Construct gene table (A genes in index 0 B genes in index 1)
        Dictionary <int, NeatGene[]> geneTable = new Dictionary <int, NeatGene[]>();

        foreach (NeatGene gene in networkA.genes)
        {
            geneTable.Add(gene.innovationId, new NeatGene[] { gene, null });
        }

        foreach (NeatGene gene in networkB.genes)
        {
            if (geneTable.ContainsKey(gene.innovationId))
            {
                geneTable[gene.innovationId][1] = gene;
            }
            else
            {
                geneTable.Add(gene.innovationId, new NeatGene[] { null, gene });
            }
        }

        // Add new genes
        List <NeatGene> childGenes = new List <NeatGene>();

        foreach (var pair in geneTable)
        {
            NeatGene[] genes = pair.Value;

            // Inherit equally
            if (networkA.fitness == networkB.fitness)
            {
                // Only A posseses the gene
                if (genes[0] != null && genes[1] == null)
                {
                    childGenes.Add(genes[0]);
                }
                // Only B posseses the gene
                else if (genes[0] == null && genes[1] != null)
                {
                    childGenes.Add(genes[1]);
                }

                // Both posses the gene, so take random
                else
                {
                    childGenes.Add(genes[Random.Range(0, 2)]);
                }
            }
            // One nework is better than the other
            else
            {
                // Both posses the gene, so take random
                if (genes[0] != null && genes[1] != null)
                {
                    childGenes.Add(genes[Random.Range(0, 2)]);
                }

                // Take gene from A
                else if (networkA.fitness > networkB.fitness && genes[0] != null)
                {
                    childGenes.Add(genes[0]);
                }

                // Take gene from B
                else if (networkB.fitness > networkA.fitness && genes[1] != null)
                {
                    childGenes.Add(genes[1]);
                }
            }
        }


        // Construct child network
        NeatNetwork childNetwork = new NeatNetwork(networkA.controller, networkA.inputCount, networkB.outputCount);

        foreach (NeatGene gene in childGenes)
        {
            int maxId = System.Math.Max(gene.fromNodeId, gene.toNodeId);

            // Ensure required genes exist (Must initilise in index order)
            while (childNetwork.nodes.Count <= maxId)
            {
                childNetwork.nodes.Add(new NeatNode(childNetwork.nodes.Count, NeatNode.NodeType.Hidden, childNetwork));
            }

            // Add gene
            NeatGene newGene = childNetwork.CreateGene(gene.fromNodeId, gene.toNodeId);
            newGene.isEnabled = gene.isEnabled;
            newGene.weight    = gene.weight;
        }

        return(childNetwork);
    }