示例#1
0
        public static (double, double) GeneticAlg(
            Func <double, double> f,
            int numberOfGuys,
            int numberOfIterations
            )
        {
            var generation = new Bit22[numberOfGuys];

            //Wygeneruj osobniki
            for (int i = 0; i < numberOfGuys; i++)
            {
                var x = Program.GetRandomNumber(-1, 2);
                generation[i] = new Bit22((decimal)x);
            }

            Bit22 bestValue = null;

            for (int i = 0; i < numberOfIterations; i++)
            {
                generation = Fit(generation, out bestValue, f);
                generation = CrossOver(generation);
                generation = Mutate(generation).ToArray();
            }

            return((double)bestValue.decValue, (f((double)bestValue.decValue)));
        }
示例#2
0
        public static decimal GetClostest(decimal p1, int bitIdx)
        {
            if (bitIdx < 0 || bitIdx > 21)
            {
                throw new Exception("Out of range");
            }

            var p1b      = new Bit22(p1).CopyAndMutate(bitIdx);
            int intValue = Math.Abs(Convert.ToInt32(p1b.value, 2));

            return(-1 + (intValue * 0.000001m));
        }
示例#3
0
        public static Bit22[] Fit(Bit22[] generation, out Bit22 fittest, Func <double, double> f)
        {
            fittest = generation
                      .Select(x => new
            {
                x   = x,
                val = f((double)x.decValue)
            })
                      .OrderByDescending(x => x.val)
                      .First().x;

            var values = generation.Select(x =>
                                           f((double)x.decValue));

            var sum = values.Sum();
            int populationNumber      = 4;
            var nextPopulationNumbers = values.OrderByDescending(x => x).Select(x =>
            {
                var current = (int)Math.Abs(Math.Round(generation.Length * x / sum));
                if (populationNumber >= current)
                {
                    populationNumber -= current;
                    return(current);
                }
                else
                {
                    populationNumber = 0;
                    return(populationNumber);
                }
            }).ToList();

            var all = nextPopulationNumbers.Sum(x => x);

            if (all < 4)
            {
                int toAdd = 4 - all;
                int max   = nextPopulationNumbers.Max();
                nextPopulationNumbers[0] = nextPopulationNumbers[0] + toAdd;
            }

            var nextPopulation = new List <Bit22>();

            for (int i = 0; i < generation.Length; i++)
            {
                for (int j = 0; j < nextPopulationNumbers[i]; j++)
                {
                    nextPopulation.Add(new Bit22(generation[i].decValue));
                }
            }
            return(nextPopulation.ToArray());
        }
示例#4
0
        public static Bit22[] CrossOver(Bit22[] generation)
        {
            List <Bit22> newGen = new List <Bit22>();

            for (int i = 0; i < generation.Length; i++)
            {
                // get random partner
                int   partner  = RandomExcept(0, generation.Length, i);
                int   crossBit = RandomExcept(0, 21, -1);
                Bit22 child    = generation[i].Cross(generation[partner], crossBit);
                newGen.Add(child);
            }
            return(newGen.ToArray());
        }
示例#5
0
        public Bit22 CopyAndMutate(decimal min, decimal max)
        {
            Random rnd    = new Random();
            var    newBit = new Bit22(this.value);

            do
            {
                var  bitIdx      = rnd.Next(0, 21);
                char valueAt     = this.value[bitIdx];
                var  stringValue = new StringBuilder(this.value)
                                   .Remove(bitIdx, 1)
                                   .Insert(bitIdx, valueAt == '1' ? '0' : '1')
                                   .ToString();
                newBit = new Bit22(stringValue);
            }while(newBit.decValue < min || newBit.decValue > max);

            return(newBit);
        }
示例#6
0
        public static (double, double) GradMultipleClostests(double x, Func <double, double> f, double step, int maxIter = 1000)
        {
            int    iter = 0;
            double max  = -1000000;

            while (iter < maxIter)
            {
                double p1       = f(x);
                double clostest = (double)Bit22.GetClostestOne((decimal)x, 1, f);
                double p2       = f(clostest);
                if (p1 > p2)
                {
                    return(p1, x);
                }
                max = p2;
                iter++;
            }
            return(max, x + step);
        }
示例#7
0
        public static decimal[] GetClostestMultipleBits(decimal p1, int bitCount)
        {
            if (bitCount < 0 || bitCount > 21)
            {
                throw new Exception("Out of range");
            }

            var res = new decimal[bitCount];

            for (int i = 0; i < bitCount; i++)
            {
                var resultBit = new Bit22(p1).CopyAndMutate(21 - i);
                int intValue  = Math.Abs(Convert.ToInt32(resultBit.value, 2));
                if (intValue > 3000000)
                {
                    intValue = 3000000;
                }
                res[i] = -1 + (intValue * 0.000001m);
            }
            return(res);
        }
示例#8
0
 public Bit22 Cross(Bit22 partner, int bitNumber)
 {
     return(new Bit22(partner.value.Substring(0, bitNumber) + this.value.Substring(bitNumber, 22 - bitNumber)));
 }
示例#9
0
        static void Main(string[] args)
        {
            var                     b                = new Bit22(3);
            int                     iter             = 10;
            List <double>           values           = new List <double>();
            List <(double, double)> resGrad          = new List <(double, double)>();
            List <(double, double)> simpleGradResult = new List <(double, double)>();
            List <(double, double)> resAnn           = new List <(double, double)>();
            Func <double, double>   f                = x => x *Math.Sin(10 *Math.PI *x) + 1;

            for (int i = 0; i < iter; i++)
            {
                values.Add(GetRandomNumber(-1, 2));
            }

            var sw = new Stopwatch();

            sw.Start();
            foreach (var x in values)
            {
                resGrad.Add(Optimizer.GradMultipleClostests(x, f, 0.001f, 1));
            }
            sw.Stop();
            var gradT = sw.ElapsedMilliseconds;

            sw.Start();
            foreach (var x in values.Take(1))
            {
                simpleGradResult.Add(Optimizer.SimpleGrad(x, f, 0.001f, 1));
            }
            sw.Stop();
            var simpleGradT = sw.ElapsedMilliseconds;

            sw = new Stopwatch();
            sw.Start();
            foreach (var x in values)
            {
                resAnn.Add(Optimizer.Annealing(x, f, 0.0000001, .9999, 100));
            }
            sw.Stop();
            var annT = sw.ElapsedMilliseconds;

            var maxGrad    = resGrad.OrderByDescending(x => x.Item1).First();
            var simpleGrad = simpleGradResult.OrderByDescending(x => x.Item1).First();
            var maxAnn     = resAnn.OrderByDescending(x => x.Item1).First();

            sw = new Stopwatch();
            sw.Start();
            var genetic = Optimizer.GeneticAlg(f, 10, 1000);

            sw.Stop();
            var genT = sw.ElapsedMilliseconds;

            //Console.WriteLine($"f({maxGrad.Item2}) = {maxGrad.Item1} T={gradT}");
            // Console.WriteLine($"f({simpleGrad.Item2}) = {simpleGrad.Item1} T={simpleGradT}");
            // Console.WriteLine($"f({maxAnn.Item2}) = {maxAnn.Item1}");
            Console.WriteLine($"f({genetic.Item2}) = {genetic.Item1}, T={genT}");


            //var bit = new Bit22(-0.999999m);
            //var clostest = Bit22.GetClostest(-0.999998m, 21);
            //Console.WriteLine(clostest);
            //TestGrad(f);
        }