internal static ConstraintNetwork GenerateQualitativeConstraintNetwork(GKOStructuringContext strContext, RelationFamily calculus, Log log) { ConstraintNetwork resultNetwork = new ConstraintNetwork(calculus, strContext.Id + "_" + calculus.Name, log); List <ConfigurationConstraintTree> constraintTrees = strContext.StructuralConstraints.Where(x => x.RelationFamily == calculus).ToList(); // Creating the constraints restricting that self edges should be labeled with the Equals relation from the calculus DomainConstraint equalsDomainConstraint = DomainConstraint.SelfEqualsConstraint(calculus); ConfigurationConstraintTree equalsConstraint = new ConfigurationConstraintTree(null, equalsDomainConstraint, strContext.Components.Where(x => x.Active).ToList(), log); // Adding the constraints restricting that self edges should be labeled with the Equals relation from the calculus constraintTrees.Add(equalsConstraint); resultNetwork.Context = strContext; // Adding all components as nodes in the constraint network strContext.Components.Where(x => x.Active).ToList().ForEach(x => resultNetwork.Nodes.Add(new Node(x))); // Creating all edges in the constraint network, so it is a complete graph foreach (var startNode in resultNetwork.Nodes) { foreach (var endNode in resultNetwork.Nodes) { QualitativeEdge edge = new QualitativeEdge(resultNetwork, startNode, endNode); resultNetwork.Edges.Add(new Tuple <Node, Node>(startNode, endNode), edge); } } // Each constraint tree has a number of configuration constraints foreach (var constraintTree in constraintTrees) { List <ConfigurationConstraint> constraints = constraintTree.GetAllConfigurationConstraints(); // ToDo: Add check for equal constraints to avoid redundancy // Adding all constraints as edges in the networks constraints.ForEach(x => { // Hack: this uses the fact that each constraint has at least one allowed relation and all have the same signature and logic (i.e. start and end node) Node startNode = x.AllowedRelations[0].GetStartNode(x); Node endNode = x.AllowedRelations[0].GetEndNode(x); Tuple <Node, Node> edgeKey = new Tuple <Node, Node>(startNode, endNode); QualitativeEdge edge = resultNetwork.Edges[edgeKey] as QualitativeEdge; // Adding the constraint to the edge edge.Constraints.Add(x); }); } return(resultNetwork); }
/// <summary> /// Generates the metric constraint network for the structured components /// </summary> /// <param name="structuringContexts">The list of structured components to generate the networks for. /// They must include the metric relation family in the list of included ones</param> /// <returns></returns> internal static List <ConstraintNetwork> GenerateMetricConstraintNetworks(List <GKOStructuringContext> structuringContexts, TmsManager tms, StructuralReasonerOptions options, Log log) { List <ConstraintNetwork> constraintNetworks = new List <ConstraintNetwork>(); List <List <Node> > clusters = new List <List <Node> >(); List <ConfigurationConstraintTree> constraintTrees = new List <ConfigurationConstraintTree>(); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); // Adding all constraint trees to the list foreach (var context in structuringContexts) { context.StructuralConstraints.ForEach(x => { // Additionally assign the special metric values based on the context of the constraints x.AssignSpecialMetricValues(context); constraintTrees.Add(x); }); } stopwatch.Stop(); log.AddItem(LogType.Info, String.Format("Assigning special metric values finished ({0} ms).", stopwatch.ElapsedMilliseconds)); stopwatch.Restart(); // Combine the nodes in the constraint trees in linked clusters, // this serve as base for generating the constraint networks foreach (var constraintTree in constraintTrees) { clusters.AddRange(constraintTree.GetNodeClusters()); ConstraintNetwork.NormalizeClusters(clusters); } stopwatch.Stop(); log.AddItem(LogType.Info, String.Format("Finding node clusters finished ({0} ms).", stopwatch.ElapsedMilliseconds)); #region TCSP specific // These constraints limit the domain of the decision variables for TCSP if (options.MetricReasoningAlgorithm == MetricReasoningAlgorithm.Tcsp) { stopwatch.Restart(); List <Node> nodes = clusters.SelectMany(x => x).Where(x => x != null).Distinct().ToList(); // Add min and max constraint for the constrained attributes foreach (var constrAttribute in nodes) { List <GKOComponent> compList = new List <GKOComponent>() { constrAttribute.Component }; DomainConstraint minConstraint = DomainConstraint.MinValueConstraint(constrAttribute.Attribute, tms.MetricDomain); DomainConstraint maxConstraint = DomainConstraint.MaxValueConstraint(constrAttribute.Attribute, tms.MetricDomain); ConfigurationConstraintTree minTree = new ConfigurationConstraintTree(null, minConstraint, compList, log); ConfigurationConstraintTree maxTree = new ConfigurationConstraintTree(null, maxConstraint, compList, log); constraintTrees.Add(minTree); constraintTrees.Add(maxTree); } stopwatch.Stop(); log.AddItem(LogType.Info, String.Format("Creating Min/Max constraints for TCSP finished ({0} ms).", stopwatch.ElapsedMilliseconds)); } #endregion stopwatch.Restart(); // Generating a new constraint network for each found node cluster foreach (var nodeCluster in clusters) { ConstraintNetwork network = new ConstraintNetwork(StructuralRelationsManager.MetricRelationsFamily, log); network.Nodes = nodeCluster; constraintNetworks.Add(network); } // Adding all configuration constraints in the constraint networks foreach (var constraintTree in constraintTrees) { ConfigurationConstraint[] treeConstraints = constraintTree.GetAllConfigurationConstraints().ToArray(); for (int i = 0; i < treeConstraints.Length; i++) { ConstraintNetwork.ApplyMetricConstraint(treeConstraints[i], constraintNetworks, log); } } // UId has to be assigned to the networks for (int i = 0; i < constraintNetworks.Count; i++) { constraintNetworks[i].UId = "MetricConstraintNetwork_" + (i + 1).ToString(); } stopwatch.Stop(); log.AddItem(LogType.Info, String.Format("Generating the constraint networks finished ({0} ms).", stopwatch.ElapsedMilliseconds)); return(constraintNetworks); }