コード例 #1
0
        public override List <TmsConstraint> GetTmsConstraints(ConfigurationConstraint constraint, Edge edge)
        {
            List <TmsConstraint> result    = new List <TmsConstraint>();
            RelationFamily       relFamily = constraint.AllowedRelations[0].RelationFamily;

            if (!(edge is MetricEdge))
            {
                edge.Network.SturcturalReasonerLog.AddItem(LogType.Warning, string.Format("Edge {0} is not a metric edge. The requested TMS constraints will not be added.", edge.GetUId()));
            }
            else if (!edge.Constraints.Contains(constraint))
            {
                edge.Network.SturcturalReasonerLog.AddItem(LogType.Warning, string.Format("The constraint {0} is not found in the edge {1}. The requested TMS constraints will not be added.", constraint.DomainConstraint.Name, edge.GetUId()));
            }
            else if (relFamily != StructuralRelationsManager.GetRelationFamily(RelationFamilyNames.MetricRelationsName))
            {
                edge.Network.SturcturalReasonerLog.AddItem(LogType.Warning, string.Format("The constraint {0} is qualitative while the needed relation for edge {1} is metric. The requested TMS constraints will not be added.", constraint.DomainConstraint.Name, edge.GetUId()));
            }
            else
            {
                string        dVarA         = edge.EndNode.GetDVarName();
                string        dVarMetric    = (constraint.RelationParts[1] as MetricRelationPart).GetDVarName();
                TmsConstraint tmsConstraint = new TmsConstraint();

                tmsConstraint.ConstraintType = TmsManager.CTNameGreaterThan;
                tmsConstraint.VariableTuple  = new List <string>()
                {
                    dVarA, dVarMetric, constraint.GetSatDVarName()
                };

                result.Add(tmsConstraint);
            }

            return(result);
        }
コード例 #2
0
        /// <summary>
        /// Generates TmsConstraints for the current constraint tree (including branches).
        /// Note: It does not generate constraints for the included configuration constraints, rather it only deals with branch combination logic
        /// </summary>
        /// <returns></returns>
        public List <TmsConstraint> GenerateTmsConstraints()
        {
            List <TmsConstraint> constraints = new List <TmsConstraint>();

            // Only trees with branches generate constraints. The configuration constraints are not processed in this function
            if (this.IsCombination)
            {
                GKODomainAbstract boolDomain = TmsManager.GenerateBoolDomain();
                IEnumerable <IEnumerable <string> > constraintDescriptions = this.GetSatDVarParts();

                // Adding the constraints from each branch
                foreach (var branch in this.ConstraintBranches)
                {
                    constraints.AddRange(branch.GenerateTmsConstraints());
                }

                // Generating the TMS constraints for the current level
                foreach (var constraintDescription in constraintDescriptions)
                {
                    TmsConstraint constraint      = new TmsConstraint();
                    string        currentDvarName = this.GetSatDVarName(constraintDescription);

                    // The first elements of the constraint are the decision variables of the branches
                    constraint.VariableTuple = constraintDescription.ToList();
                    // The last element is the decision variable of the constraint represented by the current tree
                    constraint.VariableTuple.Add(currentDvarName);

                    switch (this.CombinationType)
                    {
                    case DomainConstraintCombinationType.And:
                        constraint.ConstraintType = constraintDescription.Count().GetAndCTName();
                        break;

                    case DomainConstraintCombinationType.Or:
                        constraint.ConstraintType = constraintDescription.Count().GetOrCTName();
                        break;

                    case DomainConstraintCombinationType.ExactlyOne:
                        constraint.ConstraintType = constraintDescription.Count().GetExactlyOneCTName();
                        break;

                    default:
                        throw new Exception("The chosen constraint combination type is not recognized!");
                    }

                    constraints.Add(constraint);

                    // This prohibits the constraint to be violated if it is hard constraint
                    if (!this.DerivedFrom.CanBeViolated)
                    {
                        constraints.Add(TmsConstraint.GenerateSingleValueConstraint(boolDomain, currentDvarName, TmsManager.TrueValue));
                    }
                }
            }

            return(constraints);
        }
コード例 #3
0
        /// <summary>
        /// Creates a TMS constraint
        /// </summary>
        /// <param name="variable"></param>
        /// <param name="cdaStarTms">The CS3 instance where to create the constraint</param>
        /// <param name="variablesMap">A map for finding CS3 variables by name</param>
        /// <param name="constraintTypesMap">A map for finding CS3 constraint types by name</param>
        /// <returns></returns>
        public static IConstraint CreateIConstraint(this TmsConstraint constraint, ICDAStar cdaStarTms, Dictionary <string, IVariable> variablesMap, Dictionary <string, IConstraintType> constraintTypesMap)
        {
            IVariable[] variables = new IVariable[constraint.VariableTuple.Count];

            for (int i = 0; i < constraint.VariableTuple.Count; i++)
            {
                variables[i] = variablesMap[constraint.VariableTuple[i]];
            }

            return(cdaStarTms.DefConstraint(constraintTypesMap[constraint.ConstraintType], variables));
        }
コード例 #4
0
        /// <summary>
        /// ! Use this only once (not for every relation) per edge constraint !
        /// </summary>
        /// <param name="constraint"></param>
        /// <param name="edge"></param>
        /// <returns></returns>
        public override List <TmsConstraint> GetTmsConstraints(ConfigurationConstraint constraint, Edge edge)
        {
            ////OLD: Rem: Qualitative relations use composition constraints and constraint limiting the allowed relations between components, hence there are no constraints implied by a single relation
            //throw new NotSupportedException("A single qualitative relation do not imply a constraint!");

            List <TmsConstraint> result    = new List <TmsConstraint>();
            RelationFamily       relFamily = constraint.AllowedRelations[0].RelationFamily;

            if (!(edge is QualitativeEdge))
            {
                edge.Network.SturcturalReasonerLog.AddItem(LogType.Warning, string.Format("Edge {0} is not a qualitative edge. The requested TMS constraints will not be added.", edge.GetUId()));
            }
            else if (!edge.Constraints.Contains(constraint))
            {
                edge.Network.SturcturalReasonerLog.AddItem(LogType.Warning, string.Format("The constraint {0} is not found in the edge {1}. The requested TMS constraints will not be added.", constraint.DomainConstraint.Name, edge.GetUId()));
            }
            else if (relFamily == StructuralRelationsManager.GetRelationFamily(RelationFamilyNames.MetricRelationsName))
            {
                edge.Network.SturcturalReasonerLog.AddItem(LogType.Warning, string.Format("The constraint {0} is metric while the needed relation for edge {1} is qualitative. The requested TMS constraints will not be added.", constraint.DomainConstraint.Name, edge.GetUId()));
            }
            else
            {
                QualitativeEdge qualEdge                  = (QualitativeEdge)edge;
                GKODomain       calculusDomain            = StructuralRelationsManager.GetDomain(constraint.AllowedRelations[0].RelationFamily.GetTmsRelationsDomainName());
                TmsConstraint   exactlyOneHoldsConstraint = new TmsConstraint();
                List <string>   relDvars                  = new List <string>(); // holds all relation variables
                GKODomain       boolDomain                = TmsManager.GenerateBoolDomain();
                string          dVarSat = constraint.GetSatDVarName();

                // This will create a constraint saying that the edge dvar is matching the chosen relation and the relation's dvar is TRUE, or if they are not matching and the relation's dvar is FALSE
                foreach (var relation in constraint.AllowedRelations)
                {
                    TmsConstraint tmsConstraint      = new TmsConstraint();
                    string        edgeDVar           = qualEdge.GetDVarName();
                    string        edgeRelDVar        = qualEdge.GetDVarName((QualitativeRelation)relation);
                    string        constraintTypeName = calculusDomain.GetIndividualValueCTName(relation.Name);

                    relDvars.Add(edgeRelDVar);

                    tmsConstraint.ConstraintType = constraintTypeName;
                    tmsConstraint.VariableTuple  = new List <string>()
                    {
                        edgeDVar, edgeRelDVar
                    };

                    result.Add(tmsConstraint);
                }

                // This will create the constraint saying that one of the relation dvars has to be set
                // This works because the calculi are JEPD
                exactlyOneHoldsConstraint.ConstraintType = relDvars.Count.GetExactlyOneCTName();
                exactlyOneHoldsConstraint.VariableTuple  = new List <string>(relDvars);
                exactlyOneHoldsConstraint.VariableTuple.Add(dVarSat);

                // This prohibits the constraint to be violated
                if (!constraint.CanBeViolated)
                {
                    result.Add(TmsConstraint.GenerateSingleValueConstraint(boolDomain, dVarSat, TmsManager.TrueValue));
                }

                result.Add(exactlyOneHoldsConstraint);
            }

            return(result);
        }
コード例 #5
0
        internal SolutionDataMetric SolveMetric(StructuralReasonerOptions options, TmsManager tms)
        {
            SolutionDataMetric solutionInformation = new SolutionDataMetric(this);

            solutionInformation.StartTime = DateTime.Now;

            //try
            //{
            if (options.MetricReasoningAlgorithm == MetricReasoningAlgorithm.Tcsp)
            {
                Tcsp tcsp     = new Tcsp(this);
                Stp  solution = null;

                if (this.Edges.Values.Any(x => x.AllConstraints.Any(y => !y.OwningTreeRoot.IsValidForTcsp)))
                {
                    solutionInformation.Log.AddItem(LogType.Error, string.Format("Disjunctive domain constraints are not allowed in TCSP!", this.UId));
                }
                else
                {
                    solutionInformation.Log.AddItem(LogType.Info, string.Format("Solving metric network {0} with TCSP", this.UId));
                    solution = tcsp.Solve();
                    solutionInformation.Log.AddItem(LogType.Info, string.Format("TCSP solving process complete ({0} ms)", (DateTime.Now - solutionInformation.StartTime).TotalMilliseconds));
                }

                if (solution != null && solution.IsConsistent)
                {
                    solutionInformation.SolutionFound = true;
                    solutionInformation.Solution      = solution.GetSolution();
                }
                else
                {
                    solutionInformation.SolutionFound = false;
                }
            }
            else
            {
                List <TmsDecisionVariable>            tmsVariables            = new List <TmsDecisionVariable>(); // Normal TMS variables
                List <TmsDecisionVariable>            tmsUtilityVariables     = new List <TmsDecisionVariable>(); // Utility TMS variables
                List <TmsConstraint>                  tmsConstraints          = new List <TmsConstraint>();
                HashSet <ConfigurationConstraintTree> relevantConstraintTrees = new HashSet <ConfigurationConstraintTree>();
                GKODomainAbstract satisfiedDomain = tms.BoolDomain;
                GKODomainAbstract metricDomain    = tms.MetricDomain;

                solutionInformation.Log.AddItem(LogType.Info, string.Format("Solving metric network {0} with CDA* started", this.UId));

                solutionInformation.Stopwatch.Start();

                // Adding all node decision variables
                foreach (var node in this.Nodes)
                {
                    // The biginning of time is not relevant for the CDA*
                    if (node != null)
                    {
                        tmsVariables.Add(new TmsDecisionVariable(metricDomain, node.GetDVarName()));
                    }
                }

                // Processing configuration constraints in edges
                foreach (var edge in this.Edges.Values)
                {
                    foreach (var constraint in edge.Constraints)
                    {
                        List <MetricRelationPart> metricParts   = constraint.RelationParts.Where(x => x is MetricRelationPart).Select(x => (MetricRelationPart)x).ToList();
                        TmsConstraint             tmsConstraint = new TmsConstraint();

                        // Creating the TMS constraint implied by the configuration constraint
                        tmsConstraints.AddRange(constraint.AllowedRelations[0].GetTmsConstraints(constraint, edge));

                        // Each metric part in the constraint has its own decision variable which has to be created
                        // Additionally, there is a hard constraint restricting the value of the variable to the single selected values
                        foreach (var metricPart in metricParts)
                        {
                            // If the value of the metric part is already used it will have the same decision variable name
                            if (!tmsVariables.Any(x => x.Name == metricPart.GetDVarName()))
                            {
                                tmsVariables.Add(new TmsDecisionVariable(metricDomain, metricPart.GetDVarName()));
                                tmsConstraints.Add(TmsConstraint.GenerateSingleValueConstraint(StructuralRelationsManager.MetricDomain, metricPart.GetDVarName(), metricPart.GetValue()));
                            }
                        }
                    }

                    // Adding all configuration trees, from which the configuration constraints in edge are derived, in a set. This set is used later to generate the constraints combination and utility TMS variables and TMS constraints
                    foreach (var constraint in edge.AllConstraints)
                    {
                        relevantConstraintTrees.Add(constraint.OwningTreeRoot);
                    }
                }

                // Generating the constraints and variables for each constraint tree
                foreach (var constraintTree in relevantConstraintTrees)
                {
                    tmsConstraints.AddRange(constraintTree.GenerateTmsConstraints());
                    tmsVariables.AddRange(constraintTree.GetNonUtilityDecisionVariables());
                    tmsUtilityVariables.AddRange(constraintTree.GetUtilityDecisionVariables());
                }

                // Since some decision variables can be duplicated, we have to find the distinct ones
                // Additionally, for utility variables their utility factor has to be recalculated as needed
                tmsVariables        = TmsDecisionVariable.GetDistinctVariables(tmsVariables, false);
                tmsUtilityVariables = TmsDecisionVariable.GetDistinctVariables(tmsUtilityVariables, true);

                // It is possible that a variable is defined in both lists so it has to be removed from this one
                tmsVariables = tmsVariables.Where(x => !tmsUtilityVariables.Any(y => x.Name == y.Name)).ToList();

                solutionInformation.Stopwatch.Stop();
                solutionInformation.Log.AddItem(LogType.Info, string.Format("TMS variables and constraints generated ({0} ms)", solutionInformation.Stopwatch.ElapsedMilliseconds));

                solutionInformation.Log.AddItem(LogType.Info, string.Format("TMS solution process started", solutionInformation.Stopwatch.ElapsedMilliseconds));
                solutionInformation.Log.AddItem(LogType.Info, string.Format("Variables (excl. soft): {0}", tmsVariables.Count));
                solutionInformation.Log.AddItem(LogType.Info, string.Format("Variables for soft constraints: {0}", tmsUtilityVariables.Count));
                solutionInformation.Log.AddItem(LogType.Info, string.Format("Constraints: {0}", tmsConstraints.Count));

                solutionInformation.Stopwatch.Restart();

                this.SolveWithTms(solutionInformation, tms, tmsVariables, tmsUtilityVariables, tmsConstraints);

                solutionInformation.Stopwatch.Stop();
                solutionInformation.Log.AddItem(LogType.Info, string.Format("TMS solution process complete ({0} ms)", solutionInformation.Stopwatch.ElapsedMilliseconds));
            }
            //}
            //catch (Exception e)
            //{
            //    solutionInformation.Log.AddItem(LogType.Error, e.ToString());
            //}

            solutionInformation.SolutionFinished();

            return(solutionInformation);
        }
コード例 #6
0
        internal SolutionDataQualitative SolveQualitative(StructuralReasonerOptions options, TmsManager tms)
        {
            SolutionDataQualitative               solutionInformation     = new SolutionDataQualitative(this);
            List <TmsDecisionVariable>            tmsVariables            = new List <TmsDecisionVariable>(); // Normal TMS variables
            List <TmsDecisionVariable>            tmsUtilityVariables     = new List <TmsDecisionVariable>(); // Utility TMS variables
            List <TmsConstraint>                  tmsConstraints          = new List <TmsConstraint>();
            HashSet <ConfigurationConstraintTree> relevantConstraintTrees = new HashSet <ConfigurationConstraintTree>();
            GKODomainAbstract satisfiedDomain = tms.BoolDomain;
            GKODomainAbstract calculusDomain  = tms.CalculiDomains.Single(x => x.Name == this.RelationFamily.GetTmsRelationsDomainName());

            solutionInformation.StartTime = DateTime.Now;

            //try
            //{
            solutionInformation.Stopwatch.Start();
            // For each edge adds the decion variables of the edge and generates the TMS constraints for each configuration constraint
            foreach (var edge in this.Edges.Values)
            {
                QualitativeEdge qualEdge = (edge as QualitativeEdge);
                string          edgeDVar = qualEdge.GetDVarName();

                // Adding the edge decision variable
                tmsVariables.Add(new TmsDecisionVariable(calculusDomain, edgeDVar));

                // Adding the bool dvar for each relation used in a constraint of the edge
                // They are mapped to the edge dvar later with a constraint
                foreach (var relation in edge.Constraints.SelectMany(x => x.AllowedRelations).Distinct())
                {
                    tmsVariables.Add(new TmsDecisionVariable(satisfiedDomain, qualEdge.GetDVarName((QualitativeRelation)relation)));
                }

                foreach (var constraint in edge.Constraints)
                {
                    // ToDo: Make the GetTmsConstraints more consistent - now it is actually working on a constraint lvl for qualitative relations
                    // Adding the TMS constraints derivde by the relation
                    tmsConstraints.AddRange(constraint.AllowedRelations[0].GetTmsConstraints(constraint, edge));
                }

                // Adding all configuration trees, from which the configuration constraints in edge are derived, in a set. This set is used later to generate the constraints combination and utility TMS variables and TMS constraints
                foreach (var constraint in edge.AllConstraints)
                {
                    relevantConstraintTrees.Add(constraint.OwningTreeRoot);
                }
            }

            // Generating the constraints and variables for each constraint tree
            foreach (var constraintTree in relevantConstraintTrees)
            {
                tmsConstraints.AddRange(constraintTree.GenerateTmsConstraints());
                tmsVariables.AddRange(constraintTree.GetNonUtilityDecisionVariables());
                tmsUtilityVariables.AddRange(constraintTree.GetUtilityDecisionVariables());
            }

            // Since some decision variables can be duplicated, we have to find the distinct ones
            // Additionally, for utility variables their utility factor has to be recalculated as needed
            tmsVariables        = TmsDecisionVariable.GetDistinctVariables(tmsVariables, false);
            tmsUtilityVariables = TmsDecisionVariable.GetDistinctVariables(tmsUtilityVariables, true);

            // Generating the composition constraints
            foreach (var nodeA in this.Nodes)
            {
                foreach (var nodeB in this.Nodes)
                {
                    foreach (var nodeC in this.Nodes)
                    {
                        QualitativeEdge edgeAB                = (QualitativeEdge)this.Edges[new Tuple <Node, Node>(nodeA, nodeB)];
                        QualitativeEdge edgeBC                = (QualitativeEdge)this.Edges[new Tuple <Node, Node>(nodeB, nodeC)];
                        QualitativeEdge edgeAC                = (QualitativeEdge)this.Edges[new Tuple <Node, Node>(nodeA, nodeC)];
                        string          edgeABDVar            = edgeAB.GetDVarName();
                        string          edgeBCDVar            = edgeBC.GetDVarName();
                        string          edgeACDVar            = edgeAC.GetDVarName();
                        TmsConstraint   compositionConstraint = new TmsConstraint();

                        // Creating the constraint restricting the allowed relations by the edge
                        compositionConstraint.ConstraintType = this.RelationFamily.GetTmsCompositionConstraintName();
                        compositionConstraint.VariableTuple  = new List <string>()
                        {
                            edgeABDVar, edgeBCDVar, edgeACDVar
                        };

                        tmsConstraints.Add(compositionConstraint);
                    }
                }
            }

            solutionInformation.Stopwatch.Stop();
            solutionInformation.Log.AddItem(LogType.Info, string.Format("TMS variables and constraints generated ({0} ms)", solutionInformation.Stopwatch.ElapsedMilliseconds));

            solutionInformation.Log.AddItem(LogType.Info, string.Format("TMS solution process started", solutionInformation.Stopwatch.ElapsedMilliseconds));
            solutionInformation.Log.AddItem(LogType.Info, string.Format("Variables (excl. soft): {0}", tmsVariables.Count));
            solutionInformation.Log.AddItem(LogType.Info, string.Format("Variables for soft constraints: {0}", tmsUtilityVariables.Count));
            solutionInformation.Log.AddItem(LogType.Info, string.Format("Constraints: {0}", tmsConstraints.Count));

            solutionInformation.Stopwatch.Restart();

            this.SolveWithTms(solutionInformation, tms, tmsVariables, tmsUtilityVariables, tmsConstraints);

            solutionInformation.Stopwatch.Stop();
            solutionInformation.Log.AddItem(LogType.Info, string.Format("TMS solution process complete ({0} ms)", solutionInformation.Stopwatch.ElapsedMilliseconds));
            //}
            //catch (Exception e)
            //{
            //    solutionInformation.Log.AddItem(LogType.Error, e.ToString());
            //}

            solutionInformation.SolutionFinished();

            return(solutionInformation);
        }