#region License Information /* HeuristicLab * Copyright (C) 2002-2008 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 System.Text; using HeuristicLab.Core; using HeuristicLab.Operators; using HeuristicLab.Functions; using HeuristicLab.Data; namespace HeuristicLab.StructureIdentification { public class PopulationAnalyser : OperatorBase { public override string Description { get { return @"Generates statistics about the population. (for debugging)"; } } public PopulationAnalyser() : base() { } public override IOperation Apply(IScope topScope) { Scope resultsScope = new Scope("Pop. analyzer results"); IScope scope = topScope.SubScopes[0]; var functionTrees = scope.SubScopes.Select(s => s.GetVariableValue("OperatorTree", false)); var treeSizes = scope.SubScopes.Select(s => s.GetVariableValue("TreeSize", false).Data); var treeHeights = scope.SubScopes.Select(s => s.GetVariableValue("TreeHeight", false).Data); var qualities = scope.SubScopes.Select(s => s.GetVariableValue("Quality", false).Data); var allFunctions = functionTrees.Select(t => AllNodes(t)).Aggregate((x, y) => { x.AddRange(y); return x; }); //var results = scope.SubScopes.Select(s => (DoubleArrayData)s.GetVariableValue("Results", false)); //var resultSums = results.Select(a => a.Data.Aggregate(0.0, (x, y) => x + y)); var functionsHistogram = from f in allFunctions group f by ((StringData)f.GetVariable("TypeId").Value).Data into g select new { FunctionType = g.Key, Functions = g }; resultsScope.AddVariable(new HeuristicLab.Core.Variable("AvgTreeSize", new DoubleData(treeSizes.Average()))); resultsScope.AddVariable(new HeuristicLab.Core.Variable("MinTreeSize", new DoubleData(treeSizes.Min()))); resultsScope.AddVariable(new HeuristicLab.Core.Variable("MaxTreeSize", new DoubleData(treeSizes.Max()))); resultsScope.AddVariable(new HeuristicLab.Core.Variable("AvgTreeHeight", new DoubleData(treeHeights.Average()))); resultsScope.AddVariable(new HeuristicLab.Core.Variable("MinTreeHeight", new DoubleData(treeHeights.Min()))); resultsScope.AddVariable(new HeuristicLab.Core.Variable("MaxTreeHeight", new DoubleData(treeHeights.Max()))); resultsScope.AddVariable(new HeuristicLab.Core.Variable("AvgQuality", new DoubleData(qualities.Average()))); resultsScope.AddVariable(new HeuristicLab.Core.Variable("MinQuality", new DoubleData(qualities.Min()))); resultsScope.AddVariable(new HeuristicLab.Core.Variable("MaxQuality", new DoubleData(qualities.Max()))); ItemList list = new ItemList(); PrefixVisitor visitor = new PrefixVisitor(); foreach(IFunction function in functionTrees) { visitor.Reset(); function.Accept(visitor); list.Add(new StringData(visitor.Representation)); } resultsScope.AddVariable(new HeuristicLab.Core.Variable("Functions", list)); topScope.SubScopes[1].AddSubScope(resultsScope); return null; } private List AllNodes(IFunction f) { List result = new List(); result.Add(f); if(f.SubFunctions.Count == 0) { return result; } else return f.SubFunctions.Select(subFunction => AllNodes(subFunction)).Aggregate(result, (x, y) => { x.AddRange(y); return x; }); } private class PrefixVisitor : IFunctionVisitor { private string representation; public string Representation { get { return representation; } } public void Reset() { representation = ""; } private void VisitFunction(string name, IFunction f) { representation += "(" + name; foreach(IFunction subFunction in f.SubFunctions) { representation += " "; subFunction.Accept(this); } representation += ")"; } #region IFunctionVisitor Members public void Visit(IFunction function) { representation += function.Name; } public void Visit(Addition addition) { VisitFunction("+", addition); } public void Visit(Constant constant) { representation += constant.Value.Data.ToString("F2"); } public void Visit(Cosinus cosinus) { VisitFunction("cos", cosinus); } public void Visit(Division division) { VisitFunction("/", division); } public void Visit(Exponential exponential) { VisitFunction("expt", exponential); } public void Visit(Logarithm logarithm) { VisitFunction("log", logarithm); } public void Visit(Multiplication multiplication) { VisitFunction("*", multiplication); } public void Visit(Power power) { VisitFunction("pow", power); } public void Visit(Signum signum) { VisitFunction("signum", signum); } public void Visit(Sinus sinus) { VisitFunction("sinus", sinus); } public void Visit(Sqrt sqrt) { VisitFunction("sqrt", sqrt); } public void Visit(Substraction substraction) { VisitFunction("-", substraction); } public void Visit(Tangens tangens) { VisitFunction("tan", tangens); } public void Visit(HeuristicLab.Functions.Variable variable) { string offsetStr; if(variable.SampleOffset > 0) { offsetStr = "(+ t " + variable.SampleOffset + ")"; } else if(variable.SampleOffset < 0) { offsetStr = "(- t " + -variable.SampleOffset + ")"; } else { offsetStr = "(t)"; } int v = variable.VariableIndex; representation+= "(* " + variable.Weight.ToString("F2") + " " + variable.Name + v + offsetStr + ")"; } public void Visit(And and) { VisitFunction("and", and); } public void Visit(Average average) { VisitFunction("average", average); } public void Visit(IfThenElse ifThenElse) { VisitFunction("if-then-else", ifThenElse); } public void Visit(Not not) { VisitFunction("not", not); } public void Visit(Or or) { VisitFunction("or", or); } public void Visit(Xor xor) { VisitFunction("xor", xor); } public void Visit(Equal equal) { VisitFunction("eq?", equal); } public void Visit(LessThan lessThan) { VisitFunction("<", lessThan); } #endregion } } }