Exemplo n.º 1
0
    public Population BreedPopulation(ref Population sourcePopulation)
    {
        for(int m = 0; m < sourcePopulation.masterAgentArray.Length; m++) {
            //sourcePopulation.masterAgentArray[m].brain.genome.PrintBiases("sourcePop " + sourcePopulation.masterAgentArray[m].fitnessScore.ToString() + ", " + m.ToString() + ", ");
            //newPop.masterAgentArray[m].brain.genome.PrintBiases("newPop " + m.ToString() + ", ");
        }
        // rank sourcePop by fitness score // maybe do this as a method of Population class?
        sourcePopulation.RankAgentArray();

        Population newPopulation = new Population();
        newPopulation = sourcePopulation.CopyPopulationSettings();

        // Calculate total fitness score:
        float totalScore = 0f;
        if(survivalByRaffle) {
            for(int a = 0; a < sourcePopulation.populationMaxSize; a++) { // iterate through all agents
                totalScore += sourcePopulation.masterAgentArray[a].fitnessScore;
            }
        }

        // Create the Population that will hold the next Generation agentArray:
        Population newPop = sourcePopulation.CopyPopulationSettings();

        // Figure out How many Agents survive
        int numSurvivors = Mathf.RoundToInt(survivalRate * (float)newPop.populationMaxSize);

        //Depending on method, one at a time, select an Agent to survive until the max Number is reached
        int newChildIndex = 0;

        // For ( num Agents ) {
        for(int i = 0; i < numSurvivors; i++) {
            // If survival is by fitness score ranking:
            if(survivalByRank) {
                // Pop should already be ranked, so just traverse from top (best) to bottom (worst)
                newPopulation.masterAgentArray[newChildIndex] = sourcePopulation.masterAgentArray[newChildIndex];
                newChildIndex++;
            }
            // if survival is completely random, as a control:
            if(survivalStochastic) {
                int randomAgent = UnityEngine.Random.Range (0, numSurvivors-1);
                // Set next newChild slot to a completely randomly-chosen agent
                newPopulation.masterAgentArray[newChildIndex] = sourcePopulation.masterAgentArray[randomAgent];
                newChildIndex++;
            }
            // if survival is based on a fitness lottery:
            if(survivalByRaffle) {  // Try when Fitness is normalized from 0-1
                float randomSlicePosition = UnityEngine.Random.Range(0f, totalScore);
                float accumulatedFitness = 0f;
                for(int a = 0; a < sourcePopulation.populationMaxSize; a++) { // iterate through all agents
                    accumulatedFitness += sourcePopulation.masterAgentArray[a].fitnessScore;
                    // if accum fitness is on slicePosition, copy this Agent
                    Debug.Log ("NumSurvivors: " + numSurvivors.ToString() + ", Surviving Agent " + a.ToString() + ": AccumFitness: " + accumulatedFitness.ToString() + ", RafflePos: " + randomSlicePosition.ToString() + ", TotalScore: " + totalScore.ToString() + ", newChildIndex: " + newChildIndex.ToString());
                    if(accumulatedFitness >= randomSlicePosition) {
                        newPopulation.masterAgentArray[newChildIndex] = sourcePopulation.masterAgentArray[a];
                        newChildIndex++;
                    }

                }
            }
        //		set newPop Agent to lucky sourcePop index
        //////////	Agent survivingAgent = sourcePopulation.Select
        // Fill up newPop agentArray with the surviving Agents
        // Keep track of Index, as that will be needed for new agents
        }

        // Figure out how many new agents must be created to fill up the new population:
        int numNewChildAgents = newPopulation.populationMaxSize - numSurvivors;
        int numEligibleBreederAgents = Mathf.RoundToInt(breedingRate * (float)newPop.populationMaxSize);
        int currentRankIndex = 0;

        float totalScoreBreeders = 0f;
        if(breedingByRaffle) {
            for(int a = 0; a < numEligibleBreederAgents; a++) { // iterate through all agents
                totalScoreBreeders += sourcePopulation.masterAgentArray[a].fitnessScore;
            }
        }
        //float[][] parentAgentChromosomes = new float[][];
        // Iterate over numAgentsToCreate :
        // Change to While loop?
        int newChildrenCreated = 0;
        while(newChildrenCreated < numNewChildAgents) {
        //		Find how many parents random number btw min/max
            int numParentAgents = UnityEngine.Random.Range (minNumParents, maxNumParents);
            int numChildAgents = 1;
            if(numNewChildAgents - newChildrenCreated >= 2) {  // room for two more!
                numChildAgents = 2;
                //Debug.Log ("numNewChildAgents: " + numNewChildAgents.ToString() + " - newChildrenCreated: " + newChildrenCreated.ToString() + " = numChildAgents: " + numChildAgents.ToString());
            }
            float[][] parentAgentBiases = new float[numParentAgents][];
            float[][] parentAgentWeights = new float[numParentAgents][];
            for(int p = 0; p < numParentAgents; p++) {
        //		Iterate over numberOfParents :
        //			Depending on method, select suitable agents' genome.Arrays until the numberOfPArents is reached, collect them in an array of arrays
                // If breeding is by fitness score ranking:
                if(breedingByRank) {
                    // Pop should already be ranked, so just traverse from top (best) to bottom (worst) to select parentAgents
                    if(currentRankIndex >= numEligibleBreederAgents) { // if current rank index is greater than the num of eligible breeders, then restart the index to 0;
                        currentRankIndex = 0;
                    }
                    //parentAgentChromosomes[p] = new float[sourcePopulation.masterAgentArray[currentRankIndex].genome.genomeBiases.Length];
                    parentAgentBiases[p] = sourcePopulation.masterAgentArray[currentRankIndex].genome.genomeBiases;
                    parentAgentWeights[p] = sourcePopulation.masterAgentArray[currentRankIndex].genome.genomeWeights;
                    currentRankIndex++;
                }
                // if survival is completely random, as a control:
                if(breedingStochastic) {
                    int randomAgent = UnityEngine.Random.Range (0, numEligibleBreederAgents-1); // check if minus 1 is needed
                    // Set next newChild slot to a completely randomly-chosen agent
                    parentAgentBiases[p] = sourcePopulation.masterAgentArray[randomAgent].genome.genomeBiases;
                    parentAgentWeights[p] = sourcePopulation.masterAgentArray[randomAgent].genome.genomeWeights;
                }
                // if survival is based on a fitness lottery:
                if(breedingByRaffle) {
                    float randomSlicePosition = UnityEngine.Random.Range(0f, totalScoreBreeders);
                    float accumulatedFitness = 0f;
                    for(int a = 0; a < numEligibleBreederAgents; a++) { // iterate through all agents
                        accumulatedFitness += sourcePopulation.masterAgentArray[a].fitnessScore;
                        // if accum fitness is on slicePosition, copy this Agent
                        Debug.Log ("Breeding Agent " + a.ToString() + ": AccumFitness: " + accumulatedFitness.ToString() + ", RafflePos: " + randomSlicePosition.ToString() + ", totalScoreBreeders: " + totalScoreBreeders.ToString() + ", numEligibleBreederAgents: " + numEligibleBreederAgents.ToString());
                        if(accumulatedFitness >= randomSlicePosition) {
                            parentAgentBiases[p] = sourcePopulation.masterAgentArray[a].genome.genomeBiases;
                            parentAgentWeights[p] = sourcePopulation.masterAgentArray[a].genome.genomeWeights;
                        }
                    }
                }
            }
            // Combine the genes in the parentArrays and return the specified number of children genomes
        //		Pass that array of parentAgent genome.Arrays into the float-based MixFloatChromosomes() function,
            float[][] childAgentBiases = MixFloatChromosomes(parentAgentBiases, numChildAgents);
            float[][] childAgentWeights = MixFloatChromosomes(parentAgentWeights, numChildAgents);

        //		It can return an Array of Arrays (of new childAgent genome.Arrays)
        //		Iterate over ChildArray.Length :  // how many newAgents created
            for(int c = 0; c < numChildAgents; c++) { // for number of child Agents in floatArray[][]:
                for(int b = 0; b < sourcePopulation.masterAgentArray[0].genome.genomeBiases.Length; b++) {
                    //Debug.Log ("ChildNumber: " + c.ToString() + ", BiasIndex: " + b.ToString() + ", biasValue: " + childAgentBiases[c][b].ToString () + ", newChildIndex: " + newChildIndex.ToString() + ", numNewChildren: " + numNewChildAgents.ToString() + ", numChildAgents: " + numChildAgents.ToString() + ", newChildrenCreated: " + newChildrenCreated.ToString());
                    newPopulation.masterAgentArray[newChildIndex].genome.genomeBiases[b] = childAgentBiases[c][b];
                    // weights and functions and more!
                }
                for(int w = 0; w < sourcePopulation.masterAgentArray[0].genome.genomeWeights.Length; w++) {
                    //Debug.Log ("ChildNumber: " + c.ToString() + ", BiasIndex: " + b.ToString() + ", biasValue: " + childAgentBiases[c][b].ToString () + ", newChildIndex: " + newChildIndex.ToString() + ", numNewChildren: " + numNewChildAgents.ToString() + ", numChildAgents: " + numChildAgents.ToString() + ", newChildrenCreated: " + newChildrenCreated.ToString());
                    newPopulation.masterAgentArray[newChildIndex].genome.genomeWeights[w] = childAgentWeights[c][w];
                    // weights and functions and more!
                }
                newPopulation.masterAgentArray[newChildIndex].brain.SetBrainFromGenome(newPopulation.masterAgentArray[newChildIndex].genome);
                newChildIndex++;  // new child created!
                newChildrenCreated++;
            }

        }
        //newPop.isFunctional = true;
        return newPopulation;
    }
Exemplo n.º 2
0
    public void PerformCrossover(ref Population sourcePopulation)
    {
        Population newPop = sourcePopulation.CopyPopulationSettings();

        if(numFactions > 1) {

            Population[] sourceFactions = sourcePopulation.SplitPopulation(numFactions);
            Population[] newFactions = new Population[numFactions];
            for(int i = 0; i < numFactions; i++) {
                // Make a Genome array of each faction
                // Then BreedAgentPool on each Array?
                // Then Add those genomes to new Population masterAgentArray?
                //newFactions[i] = sourceFactions[i].CopyPopulationSettings();
                Debug.Log ("FactionSize: " + sourceFactions[i].populationMaxSize.ToString());
                newFactions[i] = BreedPopulation(ref sourceFactions[i]);
            }
            // Add them back together!
            newPop.SetToCombinedPopulations(newFactions);

        }
        else {
            newPop = BreedPopulation(ref sourcePopulation);
        }
        sourcePopulation = newPop;
    }