private void Initialization() { for (var i = 0; i < _colonySize; i++) { var x = new double[_fRange]; for (var j = 0; j < _fRange; j++) x[j] = -_func.Range + _rnd.NextDouble() * _func.Range * 2; _fireflies[i] = new Firefly { X = x, F = _func.F(x) }; } //CentroidalVoronoiTessellations(); }
/// <summary> /// Modifies initial set /// </summary> public void CentroidalVoronoiTessellations() { // Show result for function of 2 variables #region Initial print to image const int bmpSize = 1000; var bmp = new Bitmap(bmpSize, bmpSize); if (_fRange == 2) { const int dotSize = 3; foreach (var t in _fireflies) { var x = Convert.ToInt32(t.X[0] * bmpSize * .5 / _func.Range + bmpSize * .5); var y = Convert.ToInt32(t.X[1] * bmpSize * .5 / _func.Range + bmpSize * .5); for (var i1 = x - dotSize; i1 <= x + dotSize; i1++) for (var i2 = y - dotSize; i2 <= y + dotSize; i2++) if (0 <= i1 && i1 < bmp.Size.Height && 0 <= i2 && i2 < bmp.Size.Height) bmp.SetPixel(i1, i2, Color.Blue); } } #endregion var q = _colonySize * 100; var rnd = new Random(); const int centroidalVoronoiTessellationsIterations = 1000; for (var iteration = 0; iteration < centroidalVoronoiTessellationsIterations; iteration++) { // Choose q random points var qList = new List<Firefly>(q); for (var i = 0; i < q; i++) { qList.Add(new Firefly()); qList[i].X = new double[_fRange]; for (var j = 0; j < _fRange; j++) qList[i].X[j] = -_func.Range + rnd.NextDouble() * _func.Range * 2; } var qShortestDistanceTo = new List<int>(q); foreach (var point in qList) { var minDist = double.MaxValue; var minDistFirefly = 0; for (var j = 0; j < _colonySize; j++) { var r2 = _fireflies[j].X.Select((t, h) => Math.Pow(_fireflies[j].X[h] - point.X[h], 2)).Sum(); if (r2 < minDist) { minDist = r2; minDistFirefly = j; } } qShortestDistanceTo.Add(minDistFirefly); } // Calculate ai for (var i = 0; i < _colonySize; i++) { var ai = new Firefly(); ai.X = new double[_fRange]; for (var h = 0; h < _fRange; h++) ai.X[h] = 0; var isGeneratorForSomeone = false; var numberOfPoints = 0; for (var idx = 0; idx < qShortestDistanceTo.Count; idx++) if (qShortestDistanceTo[idx] == i) { isGeneratorForSomeone = true; numberOfPoints++; for (var h = 0; h < _fRange; h++) ai.X[h] += qList[idx].X[h]; } for (var h = 0; h < _fRange; h++) ai.X[h] /= numberOfPoints; if (isGeneratorForSomeone) for (var j = 0; j < _fRange; j++) _fireflies[i].X[j] += (ai.X[j] - _fireflies[i].X[j]) * .1; } Console.WriteLine($"Voronoi Tessellations Iteration #{iteration}"); } #region Final print to image // Show result for function of 2 variables if (_fRange == 2) { const int dotSize = 3; foreach (var t in _fireflies) { var x = Convert.ToInt32(t.X[0] * bmpSize * .5 / _func.Range + bmpSize * .5); var y = Convert.ToInt32(t.X[1] * bmpSize * .5 / _func.Range + bmpSize * .5); //Console.WriteLine($"{t.X[0],4} -> {x,4}"); //Console.WriteLine($"{t.X[1],4} -> {y,4}"); for (var i1 = x - dotSize; i1 <= x + dotSize; i1++) for (var i2 = y - dotSize; i2 <= y + dotSize; i2++) if (0 <= i1 && i1 < bmp.Size.Height && 0 <= i2 && i2 < bmp.Size.Height) bmp.SetPixel(i1, i2, Color.Red); } bmp.Save("Initial Generation.png"); } #endregion }