public void TestMakeRandomTree() { var input1ParamExp = Expression.Parameter(typeof(int), "input1"); var input2ParamExp = Expression.Parameter(typeof(int), "input2"); var paramArr = new[] { input1ParamExp, input2ParamExp }; var random1 = Gp.MakeRandomTree(paramArr); var printer = new GpPrinter(); TestOutput(printer.Display(random1)); var func = Expression.Lambda <Func <int, int, int> >(random1, paramArr).Compile(); TestOutput(func(7, 1)); TestOutput(func(2, 4)); var random2 = Gp.MakeRandomTree(paramArr); TestOutput(printer.Display(random2)); var func2 = Expression.Lambda <Func <int, int, int> >(random2, paramArr).Compile(); TestOutput(func2(5, 3)); TestOutput(func2(5, 20)); }
public void TestExpressionTreeMutate() { var xParamExp = Expression.Parameter(typeof(int), "x"); var yParamExp = Expression.Parameter(typeof(int), "y"); var returnLabel = Expression.Label(typeof(int)); var blockExp = Expression.Block( Expression.IfThenElse( //if判断 Expression.GreaterThan(xParamExp, Expression.Constant(3)), //if为true执行 Expression.Return(returnLabel, Expression.Add(yParamExp, Expression.Constant(5))), //else执行 Expression.Return(returnLabel, Expression.Subtract(yParamExp, Expression.Constant(2))) ), Expression.Label(returnLabel, Expression.Constant(0)) ); var printer = new GpPrinter(); TestOutput(printer.Display(blockExp)); var mutater = new ExpTestMutate(); var newExp = mutater.Mutate(blockExp); TestOutput(printer.Display(newExp)); }
public void TestMutate() { var gp = new Gp(); var input1ParamExp = Expression.Parameter(typeof(int), "input1"); var input2ParamExp = Expression.Parameter(typeof(int), "input2"); var paramArr = new[] { input1ParamExp, input2ParamExp }; var random1 = Gp.MakeRandomTree(paramArr); var printer = new GpPrinter(); TestOutput(printer.Display(random1)); TestOutput("-----------我是分隔线-------------"); var newExp = gp.Mutate(random1, paramArr); TestOutput(printer.Display(newExp)); }
public void TestCrossOver() { var gp = new Gp(); var printer = new GpPrinter(); var input1ParamExp = Expression.Parameter(typeof(int), "input1"); var input2ParamExp = Expression.Parameter(typeof(int), "input2"); var paramArr = new[] { input1ParamExp, input2ParamExp }; var random1 = Gp.MakeRandomTree(paramArr); TestOutput(printer.Display(random1)); TestOutput("-----------我是分隔线-------------"); var random2 = Gp.MakeRandomTree(paramArr); TestOutput(printer.Display(random2)); TestOutput("-----------我是分隔线-------------"); var crossed = gp.CrossOver(random1, random2); TestOutput(printer.Display(crossed)); }
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); }