public bool StopConditionSatisfied => false; // real world evaluators should have logic to know when to stop public FitnessInfo Evaluate(IBlackBox phenome) { const double LARGESTERROR = 10000; TrackedItemHarness harness = null; lock (_lock) { harness = new TrackedItemHarness(_harnessArgs); } harness.ItemRemoved += (s1, e1) => { harness.SetItem(GetNewItem(harness, _evalArgs)); }; harness.SetItem(GetNewItem(harness, _evalArgs)); // Input Array (pixels) double[] inputArr = new double[harness.InputSizeXY * harness.InputSizeXY]; double dotRadius = (harness.VisionSize / harness.InputSizeXY) * Math.Sqrt(2); // Output Array (pixels) double[] outputArr = new double[harness.OutputSizeXY * harness.OutputSizeXY]; Tuple <TrackedItemBase, Point, Vector> prevPos, currentPos; double error = 0; for (int cntr = 0; cntr < _evalArgs.TotalNumberEvaluations; cntr++) { harness.Tick(_evalArgs.ElapsedTime_Seconds); GetPrevCurrentPositions(out prevPos, out currentPos, harness, _evalArgs); // Apply Input ClearArray(inputArr); if (prevPos != null) { ApplyPoint(inputArr, harness.InputCellCenters, dotRadius, prevPos.Item2, true); } // Brain.Tick phenome.InputSignalArray.CopyFrom(inputArr, 0); phenome.Activate(); phenome.OutputSignalArray.CopyTo(outputArr, 0); // Evaluate output double[] expectedOutput = GetExpectedOutput(currentPos, harness, _evalArgs); error += CompareOutputs(outputArr, expectedOutput, ERRORMULT, _evalArgs.ErrorBias); } // Figure out what the worst possible error could be //double largestError = ERRORMULT * ERRORMULT * outputArr.Length * _evalArgs.TotalNumberEvaluations; double largestError = ERRORMULT * ERRORMULT * _evalArgs.TotalNumberEvaluations; // don't include outputArr.Length. CompareOutputs() divides that out // Scale it down to 10000 if (largestError > LARGESTERROR) { error *= LARGESTERROR / largestError; largestError = LARGESTERROR; } // SharpNEAT wants a top score instead of error, so flip it double score = largestError - error; _evaluationCount++; return(new FitnessInfo(score, score)); }
private void Timer_Tick_REAL(object sender, EventArgs e) { // This uses actual time elapsed, and runs continuously, grabbing a new neural net every 10 seconds try { imageInput.Source = null; canvasMain.Children.Clear(); DateTime now = DateTime.UtcNow; if (_harness == null) { _prevTick = now; return; } // Tell the harness to go _harness.Tick((now - _prevTick).TotalSeconds); var prevPosition = _harness.GetPreviousPosition(_harness.Time - _evalArgs.Delay_Seconds); var currentPosition = _harness.Item; if (_experiment != null && (_winningBrain == null || (now - _winningBrainTime).TotalSeconds > 10)) { NeatGenome winner = _ea.CurrentChampGenome; _genomeViewer.RefreshView(winner); _winningBrain = _experiment.GetBlackBox(winner); _winningBrainTime = now; } #region draw input double[] inputArr = new double[_harness.InputSizeXY * _harness.InputSizeXY]; AntPos_Evaluator.ClearArray(inputArr); if (prevPosition != null) { double dotRadius = (_harness.VisionSize / _harness.InputSizeXY) * Math.Sqrt(2); AntPos_Evaluator.ApplyPoint(inputArr, _harness.InputCellCenters, dotRadius, prevPosition.Item2, true); } imageInput.Source = UtilityWPF.GetBitmap(inputArr, _harness.InputSizeXY, _harness.InputSizeXY, invert: true); #endregion #region draw expected output double[] expectedOutput = null; if (currentPosition == null) { expectedOutput = AntPos_Evaluator.GetExpectedOutput(null, _harness, _evalArgs); } else { var currentPos = Tuple.Create(currentPosition, currentPosition.Position, currentPosition.Velocity); expectedOutput = AntPos_Evaluator.GetExpectedOutput(currentPos, _harness, _evalArgs); } imageExpectedOutput.Source = UtilityWPF.GetBitmap(expectedOutput, _harness.OutputSizeXY, _harness.OutputSizeXY, invert: true); #endregion #region draw nn output double[] nnOutput = null; if (_winningBrain != null) { nnOutput = new double[_harness.OutputSizeXY * _harness.OutputSizeXY]; // Brain.Tick _winningBrain.InputSignalArray.CopyFrom(inputArr, 0); _winningBrain.Activate(); _winningBrain.OutputSignalArray.CopyTo(nnOutput, 0); imageNNOutput.Source = UtilityWPF.GetBitmap(nnOutput, _harness.OutputSizeXY, _harness.OutputSizeXY, invert: true); } else { imageNNOutput.Source = null; } #endregion #region draw error (nn - expected) double[] error = null; if (nnOutput != null) { error = Enumerable.Range(0, nnOutput.Length). Select(o => Math.Abs(nnOutput[o] - expectedOutput[o])). ToArray(); imageError.Source = UtilityWPF.GetBitmap(error, _harness.OutputSizeXY, _harness.OutputSizeXY, invert: true); } else { imageError.Source = null; } #endregion #region draw actual // Vision Rectangle Rectangle visionRect = new Rectangle() { Stroke = Brushes.Silver, StrokeThickness = .3, Width = _harness.VisionSize, Height = _harness.VisionSize, }; Canvas.SetLeft(visionRect, _harness.VisionSize / -2); Canvas.SetTop(visionRect, _harness.VisionSize / -2); canvasMain.Children.Add(visionRect); // Dot Previous if (prevPosition != null) { Ellipse dot = new Ellipse() { Fill = new SolidColorBrush(prevPosition.Item1.Color), Stroke = Brushes.Black, StrokeThickness = .3, Width = 2, Height = 2, }; Canvas.SetLeft(dot, prevPosition.Item2.X - 1); Canvas.SetTop(dot, prevPosition.Item2.Y - 1); canvasMain.Children.Add(dot); } // Dot Current if (currentPosition != null) { Ellipse dot = new Ellipse() { Fill = new SolidColorBrush(currentPosition.Color), Stroke = Brushes.White, StrokeThickness = .3, Width = 2, Height = 2, }; Canvas.SetLeft(dot, currentPosition.Position.X - 1); Canvas.SetTop(dot, currentPosition.Position.Y - 1); canvasMain.Children.Add(dot); } // Transform TransformGroup transform = new TransformGroup(); transform.Children.Add(new ScaleTransform(canvasMain.ActualWidth / _harness.MapSize, canvasMain.ActualHeight / _harness.MapSize)); transform.Children.Add(new TranslateTransform(canvasMain.ActualWidth / 2, canvasMain.ActualHeight / 2)); canvasMain.RenderTransform = transform; #endregion _prevTick = now; } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }