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; }