Beispiel #1
0
        private bool ReviseArcs(ConstraintNetwork constraintNetwork)
        {
            var domainChanged = false;

            foreach (var arc in constraintNetwork.GetArcs())
            {
                /*
                 * Arcs with ternary or unary expressions are pre-computed with one
                 * or more solution sets produced for the variables involved in the expression.
                 */
                if (arc.IsPreComputed)
                {
                    continue;
                }

                var connector = arc.Connector as ConstraintExpressionConnector;
                Debug.Assert(connector != null);
                var constraint = connector.Constraint;
                if (!constraint.Node.InnerExpression.LeftExpression.IsLiteral)
                {
                    // Revise the left variable domain
                    domainChanged |= ReviseLeft(arc.Left as VariableNode, arc.Right as VariableNode, constraint);
                }

                if (!constraint.Node.InnerExpression.RightExpression.IsLiteral)
                {
                    // Revise the right variable domain
                    domainChanged |= ReviseRight(arc.Left as VariableNode, arc.Right as VariableNode, constraint);
                }
            }

            return(domainChanged);
        }
        /// <summary>
        /// Build a constraint network from the model.
        /// </summary>
        /// <param name="model">Constraint model.</param>
        /// <returns>Constraint network.</returns>
        internal ConstraintNetwork Build(ModelModel model)
        {
            MapVariables(model);
            MapValues(model);
            ConvertBuckets(model);
            _constraintNetwork = new ConstraintNetwork();
            PopulateConstraintNetwork(model);
            CreateVariables(model);

            return(_constraintNetwork);
        }
Beispiel #3
0
        /// <summary>
        /// Extract a snapshot from the constraint network.
        /// </summary>
        /// <param name="constraintNetwork">Constraint network.</param>
        /// <param name="solutionSnapshot">Solution snapshot.</param>
        /// <returns>True if a snapshot was extracted, False if the snapshot could not be extracted.</returns>
        internal bool ExtractFrom(ConstraintNetwork constraintNetwork, out SolutionSnapshot solutionSnapshot)
        {
            _constraintNetwork = constraintNetwork;
            var solverVariables = constraintNetwork.GetSolverVariables();
            var assignment      = new SnapshotLabelAssignment(solverVariables);

            _variables = new List <VariableBase>(constraintNetwork.GetVariables());
            var status = Backtrack(0, assignment, constraintNetwork);

            solutionSnapshot = status ? ConvertSnapshotFrom(assignment, constraintNetwork) : SolutionSnapshot.Empty;

            return(status);
        }
Beispiel #4
0
        /// <summary>
        /// Remove values found during the ternary pre-calculation phase that are now
        /// inconsistent with values discovered during the regular revising of
        /// domains of the binary constraints.
        /// </summary>
        /// <param name="constraintNetwork">Constraint network.</param>
        private void RemoveTernaryValuesInconsistentWithBinaryConstraints(ConstraintNetwork constraintNetwork)
        {
            var constraintExpressionSolutions = _modelSolverMap.GetTernaryConstraintExpressionSolutions();

            foreach (var constraintExpressionSolution in constraintExpressionSolutions)
            {
                var leftVariable = constraintExpressionSolution.Expression.LeftArc.Left.Content as SolverVariable;
                Debug.Assert(leftVariable != null);
                var leftVariableDomain = leftVariable.Domain;
                var leftVariableIndex  = 1;     // Left variable is always in first index

                RemoveTernaryValuesInconsistentWithBinaryConstraint(constraintExpressionSolution, leftVariableIndex, leftVariableDomain);

                var rightVariable = constraintExpressionSolution.Expression.RightArc.Left.Content as SolverVariable;
                Debug.Assert(rightVariable != null);
                var rightVariableDomain = rightVariable.Domain;
                var rightVariableIndex  = 2;     // Right variable is always in second index

                RemoveTernaryValuesInconsistentWithBinaryConstraint(constraintExpressionSolution, rightVariableIndex, rightVariableDomain);
            }
        }
Beispiel #5
0
        /// <summary>
        /// Get all value sets for the variable.
        /// </summary>
        /// <param name="variable">Variable</param>
        /// <param name="assignment">All value assignments.</param>
        /// <param name="constraintNetwork">Constraint network.</param>
        /// <returns>All value sets for the variable.</returns>
        private IEnumerable <ValueSet> OrderDomainValues(VariableBase variable, SnapshotLabelAssignment assignment, ConstraintNetwork constraintNetwork)
        {
            switch (variable)
            {
            case SolverVariable solverVariable:
                return(solverVariable.GetCandidates());

            case EncapsulatedVariable encapsulatedVariable:
                return(encapsulatedVariable.GetCandidates());

            default:
                throw new NotImplementedException();
            }
        }
Beispiel #6
0
        /// <summary>
        /// Backtrack through a variable's value sets until one is found that is arc consistent.
        /// </summary>
        /// <param name="currentVariableIndex">Current variable index.</param>
        /// <param name="snapshotAssignment">Current snapshot of value sets.</param>
        /// <param name="constraintNetwork">Constraint network.</param>
        /// <returns>True if a value is found to be consistent, False if a value is not found.</returns>
        private bool Backtrack(int currentVariableIndex, SnapshotLabelAssignment snapshotAssignment, ConstraintNetwork constraintNetwork)
        {
            // Label assignment has been successful...
            if (snapshotAssignment.IsComplete() && AllVariablesTested(currentVariableIndex))
            {
                return(true);
            }

            // The unassigned variable may be a regular variable or an encapsulated variable
            var currentVariable = SelectUnassignedVariable(currentVariableIndex, constraintNetwork, snapshotAssignment);

            foreach (var value in OrderDomainValues(currentVariable, snapshotAssignment, constraintNetwork))
            {
                if (IsConsistent(value, snapshotAssignment))
                {
                    snapshotAssignment.AssignTo(value);

                    // Is this the final variable?
                    if (AllVariablesTested(currentVariableIndex))
                    {
                        return(true);
                    }

                    if (Backtrack(currentVariableIndex + 1, snapshotAssignment, constraintNetwork))
                    {
                        return(true);
                    }
                }

                snapshotAssignment.Remove(value);
            }

            return(false);
        }
Beispiel #7
0
        private IEnumerable <BucketLabelModel> ExtractBucketLabelsFrom(SnapshotLabelAssignment assignment, ConstraintNetwork constraintNetwork)
        {
            var bucketLabelAccumulator = new List <BucketLabelModel>();

            foreach (var bucketVariableMap in _modelSolverMap.GetBucketVariables())
            {
                bucketLabelAccumulator.Add(ExtractBucketLabelFrom(assignment, bucketVariableMap));
            }

            return(bucketLabelAccumulator);
        }
Beispiel #8
0
        private IEnumerable <AggregateVariableLabelModel> ExtractAggregateLabelsFrom(SnapshotLabelAssignment assignment, ConstraintNetwork constraintNetwork)
        {
            var aggregatorLabelAccumulator = new List <AggregateVariableLabelModel>();

            foreach (var aggregateSolverVariable in constraintNetwork.GetAggregateVariables())
            {
                var internalAccumulator    = new List <ValueModel>();
                var aggregateVariableModel = _modelSolverMap.GetModelAggregateVariableByName(aggregateSolverVariable.Name);
                foreach (var variable in aggregateSolverVariable.Variables)
                {
                    var solverVariable      = _modelSolverMap.GetSolverVariableByName(variable.Name);
                    var labelAssignment     = assignment.GetAssignmentFor(solverVariable);
                    var variableSolverValue = labelAssignment.Value;
                    var variableModel       = _modelSolverMap.GetInternalModelAggregateVariableByName(variable.Name);
                    var variableModelValue  = ConvertSolverValueToModel((SingletonVariableModel)variableModel, variableSolverValue);
                    internalAccumulator.Add(new ValueModel(variableModelValue));
                }

                var label = new AggregateVariableLabelModel(aggregateVariableModel, internalAccumulator);
                aggregatorLabelAccumulator.Add(label);
            }

            return(aggregatorLabelAccumulator);
        }
Beispiel #9
0
        private IEnumerable <SingletonVariableLabelModel> ExtractSingletonLabelsFrom(SnapshotLabelAssignment assignment, ConstraintNetwork constraintNetwork)
        {
            var labelAccumulator = new List <SingletonVariableLabelModel>();

            foreach (var variable in constraintNetwork.GetSingletonVariables())
            {
                var solverVariable      = _modelSolverMap.GetSolverSingletonVariableByName(variable.Name);
                var labelAssignment     = assignment.GetAssignmentFor(solverVariable);
                var variableSolverValue = labelAssignment.Value;
                var variableModel       = _modelSolverMap.GetModelSingletonVariableByName(variable.Name);
                var variableModelValue  = ConvertSolverValueToModel(variableModel, variableSolverValue);
                var label = new SingletonVariableLabelModel(variableModel, new ValueModel(variableModelValue));
                labelAccumulator.Add(label);
            }

            return(labelAccumulator);
        }
Beispiel #10
0
 private SolutionSnapshot ConvertSnapshotFrom(SnapshotLabelAssignment assignment, ConstraintNetwork constraintNetwork)
 {
     return(new SolutionSnapshot(ExtractSingletonLabelsFrom(assignment, constraintNetwork),
                                 ExtractAggregateLabelsFrom(assignment, constraintNetwork),
                                 ExtractBucketLabelsFrom(assignment, constraintNetwork)));
 }
Beispiel #11
0
        private VariableBase SelectUnassignedVariable(int currentVariableIndex, ConstraintNetwork constraintNetwork, SnapshotLabelAssignment assignment)
        {
            Debug.Assert(currentVariableIndex < _variables.Count, "Backtracking must never attempt to go over the end of the variables.");

            return(_variables[currentVariableIndex]);
        }