Beispiel #1
0
        public Expression CrossOver(Expression t1, Expression t2, double probswap = 0.7, bool top = true)
        {
            if (RndGenerator.RndDouble() < probswap && !top)
            {
                return(t2);
            }
            var result         = t1;
            var childrenExpsT1 = GetChildren(t1);
            var childrenExpsT2 = GetChildren(t2);

            if (childrenExpsT1 == null || childrenExpsT2 == null)
            {
                return(result);
            }
            var newChildren = new List <Expression>();

            foreach (var expression in childrenExpsT1)
            {
                newChildren.Add(CrossOver(expression, childrenExpsT2[RndGenerator.RndInt32(0, childrenExpsT2.Count)], probswap, false));
            }
            return(UpdateChildren(result, newChildren));
        }
Beispiel #2
0
        public static Expression MakeRandomTree(ParameterExpression[] paramExps, int maxTreeDepth = 4,
                                                double fpr = 0.5, double ppr = 0.6)
        {
            if (RndGenerator.RndDouble() < fpr && maxTreeDepth > 0)
            {
                (var funcExp, var pc) = ExpFactory.Choice();
                var children = new Expression[pc];
                for (int i = 0; i < pc; i++)
                {
                    children[i] = MakeRandomTree(paramExps, maxTreeDepth - 1, fpr, ppr);
                }
                return(funcExp(children));
            }

            else if (RndGenerator.RndDouble() < ppr)
            {
                return(paramExps[RndGenerator.RndInt32(0, paramExps.Length)]);
            }
            else
            {
                return(Expression.Constant(RndGenerator.RndInt32(0, 10)));
            }
        }
Beispiel #3
0
        public Func <int, int, int> Evolve(ParameterExpression[] pc, int popsize,
                                           Func <List <ValueTuple <Func <int, int, int>, Expression> >, List <ValueTuple <long, Func <int, int, int>, Expression> > > rankfunction, int maxgen = 500, double mutationrate = 0.1,
                                           double breedingreate = 0.4, double pexp = 0.7, double pnew = 0.05)
        {
            //返回一个随机数,通常是一个较小的数
            //pexp的取值越小,我们得到的随机数就越小
            Func <int> selectIndex = () => (int)(Math.Log(RndGenerator.RndDouble()) / Math.Log(pexp));

            // 创建一个随机的初始种群
            var population = new List <ValueTuple <Func <int, int, int>, Expression> >(popsize);

            for (int i = 0; i < popsize; i++)
            {
                var exp  = MakeRandomTree(pc);
                var func = exp.Compile <Func <int, int, int> >(pc);
                population.Add((func, exp));
            }
            List <ValueTuple <long, Func <int, int, int>, Expression> > scores = null;

            for (int i = 0; i < maxgen; i++)
            {
                scores = rankfunction(population);
                _outputWriter?.Invoke(scores[0].Item1);
                if (scores[0].Item1 == 0)
                {
                    break;
                }

                // 取两个最优的程序
                var newpop = new List <ValueTuple <Func <int, int, int>, Expression> >()
                {
                    (scores[0].Item2, scores[0].Item3),
                    (scores[1].Item2, scores[1].Item3)
                };

                //构造下一代
                while (newpop.Count < popsize)
                {
                    if (RndGenerator.RndDouble() > pnew)
                    {
                        var exp = Mutate(
                            CrossOver(scores[selectIndex()].Item3,
                                      scores[selectIndex()].Item3, breedingreate), pc, mutationrate);
                        var func = exp.Compile <Func <int, int, int> >(pc);
                        newpop.Add((func, exp));
                    }
                    else
                    {
                        //加入一个随机节点,增加种群的多样性
                        var exp  = MakeRandomTree(pc);
                        var func = exp.Compile <Func <int, int, int> >(pc);
                        newpop.Add((func, exp));
                    }
                }

                population = newpop;
            }
            var printer = new GpPrinter();

            _outputWriter?.Invoke(printer.Display(scores[0].Item3));
            return(scores[0].Item2);
        }