/// <summary> /// Looks for the child that gets activated for the given value. /// </summary> /// <param name="value">The value to find the fitting child for.</param> /// <param name="child">Outputs the child if one was found, else null.</param> /// <exception cref="ArgumentException">Thrown if the given value is not a legal value for the node.</exception> /// <returns>Whether the child was found.</returns> public bool TryGetChild(object value, out IParameterTreeNode child) { // Check given value's type. if (!(value is T)) { throw new ArgumentException( $"Tried to get child of {typeof(T)} OR node for a value of type {value.GetType()}"); } // If correct type, check if value is legal and throw an exception if it isn't. var typedValue = (T)value; this.ThrowIfIllegal(typedValue); // Correct type & legal value --> set child and return. return(this._children.TryGetValue(typedValue, out child)); }
public void ChildrenAreReturnedCorrectly() { // Add several children... var children = new List <IParameterTreeNode>(); var domainValues = OrNodeTest.Domain.PossibleValues; for (int i = 0; i < domainValues.Count; i++) { IParameterTreeNode child = OrNodeTest.CreateNode(domainValues[i] + "_child"); children.Add(child); this._decisionNode.AddChild(domainValues[i], child); } // ..and compare them with the returned set when querying for the node's children. Assert.True( TestUtils.SetsAreEquivalent(children, this._decisionNode.Children), $"Added children {TestUtils.PrintList(children)}, but return value was {TestUtils.PrintList(this._decisionNode.Children)}"); }
public void ChildrenAreReturnedCorrectly() { var andNode = new AndNode(); // Add several children... var childIdentifiers = new List <string> { "a", "b", "c", "d" }; var children = new List <IParameterTreeNode>(); for (int i = 0; i < childIdentifiers.Count; i++) { IParameterTreeNode child = AndNodeTest.CreateNode(childIdentifiers[i]); children.Add(child); andNode.AddChild(child); } // ..and compare them with the returned set when querying for the node's children. Assert.True( TestUtils.SetsAreEquivalent(children, andNode.Children), $"Added children {TestUtils.PrintList(children)}, but return value was {TestUtils.PrintList(andNode.Children)}"); }
/// <summary> /// Sets the node's child. Overwrites it if it was already set. /// </summary> /// <param name="child">The child.</param> public void SetChild(IParameterTreeNode child) { this._child = child; }
/// <summary> /// Sets the value for the specified gene on the given child, /// respecting its parents and the latest parameter origin. /// </summary> /// <param name="node"> /// Specifies the gene to set the value for. /// Is allowed to be an <see cref="AndNode" />. In this case, nothing happens. /// </param> /// <param name="parent1">The first parent.</param> /// <param name="parent2">The second parent.</param> /// <param name="child">The child. Genome will be modified.</param> /// <param name="lastParameterOrigin"> /// The latest parameter origin. /// Influences the probability which parent's gene the child inherits. /// </param> /// <returns> /// The origin of the inherited gene value. /// For an <see cref="AndNode" />, returns the given parameter origin. /// </returns> private ParameterOrigin SetGeneValue( IParameterTreeNode node, Genome parent1, Genome parent2, Genome child, ParameterOrigin lastParameterOrigin = ParameterOrigin.Open) { // If the node is not a parameter node, we do not have to set a value. // The parameter origin does not change. var nodeAsParameter = node as IParameterNode; if (nodeAsParameter == null) { return(lastParameterOrigin); } // If it is a parameter node, find the parents' gene values. var parameterName = nodeAsParameter.Identifier; var parent1GeneValue = parent1.GetGeneValue(parameterName); var parent2GeneValue = parent2.GetGeneValue(parameterName); // If they are equal and the last parameter's origin is open, set child's parameter value to it // and keep the origin. if (lastParameterOrigin == ParameterOrigin.Open && object.Equals(parent1GeneValue, parent2GeneValue)) { child.SetGene(parameterName, parent1GeneValue); return(lastParameterOrigin); } // Otherwise, randomly decide on one of the two parents. // The probability for the parents is dependent on the last parameter's origin. double probabilityForFirstParent; switch (lastParameterOrigin) { case ParameterOrigin.FirstParent: probabilityForFirstParent = 1 - this._crossoverSwitchProbability; break; case ParameterOrigin.SecondParent: probabilityForFirstParent = this._crossoverSwitchProbability; break; case ParameterOrigin.Open: probabilityForFirstParent = 0.5; break; default: throw new ArgumentException($"Parameter origin {lastParameterOrigin} is unknown."); } // Throw a (biased) coin and decide on one parent to inherit the gene value from. var useFirstParent = Randomizer.Instance.Decide(probabilityForFirstParent); if (useFirstParent) { child.SetGene(parameterName, parent1GeneValue); return(ParameterOrigin.FirstParent); } child.SetGene(parameterName, parent2GeneValue); return(ParameterOrigin.SecondParent); }
/// <summary> /// Initializes a new instance of the <see cref="ParameterTree" /> class. /// </summary> /// <param name="root">The tree's root.</param> public ParameterTree(IParameterTreeNode root) { this.Root = root; this.ReplacedParameterFilter = new ReplacedParameterFilter(); }
/// <summary> /// Adds child for the specified value. /// </summary> /// <param name="value">Value from the domain.</param> /// <param name="child">The child to add.</param> /// <exception cref="ArgumentException"> /// Thrown if the value is not from the domain or /// another child was already added for the value. /// </exception> public void AddChild(T value, IParameterTreeNode child) { this.ThrowIfIllegal(value); this._children.Add(value, child); }
/// <summary> /// Adds a child. /// </summary> /// <param name="node">The child to add.</param> public void AddChild(IParameterTreeNode node) { this._children.Add(node); }
/// <summary> /// Returns whether the given <see cref="IParameterTreeNode"/> represents the parameter described by the given /// identifier. /// </summary> /// <param name="node">The node to check.</param> /// <param name="identifier">The identifier to check for.</param> /// <returns>True if and only if the node is an <see cref="IParameterNode"/> with identifier equal to the given /// one. /// </returns> public static bool RepresentsParameter(IParameterTreeNode node, string identifier) { return(node is IParameterNode parameterNode && parameterNode.Identifier == identifier); }