Пример #1
0
        private void PaintView(IBlackBox box)
        {
            if (_initializing)
            {
                return;
            }

            Graphics g = Graphics.FromImage(_image);

            g.FillRectangle(_brushBackground, 0, 0, _image.Width, _image.Height);
            g.SmoothingMode = SmoothingMode.AntiAlias;

            // Get control width and height.
            int width  = Width;
            int height = Height;

            // Determine smallest dimension. Use that as the edge length of the square grid.
            width = height = Math.Min(width, height);

            // Pixel size is calculated using integer division to produce cleaner lines when drawing.
            // The inherent rounding down may produce a grid 1 pixel smaller then the determined edge length.
            // Also make room for a combo box above the grid. This will be used allow the user to change the grid resolution.
            int visualFieldPixelSize = (height - GridTop) / _visualFieldResolution;

            width = height = visualFieldPixelSize * _visualFieldResolution;

            // Paint pixel outline grid.
            // Vertical lines.
            int x = GridLeft;

            for (int i = 0; i <= _visualFieldResolution; i++, x += visualFieldPixelSize)
            {
                g.DrawLine(__penGrey, x, GridTop, x, GridTop + height);
            }

            // Horizontal lines.
            int y = GridTop;

            for (int i = 0; i <= _visualFieldResolution; i++, y += visualFieldPixelSize)
            {
                g.DrawLine(__penGrey, GridLeft, y, GridLeft + width, y);
            }

            // Apply test case to black box's visual field sensor inputs.
            BoxesVisualDiscriminationEvaluator.ApplyVisualFieldToBlackBox(_testCaseField, box, _visualFieldResolution, _visualOriginPixelXY, _visualPixelSize);

            // Activate the black box.
            box.ResetState();
            box.Activate();

            // Read output responses and paint them to the pixel grid.
            // Also, we determine the range of values so that we can normalize the range of pixel shades used.
            double low, high;

            low = high = box.OutputSignalArray[0];
            for (int i = 1; i < box.OutputSignalArray.Length; i++)
            {
                double val = box.OutputSignalArray[i];
                if (val > high)
                {
                    high = val;
                }
                else if (val < low)
                {
                    low = val;
                }
            }

            double colorScaleFactor;

            if (0.0 == (high - low))
            {
                colorScaleFactor = 1.0;
            }
            else
            {
                colorScaleFactor = 1.0 / (high - low);
            }

            IntPoint maxActivationPoint = new IntPoint(0, 0);
            double   maxActivation      = -1.0;
            int      outputIdx          = 0;

            y = GridTop;
            for (int i = 0; i < _visualFieldResolution; i++, y += visualFieldPixelSize)
            {
                x = GridLeft;
                for (int j = 0; j < _visualFieldResolution; j++, x += visualFieldPixelSize, outputIdx++)
                {
                    double output = box.OutputSignalArray[outputIdx];
                    if (output > maxActivation)
                    {
                        maxActivation         = output;
                        maxActivationPoint._x = j;
                        maxActivationPoint._y = i;
                    }

                    Color color = GetResponseColor((output - low) * colorScaleFactor);
                    Brush brush = new SolidBrush(color);
                    g.FillRectangle(brush, x + 1, y + 1, visualFieldPixelSize - 2, visualFieldPixelSize - 2);
                }
            }

            // Paint lines around the small and large test case boxes to highlight them.
            // Small box.
            int testFieldPixelSize = (_visualFieldResolution / TestCaseField.TestFieldResolution) * visualFieldPixelSize;

            g.DrawRectangle(__penBoxOutline,
                            GridLeft + (_testCaseField.SmallBoxTopLeft._x * testFieldPixelSize),
                            GridTop + (_testCaseField.SmallBoxTopLeft._y * testFieldPixelSize),
                            testFieldPixelSize, testFieldPixelSize);

            // Large box.
            g.DrawRectangle(__penBoxOutline,
                            GridLeft + (_testCaseField.LargeBoxTopLeft._x * testFieldPixelSize),
                            GridTop + (_testCaseField.LargeBoxTopLeft._y * testFieldPixelSize),
                            testFieldPixelSize * 3, testFieldPixelSize * 3);

            // Draw red line around pixel with highest activation.
            g.DrawRectangle(__penSelectedPixel,
                            GridLeft + (maxActivationPoint._x * visualFieldPixelSize),
                            GridTop + (maxActivationPoint._y * visualFieldPixelSize),
                            visualFieldPixelSize, visualFieldPixelSize);

            Refresh();
        }
        /// <summary>
        /// Create and return a GenerationalNeatEvolutionAlgorithm object ready for running the NEAT algorithm/search. Various sub-parts
        /// of the algorithm are also constructed and connected up.
        /// This overload accepts a pre-built genome population and their associated/parent genome factory.
        /// </summary>
        public INeatEvolutionAlgorithm<NeatGenome> CreateEvolutionAlgorithm(IGenomeFactory<NeatGenome> genomeFactory, List<NeatGenome> genomeList)
        {
            // Create distance metric. Mismatched genes have a fixed distance of 10; for matched genes the distance is their weigth difference.
            IDistanceMetric distanceMetric = new ManhattanDistanceMetric(1.0, 0.0, 10.0);
            ISpeciationStrategy<NeatGenome> speciationStrategy = new ParallelKMeansClusteringStrategy<NeatGenome>(distanceMetric, _parallelOptions);

            // Create complexity regulation strategy.
            IComplexityRegulationStrategy complexityRegulationStrategy = ExperimentUtils.CreateComplexityRegulationStrategy(_complexityRegulationStr, _complexityThreshold);

            // Create the evolution algorithm.
            GenerationalNeatEvolutionAlgorithm<NeatGenome> ea = new GenerationalNeatEvolutionAlgorithm<NeatGenome>(_eaParams, speciationStrategy, complexityRegulationStrategy);

            // Create IBlackBox evaluator.
            BoxesVisualDiscriminationEvaluator evaluator = new BoxesVisualDiscriminationEvaluator(_visualFieldResolution);

            // Create genome decoder. Decodes to a neural network packaged with an activation scheme that defines a fixed number of activations per evaluation.
            IGenomeDecoder<NeatGenome,IBlackBox> genomeDecoder = CreateGenomeDecoder(_visualFieldResolution, _lengthCppnInput);

            // Create a genome list evaluator. This packages up the genome decoder with the genome evaluator.
            IGenomeEvaluator<NeatGenome> innerFitnessEvaluator = new ParallelGenomeFitnessEvaluator<NeatGenome, IBlackBox>(genomeDecoder, evaluator, _parallelOptions);

            // Wrap the list evaluator in a 'selective' evaulator that will only evaluate new genomes. That is, we skip re-evaluating any genomes
            // that were in the population in previous generations (elite genomes). This is determiend by examining each genome's evaluation info object.
            IGenomeEvaluator<NeatGenome> selectiveFitnessEvaluator = new SelectiveGenomeFitnessEvaluator<NeatGenome>(
                                                                                    innerFitnessEvaluator,
                                                                                    SelectiveGenomeFitnessEvaluator<NeatGenome>.CreatePredicate_OnceOnly());
            // Initialize the evolution algorithm.
            ea.Initialize(selectiveFitnessEvaluator, genomeFactory, genomeList);

            // Finished. Return the evolution algorithm
            return ea;
        }