/// <summary> /// Generates a list containing the decision variables of the branches, which can be used to derive a single decision variable of the constraint tree. /// <para>Basically, this generates the carthesian product of the decision variables of the branches</para> /// This can be used to generate constraints of sort: /// Tree-Constraint-1-Satisfied = Branch-A-Satisfied OR Branch-B-Satisfied /// </summary> /// <param name="constraintTree"></param> /// <returns></returns> public static IEnumerable <IEnumerable <string> > GetSatDVarParts(this ConfigurationConstraintTree constraintTree) { if (constraintTree.IsCombination) { List <List <string> > branchDvarLists = new List <List <string> >(); IEnumerable <IEnumerable <string> > dvarsCarthesianProduct = new[] { Enumerable.Empty <string>() }; // For each branch we find its satisfaction decision variables foreach (var branch in constraintTree.ConstraintBranches) { List <String> branchDvars = branch.GetSatDVarNames(); if (branchDvars.Count > 0) { branchDvarLists.Add(branch.GetSatDVarNames()); } } // Then the carthesian product of the decision variables is calculated dvarsCarthesianProduct = branchDvarLists.Aggregate( dvarsCarthesianProduct, (accumulator, sequence) => from accseq in accumulator from item in sequence select accseq.Concat(new[] { item })); return(dvarsCarthesianProduct); } // if this is not a combination constraint tree return empty list return(new List <List <string> >()); }
/// <summary> /// Creates a constraint tree for a set of components from a domain constraint. /// </summary> /// <param name="parent">The parent of the current constraint tree</param> /// <param name="derivedFrom">The domain constraint from which the tree is derived</param> /// <param name="components">The components for which to apply the relevant DomainConstraint</param> /// <param name="log">The processing log</param> internal ConfigurationConstraintTree(ConfigurationConstraintTree parent, DomainConstraint derivedFrom, List <GKOComponent> components, Log log) { if (derivedFrom == null) { throw new ArgumentNullException("The derived from domain constraints has to be set for a configuration constraints tree!"); } this.Parent = parent; // assigning the right DomainConstraint if (derivedFrom is ITransformDomainConstraint) { this.derivedFrom = (derivedFrom as ITransformDomainConstraint).TransformConstraint(); } else { this.derivedFrom = derivedFrom; } if (this.DerivedFrom is DomainConstraintCombination) { this.CreateFromCombinationConstraint((DomainConstraintCombination)this.DerivedFrom, components, log); } else { this.CreateFromNormalConstraint(this.DerivedFrom, components, log); } }
/// <summary> /// Finds the list of satisfaction variables for the current tree. /// Takes in consideration the branches of the tree (if any), but does not return their decision variables. /// If the tree has configuration constraints returns a list of their decision variables names. /// </summary> /// <param name="constraintTree"></param> /// <returns></returns> public static List <string> GetSatDVarNames(this ConfigurationConstraintTree constraintTree) { List <string> dVarNames = new List <string>(); if (constraintTree.IsCombination) { IEnumerable <IEnumerable <string> > dvarsCarthesianProduct = constraintTree.GetSatDVarParts(); // Create the decision variables based on the included branch variables foreach (var dVarList in dvarsCarthesianProduct) { dVarNames.Add(constraintTree.GetSatDVarName(dVarList)); } } else { foreach (var constraint in constraintTree.ConfigurationConstraints) { dVarNames.Add(constraint.GetSatDVarName()); } } return(dVarNames); }
/// <summary> /// Generates the satisfaction decision variable name for the current constraint tree, when using a specific decision variables of the branches /// </summary> /// <param name="constraintTree"></param> /// <param name="parts">An ordered list of the chosen decision variables of the included branches</param> /// <returns></returns> public static string GetSatDVarName(this ConfigurationConstraintTree constraintTree, IEnumerable <string> parts) { return(string.Format("{0}-{1}-satisfied", constraintTree.DerivedFrom.Name, parts.Aggregate((x, y) => x + "-" + y))); }