/// <summary>
    /// Evaluate the provided phenome and return its fitness score.
    /// This takes a blackbox (pretty much the decoded neuralnetwork (the phenome)) that input can be passed to
    /// and output processed in the domain. Makes it very easy, we dont have to wory about the genome (genelist) or phenome (network) at all
    /// </summary>
    public FitnessInfo Evaluate(IBlackBox box)
    {
        // Set a maximum number of evaluations
        _evalCount++;
        double      fitness     = 0.5;
        FitnessInfo fitnessInfo = new FitnessInfo(fitness, fitness);

        if (_evalCount > _nextEvalStop)
        {
            _nextEvalStop          += _evalBlockSize;
            _stopConditionSatisfied = true;
        }

        // Only use player model if it has been initialized. Otherwise, all fitness is 0.5
        if (_experiment.playerModel != null)
        {
            // Get highlevel features
            PCGSharpHighLevelFeatures featureCounts = new PCGSharpHighLevelFeatures();
            PCGSharpHighLevelFeatures.C_HL_ROOMTYPE lastRoomType = PCGSharpHighLevelFeatures.C_HL_ROOMTYPE.NoPreviousRoom;
            for (int i = 0; i < _experiment.geomNodeList.Count; i++)
            {
                // Get cppn output for each node
                box.InputSignalArray[0] = _experiment.geomNodeList[i].normDepth;
                box.InputSignalArray[1] = _experiment.geomNodeList[i].normSiblingIndex;

                box.ResetState();
                box.Activate();

                double[] outputs = new double[box.OutputCount];
                for (int j = 0; j < box.OutputCount; j++)
                {
                    outputs[j] = box.OutputSignalArray[j];
                }

                // Convert each nodes cppn output into a contentId
                int combinedContentID = featureCounts.CPPNOutputToSettingsId(outputs);
                lastRoomType = featureCounts.UpdateFeatures(combinedContentID, lastRoomType);
            }

            // Pass the highlevel features into the player model to get the fitness
            double[] distributions = _experiment.playerModel.ClassifyNewData(featureCounts.ToDoubleArray());
            // Fitness is the membership to the "Like" class (positive class)
            fitnessInfo = new FitnessInfo(distributions[1], distributions[1]);
        }

        return(fitnessInfo);
    }
    // Represent difference with negative number. More negative = more different
    public double CompareToOther(PCGSharpHighLevelFeatures other)
    {
        double[] data1 = ToDoubleArray();
        double[] data2 = other.ToDoubleArray();

        double difference = 0;

        for (int i = 0; i < data1.Length; i++)
        {
            if (data1[i] >= data2[i])
            {
                difference -= (data1[i] - data2[i]);
            }
            else
            {
                difference -= (data2[i] - data1[i]);
            }
        }
        return(difference);
    }
    public void PrintStats()
    {
        // MUST BE CALLED AFTER RunEA
        NeatAlgorithmStats stats = contentEA.Statistics;
        Debug.Log("************* NEAT STATS **************");
        Debug.Log("Generation = " + stats._generation + ", Total Evaluation = " + stats._totalEvaluationCount
            + ", Max Fitness = " + stats._maxFitness + ", MeanFitness = " + stats._meanFitness);

        IGenomeDecoder<NeatGenome, IBlackBox> decoder = experiment.CreateGenomeDecoder();
        IBlackBox box = decoder.Decode(contentEA.CurrentChampGenome);
        FastAcyclicNetwork concrete = (FastAcyclicNetwork)box;

        Debug.Log("Champ:Num hidden nodes = " + concrete.hiddenNodeCount + ", num connections = " + concrete.connectionCount);

        // Get highlevel features
        PCGSharpHighLevelFeatures featureCounts = new PCGSharpHighLevelFeatures();
        PCGSharpHighLevelFeatures.C_HL_ROOMTYPE lastRoomType = PCGSharpHighLevelFeatures.C_HL_ROOMTYPE.NoPreviousRoom;
        for (int i = 0; i < (experiment as PCGNeatExperiment).geomNodeList.Count; i++) {
            // Get cppn output for each node
            box.InputSignalArray[0] = (experiment as PCGNeatExperiment).geomNodeList[i].normDepth;
            box.InputSignalArray[1] = (experiment as PCGNeatExperiment).geomNodeList[i].normSiblingIndex;

            box.ResetState();
            box.Activate();

            string outputString = box.OutputSignalArray[0].ToString();
            double[] outputs = new double[box.OutputCount];
            outputs[0] = box.OutputSignalArray[0];
            for (int j = 1; j < box.OutputCount; j++) {
                outputString = outputString +","+box.OutputSignalArray[j];
                outputs[j] = box.OutputSignalArray[j];
            }

            Debug.Log("(" + (experiment as PCGNeatExperiment).geomNodeList[i].normDepth + ","
                + (experiment as PCGNeatExperiment).geomNodeList[i].normSiblingIndex + ") -> (" + outputString + ")");

            // Convert each nodes cppn output into a contentId
            int combinedContentID = featureCounts.CPPNOutputToSettingsId(outputs);
            lastRoomType = featureCounts.UpdateFeatures(combinedContentID, lastRoomType);
        }

        // Pass the highlevel features into the player model to get the fitness
        if ((experiment as PCGNeatExperiment).playerModel != null) {
            double[] distributions = (experiment as PCGNeatExperiment).playerModel.ClassifyNewData(featureCounts.ToDoubleArray());
            Debug.Log("Classifier: Champ Distributions: Dislike = " + distributions[0] + ", Like = " + distributions[1]);
            (experiment as PCGNeatExperiment).playerModel.PrintClassifierTestReport();
        }

        Debug.Log("**************END NEAT STATS**************");
    }
Beispiel #4
0
    public void PrintStats()
    {
        // MUST BE CALLED AFTER RunEA
        NeatAlgorithmStats stats = contentEA.Statistics;

        Debug.Log("************* NEAT STATS **************");
        Debug.Log("Generation = " + stats._generation + ", Total Evaluation = " + stats._totalEvaluationCount
                  + ", Max Fitness = " + stats._maxFitness + ", MeanFitness = " + stats._meanFitness);

        IGenomeDecoder <NeatGenome, IBlackBox> decoder = experiment.CreateGenomeDecoder();
        IBlackBox          box      = decoder.Decode(contentEA.CurrentChampGenome);
        FastAcyclicNetwork concrete = (FastAcyclicNetwork)box;

        Debug.Log("Champ:Num hidden nodes = " + concrete.hiddenNodeCount + ", num connections = " + concrete.connectionCount);

        // Get highlevel features
        PCGSharpHighLevelFeatures featureCounts = new PCGSharpHighLevelFeatures();

        PCGSharpHighLevelFeatures.C_HL_ROOMTYPE lastRoomType = PCGSharpHighLevelFeatures.C_HL_ROOMTYPE.NoPreviousRoom;
        for (int i = 0; i < (experiment as PCGNeatExperiment).geomNodeList.Count; i++)
        {
            // Get cppn output for each node
            box.InputSignalArray[0] = (experiment as PCGNeatExperiment).geomNodeList[i].normDepth;
            box.InputSignalArray[1] = (experiment as PCGNeatExperiment).geomNodeList[i].normSiblingIndex;

            box.ResetState();
            box.Activate();

            string   outputString = box.OutputSignalArray[0].ToString();
            double[] outputs      = new double[box.OutputCount];
            outputs[0] = box.OutputSignalArray[0];
            for (int j = 1; j < box.OutputCount; j++)
            {
                outputString = outputString + "," + box.OutputSignalArray[j];
                outputs[j]   = box.OutputSignalArray[j];
            }

            Debug.Log("(" + (experiment as PCGNeatExperiment).geomNodeList[i].normDepth + ","
                      + (experiment as PCGNeatExperiment).geomNodeList[i].normSiblingIndex + ") -> (" + outputString + ")");

            // Convert each nodes cppn output into a contentId
            int combinedContentID = featureCounts.CPPNOutputToSettingsId(outputs);
            lastRoomType = featureCounts.UpdateFeatures(combinedContentID, lastRoomType);
        }

        // Pass the highlevel features into the player model to get the fitness
        if ((experiment as PCGNeatExperiment).playerModel != null)
        {
            double[] distributions = (experiment as PCGNeatExperiment).playerModel.ClassifyNewData(featureCounts.ToDoubleArray());
            Debug.Log("Classifier: Champ Distributions: Dislike = " + distributions[0] + ", Like = " + distributions[1]);
            (experiment as PCGNeatExperiment).playerModel.PrintClassifierTestReport();
        }

        Debug.Log("**************END NEAT STATS**************");
    }
    // Represent difference with negative number. More negative = more different
    public double CompareToOther(PCGSharpHighLevelFeatures other)
    {
        double[] data1 = ToDoubleArray();
        double[] data2 = other.ToDoubleArray();

        double difference = 0;
        for (int i = 0; i < data1.Length; i++) {
            if (data1[i] >=	data2[i])
                difference -= (data1[i]-data2[i]);
            else
                difference -= (data2[i]-data1[i]);
        }
        return difference;
    }