#region License Information /* HeuristicLab * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using System; using System.Collections.Generic; using System.Linq; using HeuristicLab.Core; using HeuristicLab.Random; namespace HeuristicLab.ExpressionGenerator { public abstract class ExpressionTemplate { private List> arguments; private readonly Func, double> transform; private readonly string label; protected Expression Instantiate(IRandom random, int n, bool sampleWithRepetition = false) { var weights = arguments.Select(x => x.Item2); var args = sampleWithRepetition ? arguments.SampleProportional(random, n, weights).Select(x => x.Item1) : arguments.SampleProportionalWithoutRepetition(random, n, weights).Select(x => x.Item1); return Expression.Function(label, transform, args); } public abstract Expression Instantiate(IRandom random, bool sampleWithRepetition = false); protected ExpressionTemplate(string label, Func, double> transform) { this.transform = transform; this.label = label; } public void AddArgument(Expression expression, double priority = 1d) { arguments = arguments ?? new List>(); arguments.Add(Tuple.Create(expression, priority)); } public void AddArguments(IEnumerable expressions) { arguments = arguments ?? new List>(); arguments.AddRange(expressions.Select(x => Tuple.Create(x, 1d))); } public void AddArguments(IEnumerable expressions, IEnumerable priorities) { arguments = arguments ?? new List>(); arguments.AddRange(expressions.Zip(priorities, Tuple.Create)); } } public class RandomArityTemplate : ExpressionTemplate { private readonly IRandom arityDistribution; public RandomArityTemplate(string label, Func, double> transform, IRandom arityDistribution) : base(label, transform) { this.arityDistribution = arityDistribution; } public override Expression Instantiate(IRandom random, bool sampleWithRepetition = false) { var arity = (int)Math.Round(arityDistribution.NextDouble()); return Instantiate(random, arity, sampleWithRepetition); } } public class FixedArityTemplate : ExpressionTemplate { private readonly int arity; public FixedArityTemplate(string label, Func, double> transform, int arity) : base(label, transform) { this.arity = arity; } public override Expression Instantiate(IRandom random, bool sampleWithRepetition = false) { return Instantiate(random, arity, sampleWithRepetition); } } }