예제 #1
0
    /// <summary>
    /// Assign a species to each network in the population
    /// </summary>
    private void AssignPopulationToSpecies()
    {
        foreach (NeatNetwork network in population)
        {
            // Attempt to add an existing species
            bool added = false;
            foreach (NeatSpecies species in activeSpecies)
            {
                added = species.AttemptAdd(network);
                if (added)
                {
                    break;
                }
            }

            // Create a new species with this as a rep
            if (!added)
            {
                NeatSpecies newSpecies = new NeatSpecies(this, network);
                activeSpecies.Add(newSpecies);
            }
        }


        // Remove species with no currently active members
        for (int i = 0; i < activeSpecies.Count; ++i)
        {
            if (activeSpecies[i].population.Count == 0)
            {
                Debug.Log("Species (" + activeSpecies[i].colour.ToString() + ") has died after " + activeSpecies[i].generationsLived + " generations");
                activeSpecies.RemoveAt(i);
                --i;
            }
        }
    }
예제 #2
0
    /// <summary>
    /// Create the next generation of networks
    /// </summary>
    /// <param name="newPopulationSize">How large the next population should be</param>
    /// <returns></returns>
    public NeatNetwork[] BreedNextGeneration(int newPopulationSize)
    {
        SaveXML();

        // Calulate the average adjusted fitness
        float totalFitness = 0.0f;
        Dictionary <NeatSpecies, float> fitness = new Dictionary <NeatSpecies, float>();

        foreach (NeatSpecies species in activeSpecies)
        {
            float adjustedFitness = species.CalulateAverageAdjustedFitness();
            totalFitness    += adjustedFitness;
            fitness[species] = adjustedFitness;
        }


        // Determine how many networks each species has been allocated
        Dictionary <NeatSpecies, int> allocation = new Dictionary <NeatSpecies, int>();
        int totalNewCount = 0;

        foreach (NeatSpecies species in activeSpecies)
        {
            if (totalFitness <= 0.0f)
            {
                allocation[species] = 0;
            }
            else
            {
                int alloc = (int)((fitness[species] / totalFitness) * newPopulationSize);
                allocation[species] = alloc;
                totalNewCount      += alloc;
            }
        }


        // Handle if new count is too high or low
        if (totalNewCount < newPopulationSize)
        {
            // Randomly allocate the remainder
            for (int i = 0; i < newPopulationSize - totalNewCount; ++i)
            {
                NeatSpecies species = activeSpecies[Random.Range(0, activeSpecies.Count)];
                allocation[species]++;
            }
        }
        else if (totalNewCount > newPopulationSize)
        {
            // Randomly deallocate the remainder
            for (int i = 0; i < totalNewCount - newPopulationSize; ++i)
            {
                NeatSpecies species = activeSpecies[Random.Range(0, activeSpecies.Count)];
                allocation[species]--;
            }
        }


        // Generate new popluation
        List <NeatNetwork> newPopulation = new List <NeatNetwork>();

        foreach (NeatSpecies species in activeSpecies)
        {
            species.NextGeneration(allocation[species], newPopulation);
        }

        population = newPopulation.ToArray();


        // Assign correct species to the new networks
        AssignPopulationToSpecies();


        generationCounter++;
        Debug.Log("Generation " + generationCounter + " with " + activeSpecies.Count + " species");
        return(population);
    }