Esempio n. 1
0
    public NeatNetwork(NeatController controller, int inputCount, int outputCount)
    {
        this.controller = controller;
        age             = 0;

        this.inputCount  = inputCount;
        this.outputCount = outputCount;

        // Initialise network
        nodes     = new List <NeatNode>();
        genes     = new List <NeatGene>();
        geneTable = new Dictionary <Vector2Int, NeatGene>();


        // The first I nodes will be inputs and the following O nodes will be outputs
        for (int i = 0; i < inputCount; ++i)
        {
            nodes.Add(new NeatNode(nodes.Count, NeatNode.NodeType.Input, this));
        }

        for (int i = 0; i < outputCount; ++i)
        {
            nodes.Add(new NeatNode(nodes.Count, NeatNode.NodeType.Output, this));
        }


        //
        // Avoid creation of non-essential genes (Requires testing)
        //
        // Create initial (minimal genes) connection inputs to outputs
        //for (int i = 0; i < inputCount; ++i)
        //    for (int j = 0; j < outputCount; ++j)
        //		CreateGene(i, inputCount + j);
    }
Esempio n. 2
0
    void OnEnable()
    {
        existingCollections = NeatController.GetExistingCollections();
        existingTrees       = TreeInputAgent.GetExistingTrees();

        // No collections on disc so cannot load
        if (existingCollections.Length == 0)
        {
            populationName.gameObject.SetActive(false);


            treeCount.SetRange(0, MaxCharacterCount);
            treeCount.Value        = treeCount.Max;
            treeCount.Interactable = false;

            neuralCount.SetRange(0, MaxCharacterCount);
            neuralCount.Value        = 0;
            neuralCount.Interactable = false;

            existingCollections = new string[] { "AiArena" };
        }
        else
        {
            populationName.gameObject.SetActive(true);
            treeCount.Interactable   = true;
            neuralCount.Interactable = true;

            // Update displayed options
            populationName.ClearOptions();

            List <Dropdown.OptionData> options = new List <Dropdown.OptionData>();
            foreach (string collection in existingCollections)
            {
                options.Add(new Dropdown.OptionData(collection));
            }
            populationName.AddOptions(options);
        }


        if (existingTrees.Length == 0)
        {
            existingTrees = new string[] { "Null" };
        }

        // Update displayed options
        treeName.ClearOptions();

        List <Dropdown.OptionData> treeOptions = new List <Dropdown.OptionData>();

        foreach (string collection in existingTrees)
        {
            treeOptions.Add(new Dropdown.OptionData(collection));
        }
        treeName.AddOptions(treeOptions);


        populationName.value = 0;
        treeName.value       = 0;
    }
Esempio n. 3
0
    public NeatSpecies(NeatController controller, NeatNetwork representative)
    {
        this.controller     = controller;
        this.representative = representative;
        colour           = Color.HSVToRGB(Random.value, Random.Range(0.5f, 1.0f), Random.Range(0.5f, 1.0f));
        generationsLived = 0;
        guid             = System.Guid.NewGuid();

        population = new List <NeatNetwork>();
        population.Add(representative);
        representative.assignedSpecies = this;
    }
Esempio n. 4
0
    void OnEnable()
    {
        existingCollections = NeatController.GetExistingCollections();

        // No collections on disc so cannot load
        if (existingCollections.Length == 0)
        {
            newPopulationToggle.interactable = false;
        }
        else
        {
            newPopulationToggle.interactable = true;
        }
    }
Esempio n. 5
0
    /// <summary>
    /// Create a copy of an existing network structure (Only structual values are copies)
    /// </summary>
    /// <param name="controller"></param>
    /// <param name="inputCount"></param>
    /// <param name="outputCount"></param>
    public NeatNetwork(NeatNetwork other)
    {
        this.controller = other.controller;
        previousFitness = other.fitness;
        this.age        = other.age + 1;

        this.inputCount  = other.inputCount;
        this.outputCount = other.outputCount;

        // Initialise network
        nodes     = new List <NeatNode>(other.nodes);
        genes     = new List <NeatGene>(other.genes);
        geneTable = new Dictionary <Vector2Int, NeatGene>(other.geneTable);
    }
Esempio n. 6
0
    /// <summary>
    /// Create networks
    /// </summary>
    /// <param name="collectionName">The name of the collection to load/create</param>
    /// <param name="count">Number of networks to create</param>
    public void InitialiseController(string collectionName, int count)
    {
        populationSize = count;

        // Load NEAT controller
        neatController = new NeatController(collectionName);
        if (!neatController.LoadNeatSettings())
        {
            Debug.Log("Using default NEAT settings");
            neatController.WriteNeatSettings();
        }


        neatController.GenerateBasePopulation(count, NeuralInputAgent.InputCount, NeuralInputAgent.OutputCount, 1);

        // Use controller's runtime to start from
        runTime = neatController.runTime;
    }
Esempio n. 7
0
 public NeatSpecies(NeatController controller, XmlElement content)
 {
     this.controller = controller;
     population      = new List <NeatNetwork>();
     ReadXML(content);
 }
Esempio n. 8
0
    /// <summary>
    /// Can these 2 networks be consider the same species
    /// </summary>
    /// <returns></returns>
    public static bool AreSameSpecies(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 });
            }
        }


        // Consider genes in order
        List <int> geneIds = new List <int>(geneTable.Keys);

        geneIds.Sort((x, y) => - x.CompareTo(y));        // Sort from last to first


        int   excessCount          = 0;
        int   disjointCount        = 0;
        int   matchCount           = 0;
        float matchTotalWeightDiff = 0.0f;

        bool checkingForExcess   = true;
        bool checkingExcessFromA = false;         // Otherwise read from B

        // Calculate counts by considering each gene
        for (int i = 0; i < geneIds.Count; ++i)
        {
            NeatGene[] genes = geneTable[geneIds[i]];

            // Gene is excess if exists at hanging at end of gene list
            if (checkingForExcess)
            {
                // Check which side we're to read excess from
                if (i == 0)
                {
                    checkingExcessFromA = (genes[0] != null);
                }

                if (checkingExcessFromA && genes[1] == null)
                {
                    ++excessCount;
                }
                else if (!checkingExcessFromA && genes[0] == null)
                {
                    ++excessCount;
                }

                // Finished reading the excess (either the network we're reading doesn't have this gene or the other network also has this gene)
                else
                {
                    checkingForExcess = false;
                }
            }

            // (Can be changed above, so still check for disjoint of matching)
            if (!checkingForExcess)
            {
                // Matching gene
                if (genes[0] != null && genes[1] != null)
                {
                    ++matchCount;
                    matchTotalWeightDiff += Mathf.Abs(genes[0].weight - genes[1].weight);
                }
                // One net doesn't have this gene, so disjoint
                else
                {
                    ++disjointCount;
                }
            }
        }

        NeatController controller = networkA.controller;         // Should be the same for B
        float          geneCount  = Mathf.Max(networkA.genes.Count, networkB.genes.Count);

        float networkDelta =
            controller.excessCoefficient * (geneCount == 0 ? 0 : excessCount / geneCount) +
            controller.disjointCoefficient * (geneCount == 0 ? 0 : disjointCount / geneCount) +
            controller.weightDiffCoefficient * (matchCount == 0 ? 0 : (matchTotalWeightDiff / (float)matchCount));

        // Each network can be considered under the same species, if their difference is in acceptable range
        return(networkDelta <= controller.speciesDeltaThreshold);
    }
Esempio n. 9
0
 public NeatNetwork(NeatController controller, XmlElement content)
 {
     this.controller = controller;
     ReadXML(content);
 }