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
        }