public static IInd Mutation(IInd inpStringInd, double rate)
        {
            double[] values = inpStringInd.getDoubleArray();
            for (int i = 0; i < values.Length; i++)
            {
                var r = Rand.NextDouble();
                if (r <= rate)
                {
                    values[i] = Rand.NextDouble() * (maxVal - minVal) + minVal;
                }
            }
            IInd res = new DoubleInd(values);
            return res;

        }
        public static Tuple<IInd, IInd> Crossover(Tuple<IInd, IInd> inp)
        {
            //Two point crossover
            var p1Bits = inp.Item1.getDoubleArray();
            var p2Bits = inp.Item2.getDoubleArray();

            var c1Bits = new double[p1Bits.Length];
            p1Bits.CopyTo(c1Bits, 0);
            var c2Bits = new double[p1Bits.Length];
            p2Bits.CopyTo(c2Bits, 0);

            var splitpoint1 = Rand.Next(1, p1Bits.Length - 1);
            var splitpoint2 = Rand.Next(splitpoint1 + 1, p1Bits.Length);

            for (int i = splitpoint1; i <= splitpoint2; i++)
            {
                c1Bits[i] = p2Bits[i];
                c2Bits[i] = p1Bits[i];
            }

            IInd child1 = new DoubleInd(c1Bits);
            IInd child2 = new DoubleInd(c2Bits);

            return new Tuple<IInd, IInd>(child1, child2);
        }