Esempio n. 1
0
        public Tcsp(ConstraintNetwork constraintNetwork)
        {
            Nodes = constraintNetwork.Nodes;
            Edges = new Dictionary <Tuple <Node, Node>, MetricEdge>();

            foreach (var edgeKey in constraintNetwork.Edges.Keys)
            {
                MetricEdge edge = (MetricEdge)constraintNetwork.Edges[edgeKey];

                edge.GenerateAllowedIntervals();
                Edges.Add(edgeKey, edge);
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Recursively solves a TCSP
        /// </summary>
        /// <param name="unprocessedEdges">The TCSP unprocessed edges</param>
        /// <param name="selectedLabels">The current active edge intervals</param>
        /// <returns>The first consistent solution</returns>
        private Stp SolveTcsp(Dictionary <Tuple <Node, Node>, MetricEdge> unprocessedEdges, Dictionary <Tuple <Node, Node>, Interval> selectedLabels)
        {
            if (selectedLabels.Count == this.edgesCounts)
            {
                Stp completeStp;

                stopwatch1.Start();
                completeStp = new Stp(selectedLabels);
                completeStp.ApplyDPC(completeStp.Nodes);
                stopwatch1.Stop();
                this.ExaminedStps++;
                if (completeStp.IsConsistent)
                {
                    completeStp.ApplyAPSP();
                    return(completeStp);
                }
                else
                {
                    return(null);
                }
            }
            else
            {
                // Ordering the edges has a huge impact on the performance
                // Here the Beginning of time edges are processed first
                Tuple <Node, Node> currEdgeKey = unprocessedEdges.Keys.OrderBy(x => x.Item1).First();
                MetricEdge         currEdge    = unprocessedEdges[currEdgeKey];

                // Removing the explored edge
                unprocessedEdges.Remove(currEdgeKey);

                // Explore all possible intervals in the selected edge
                foreach (var interval in currEdge.AllowedIntervals)
                {
                    Stp partialStp;

                    // inserting the interval data in the selected labels
                    selectedLabels.Add(currEdgeKey, interval);

                    stopwatch55.Start();
                    partialStp = new Stp(selectedLabels);
                    partialStp.ApplyDPC(partialStp.Nodes);
                    stopwatch55.Stop();

                    // If the partial assignment is consistent continue with the assignment
                    if (partialStp.IsConsistent)
                    {
                        Stp solution = SolveTcsp(unprocessedEdges, selectedLabels);

                        // If a solution is available return it
                        if (solution != null)
                        {
                            return(solution);
                        }
                        else
                        {
                            // The current labeling has to be removed before continuing
                            selectedLabels.Remove(currEdgeKey);
                        }
                    }
                    else
                    {
                        // The current labeling has to be removed before continuing
                        selectedLabels.Remove(currEdgeKey);
                    }
                }

                // If no solution is found the edge is returned to the list of unprocessed ones
                unprocessedEdges.Add(currEdgeKey, currEdge);
                return(null);
            }
        }
        /// <summary>
        /// Adds a configuration constraint
        /// </summary>
        /// <param name="constraint">The constraint to add</param>
        /// <param name="constrNetworks">The list of possible constraint networks where the constraint can e added</param>
        /// <param name="log"></param>
        private static void ApplyMetricConstraint(ConfigurationConstraint constraint, List <ConstraintNetwork> constrNetworks, Log log)
        {
            IMetricRelation relation = constraint.AllowedRelations[0] as IMetricRelation;

            if (relation == null)
            {
                log.AddItem(LogType.Warning, String.Format("A constraint ({0}) is skipped during the generation of a metric constraint network, because it is {1} relation and not recognized as metric.", constraint.DomainConstraint.Name, constraint.AllowedRelations[1].RelationFamily.Name));
            }
            else
            {
                ConstraintNetwork constraintNetwork = constrNetworks.Single(x => constraint.GetIncludedNodes().All(y => x.Nodes.Contains(y)));
                Node startNode                    = (relation as BinaryRelation).GetStartNode(constraint);
                Node endNode                      = (relation as BinaryRelation).GetEndNode(constraint);
                Tuple <Node, Node> edgeKey        = new Tuple <Node, Node>(startNode, endNode);
                Tuple <Node, Node> reverseEdgeKey = new Tuple <Node, Node>(endNode, startNode);
                List <Interval>    intervals      = relation.GetDifferenceIntervals(constraint);

                // Check if the edge already exists
                if (constraintNetwork.Edges.ContainsKey(edgeKey))
                {
                    // Adding the current constraint to the edge
                    MetricEdge edge = constraintNetwork.Edges[edgeKey] as MetricEdge;
                    ConfigurationConstraint equalConstraint = edge.Constraints.SingleOrDefault(x => x.Equals(constraint));

                    // Add the constraint if an equal one doesn't already exist
                    if (equalConstraint == null)
                    {
                        edge.AddConstraintIntervals(constraint, intervals, log);
                    }
                    else
                    {
                        // Adding the constraints as implied by a previous one
                        edge.ImpliedConstraints.Add(constraint);
                        constraint.EqualActiveConstraint = equalConstraint;
                    }
                }
                // Check if the reverse of the edge exists
                else if (constraintNetwork.Edges.ContainsKey(reverseEdgeKey))
                {
                    // Adding the inverse constraint to the mirror edge
                    MetricEdge              edge = constraintNetwork.Edges[reverseEdgeKey] as MetricEdge;
                    IMetricRelation         asMetricConstraint        = (IMetricRelation)constraint.AllowedRelations[0];
                    ConfigurationConstraint inverseConstraint         = asMetricConstraint.GetInverseConstraint(constraint);
                    IMetricRelation         inverseAsMetricConstraint = (IMetricRelation)inverseConstraint.AllowedRelations[0];
                    ConfigurationConstraint equalConstraint           = edge.Constraints.SingleOrDefault(x => x.Equals(inverseConstraint));

                    // Since the inverse constraint is used, it should be included instead of the current one in the constraint tree
                    constraint.OwningTree.SwitchConstraint(constraint, inverseConstraint);

                    // Add the constraint if an equal one doesn't already exist
                    if (equalConstraint == null)
                    {
                        edge.AddConstraintIntervals(inverseConstraint, inverseAsMetricConstraint.GetDifferenceIntervals(inverseConstraint), log);
                    }
                    else
                    {
                        // Adding the constraints as implied by a previous one
                        edge.ImpliedConstraints.Add(inverseConstraint);
                        inverseConstraint.EqualActiveConstraint = equalConstraint;
                    }
                }
                // Adding the new edge with the found intervals
                else
                {
                    MetricEdge edge = new MetricEdge(constraintNetwork, edgeKey.Item1, edgeKey.Item2);

                    edge.AddConstraintIntervals(constraint, intervals, log);
                    constraintNetwork.Edges.Add(edgeKey, edge);
                }
            }
        }