private static ITreeProgram <TOutput> Replace <TOutput>( this ITreeProgram <TOutput> program, ref uint index, ITreeProgram <TOutput> newSubProgram) { if (program == null) { return(default(ITreeProgram <TOutput>)); } if (index == 0) { return(newSubProgram); } if (program.Input == null) { return(program); } var newChildren = program.Input.ToArray(); for (var i = 0; i < program.Input.Count; i++) { index--; newChildren[i] = Replace(program.Input[i], ref index, newSubProgram); if (index == 0) { break; } } return(program.CreateNew(newChildren)); }
/// <summary> /// Gets a new copy of <paramref name="program" /> where all sub-programs that are equal to /// <paramref name="oldSubProgram" /> are replaced by <paramref name="newSubProgram" />. /// </summary> /// <param name="program">The root program to copy and search for the given sub-program .</param> /// <param name="oldSubProgram">The sub-program we want to replace.</param> /// <param name="newSubProgram">The new sub-program to replace the given one.</param> /// <returns> /// A copy of the program with the given descendant replaced by the new program. If the given program is equal to the /// sub-program we want to replace, then the replacement is returned. If the given sub-program is not found, a copy of /// the original program is returned, or <c>null</c> if the program is <c>null</c>. /// </returns> /// <typeparam name="TOutput">The type of program output.</typeparam> public static ITreeProgram <TOutput> Replace <TOutput>( this ITreeProgram <TOutput> program, ITreeProgram <TOutput> oldSubProgram, ITreeProgram <TOutput> newSubProgram) { if (program == null || oldSubProgram == null || newSubProgram == null) { return(program); } // checks if program is equal, return replacement if (program.Equals(oldSubProgram)) { return(newSubProgram); } // replaces children recursively and creates a new program if (program.Input == null || program.Input.Count == 0) { return(program); } var children = new ITreeProgram <TOutput> [program.Input.Count]; for (var i = 0; i < program.Input.Count; i++) { children[i] = Replace(program.Input[i], oldSubProgram, newSubProgram); } return(program.CreateNew(children)); }
/// <summary> /// Computes a <see cref="Range" /> representing the minimum and maximum values that a given <see cref="MathProgram" /> /// can compute, as dictated by its sub-programs. /// </summary> /// <param name="program">The program whose range we want to compute.</param> /// <returns>The range of the given program.</returns> public static Range GetRange(this ITreeProgram <double> program) { // checks for constant value if (program.IsConstant()) { var value = program.Compute(); return(new Range(value, value)); } // checks for variable if (program is Variable) { return(((Variable)program).Range); } // collects info on ranges of all children var childrenRanges = new List <IEnumerable <double> >(); foreach (var child in program.Input) { var childRange = GetRange(child); childrenRanges.Add(new[] { childRange.Min, childRange.Max }); } // gets all combinations between children ranges var min = double.MaxValue; var max = double.MinValue; var allRangeCombinations = childrenRanges.GetAllCombinations(); foreach (var rangeCombination in allRangeCombinations) { // builds new program by replacing children with constant values (range min or max) var children = new ITreeProgram <double> [rangeCombination.Count]; for (var i = 0; i < rangeCombination.Count; i++) { children[i] = new Constant(rangeCombination[i]); } var newElem = program.CreateNew(children); // checks min and max values from new prog value var val = newElem.Compute(); min = Math.Min(min, val); max = Math.Max(max, val); } return(new Range(min, max)); }
private static ISet <ITreeProgram <TOutput> > GetSubCombs <TOutput>(ITreeProgram <TOutput> program) { var combs = new HashSet <ITreeProgram <TOutput> >(); if (program == null) { return(combs); } // checks no more children if (program.IsLeaf()) { combs.Add(program); return(combs); } // gets sub-programs from all children var childrenSubCombs = new List <IEnumerable <ITreeProgram <TOutput> > >(); foreach (var child in program.Input) { var childSubCombs = GetSubCombs(child); childrenSubCombs.Add(childSubCombs); // adds the sub-combinations of children to combination list foreach (var childSubComb in childSubCombs) { combs.Add(childSubComb); } } // creates new programs where each child is replaced by some sub-combination of it var allChildrenCombs = childrenSubCombs.GetAllCombinations(); foreach (var children in allChildrenCombs) { if (children.Count == program.Input.Count) { combs.Add(program.CreateNew(children)); } } childrenSubCombs.Clear(); return(combs); }
private static ITreeProgram <double> ReplaceVariables( this ITreeProgram <double> program, IDictionary <Variable, Variable> customVars) { // if program is not a variable, tries to replace all children recursively var variable = program as Variable; if (variable == null) { return(program.CreateNew(program.Input?.Select(child => child.ReplaceVariables(customVars)) .ToList())); } // checks if a corresponding variable has not yet been created if (!customVars.ContainsKey(variable)) { customVars.Add(variable, new Variable($"{VAR_NAME_STR}{customVars.Count}")); } // replaces it by the custom variable return(customVars[variable]); }
private static void GetLeaves <TOutput>( this ITreeProgram <TOutput> program, IDictionary <ITreeProgram <TOutput>, uint> leaves) { // checks program is leaf, add to set and update count if (program.Input == null || program.Input.Count == 0) { var leaf = program.CreateNew(new List <ITreeProgram <TOutput> >()); if (!leaves.ContainsKey(leaf)) { leaves.Add(leaf, 0); } leaves[leaf]++; return; } // searches children if (program.Input != null) { foreach (var child in program.Input) { GetLeaves(child, leaves); } } }