/// <summary>
        /// Construct a function regression evaluator with the provided parameter sampling info and function to regress.
        /// </summary>
        public FnRegressionEvaluator(IFunction fn, ParamSamplingInfo paramSamplingInfo, double gradientMseWeight, IBlackBoxProbe blackBoxProbe)
        {
            _paramSamplingInfo = paramSamplingInfo;
            _gradientMseWeight = gradientMseWeight;
            _yMseWeight        = 1.0 - gradientMseWeight;
            _blackBoxProbe     = blackBoxProbe;

            // Predetermine target responses.
            int sampleCount = _paramSamplingInfo._sampleCount;

            _yArrTarget        = new double[sampleCount];
            _gradientArrTarget = new double[sampleCount];

            FunctionProbe fnProbe = new FunctionProbe(paramSamplingInfo);

            fnProbe.Probe(fn, _yArrTarget);
            FnRegressionUtils.CalcGradients(paramSamplingInfo, _yArrTarget, _gradientArrTarget);
        }
Exemple #2
0
        /// <summary>
        /// Evaluate the provided IBlackBox against the XOR problem domain and return its fitness score.
        /// </summary>
        public FitnessInfo Evaluate(IBlackBox box)
        {
            int sampleCount = _paramSamplingInfo._sampleCount;

            // TODO: We can avoid a memory allocation here by allocating at construction time, but this requires modification of
            // ParallelGenomeListEvaluator to utilise multiple evaluators (one per thread).
            double[] yArr        = new double[sampleCount];
            double[] gradientArr = new double[sampleCount];

            // Probe the black box over the full range of the input parameter.
            _blackBoxProbe.Probe(box, yArr);

            // Calc gradients.
            FnRegressionUtils.CalcGradients(_paramSamplingInfo, yArr, gradientArr);

            // Calc y position mean squared error (MSE), and apply weighting.
            double yMse = FnRegressionUtils.CalcMeanSquaredError(yArr, _yArrTarget);

            yMse *= _yMseWeight;

            // Calc gradient mean squared error.
            double gradientMse = FnRegressionUtils.CalcMeanSquaredError(gradientArr, _gradientArrTarget);

            gradientMse *= _gradientMseWeight;

            // Calc fitness as the inverse of MSE (higher value is fitter).
            // Add a constant to avoid divide by zero, and to constrain the fitness range between bad and good solutions;
            // this allows the selection strategy to select solutions that are mediocre and therefore helps preserve diversity.
            double fitness = 20.0 / (yMse + gradientMse + 0.02);

            // Test for stopping condition (near perfect response).
            if (fitness >= 100000.0)
            {
                _stopConditionSatisfied = true;
            }
            _evalCount++;
            return(new FitnessInfo(fitness, fitness));
        }