#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 System.Text;
using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
public static class SchemaUtil {
private static readonly Dictionary ShortNames = new Dictionary {
{ "Addition", "+" },
{ "Subtraction", "-" },
{ "Multiplication", "*" },
{ "Division", "/" },
{ "Logarithm", "Log" },
{ "Exponential", "Exp" }
};
public static void ReplaceSubtree(ISymbolicExpressionTreeNode original, ISymbolicExpressionTreeNode replacement, bool preserveChildren = true) {
var parent = original.Parent;
if (parent == null)
throw new ArgumentException("Parent cannot be null for node " + original);
var index = parent.IndexOfSubtree(original);
parent.RemoveSubtree(index);
parent.InsertSubtree(index, replacement);
if (preserveChildren) {
var subtrees = original.Subtrees.ToList();
for (int i = subtrees.Count - 1; i >= 0; --i)
original.RemoveSubtree(i);
for (int i = 0; i < subtrees.Count; ++i) {
replacement.AddSubtree(subtrees[i]);
}
}
}
public static string FormatToString(this ISymbolicExpressionTreeNode node, bool strict = false) {
StringBuilder strBuilder = new StringBuilder();
// internal nodes or leaf nodes?
if (node is AnySubtree)
return "# ";
if (node.SubtreeCount > 0) {
strBuilder.Append("(");
// symbol on same line as '('
string label = string.Empty;
if (node is AnyNode)
label = "=";
else {
string shortName;
ShortNames.TryGetValue(node.Symbol.Name, out shortName);
label = string.IsNullOrEmpty(shortName) ? node.Symbol.Name : shortName;
}
strBuilder.Append(label + " ");
// each subtree expression on a new line
// and closing ')' also on new line
foreach (var subtree in node.Subtrees) {
strBuilder.Append(subtree.FormatToString(strict));
}
strBuilder.Append(") ");
} else {
// symbol in the same line with as '(' and ')'
var v = node as VariableTreeNode;
var c = node as ConstantTreeNode;
var w = node as AnyNode; // wildcard
string label = string.Empty;
if (w != null)
label = "=";
else if (v != null)
label = strict ? string.Format("{0:0.00}_{1}", v.Weight, v.VariableName) : string.Format("{0}", v.VariableName);
else if (c != null)
label = strict ? string.Format("{0:0.00}", c.Value) : "C";
strBuilder.Append(label);
if (node.Parent != null && node != node.Parent.Subtrees.Last())
strBuilder.Append(" ");
//strBuilder.Append(")");
}
return strBuilder.ToString();
}
}
}