Пример #1
0
            /** Returns the values of Dom(var) in a special order. The least constraining value comes first. */
            public ICollection <VAL> apply(CSP <VAR, VAL> csp, Assignment <VAR, VAL> assignment, VAR var)
            {
                ICollection <Pair <VAL, int> > pairs = CollectionFactory.CreateQueue <Pair <VAL, int> >();

                foreach (VAL value in csp.getDomain(var))
                {
                    int num = countLostValues(csp, assignment, var, value);
                    pairs.Add(new Pair <VAL, int>(value, num));
                }

                pairs.Sort(new PairComparer <VAL>());
                ICollection <VAL> obj = CollectionFactory.CreateQueue <VAL>();

                foreach (Pair <VAL, int> val in pairs)
                {
                    obj.Add(val.GetFirst());
                }
                return(obj);
            }
Пример #2
0
        private ISet <VAR> getConflictedVariables(Assignment <VAR, VAL> assignment, CSP <VAR, VAL> csp)
        {
            ISet <VAR> result = CollectionFactory.CreateSet <VAR>();

            foreach (IConstraint <VAR, VAL> constraint in csp.getConstraints())
            {
                if (!constraint.isSatisfiedWith(assignment))
                {
                    foreach (VAR var in constraint.getScope())
                    {
                        if (!result.Contains(var))
                        {
                            result.Add(var);
                        }
                    }
                }
            }
            return(result);
        }
Пример #3
0
            /** Returns variables from <code>vars</code> which are the best with respect to DEG. */
            public ICollection <VAR> apply(CSP <VAR, VAL> csp, ICollection <VAR> vars)
            {
                ICollection <VAR> result = CollectionFactory.CreateQueue <VAR>();
                int maxDegree            = -1;

                foreach (VAR var in vars)
                {
                    int degree = csp.getConstraints(var).Size();
                    if (degree >= maxDegree)
                    {
                        if (degree > maxDegree)
                        {
                            result.Clear();
                            maxDegree = degree;
                        }
                        result.Add(var);
                    }
                }
                return(result);
            }
Пример #4
0
            /** Returns variables from <code>vars</code> which are the best with respect to MRV. */
            public ICollection <VAR> apply(CSP <VAR, VAL> csp, ICollection <VAR> vars)
            {
                ICollection <VAR> result = CollectionFactory.CreateQueue <VAR>();
                int mrv = int.MaxValue;

                foreach (VAR var in vars)
                {
                    int rv = csp.getDomain(var).size();
                    if (rv <= mrv)
                    {
                        if (rv < mrv)
                        {
                            result.Clear();
                            mrv = rv;
                        }
                        result.Add(var);
                    }
                }
                return(result);
            }
Пример #5
0
        /**
         * Computes an explicit representation of the tree structure and a total order which is consistent with the
         * parent-child relations. If the provided CSP has not the required properties (CSP contains only binary
         * constraints, constraint graph is tree-structured and connected), an exception is thrown.
         *
         * @param csp               A CSP
         * @param root              A root variable
         * @param orderedVars       The computed total order (initially empty)
         * @param parentConstraints The tree structure, maps a variable to the constraint representing the arc to the parent
         *                          variable (initially empty)
         */
        private void topologicalSort(CSP <VAR, VAL> csp, VAR root, ICollection <VAR> orderedVars,
                                     IMap <VAR, IConstraint <VAR, VAL> > parentConstraints)
        {
            orderedVars.Add(root);
            parentConstraints.Put(root, null);
            int currParentIdx = -1;

            while (currParentIdx < orderedVars.Size() - 1)
            {
                currParentIdx++;
                VAR currParent          = orderedVars.Get(currParentIdx);
                int arcsPointingUpwards = 0;
                foreach (IConstraint <VAR, VAL> constraint in csp.getConstraints(currParent))
                {
                    VAR neighbor = csp.getNeighbor(currParent, constraint);
                    if (neighbor == null)
                    {
                        throw new IllegalArgumentException("Constraint " + constraint + " is not binary.");
                    }
                    if (parentConstraints.ContainsKey(neighbor))
                    { // faster than orderedVars.contains(neighbor)!
                        arcsPointingUpwards++;
                        if (arcsPointingUpwards > 1)
                        {
                            throw new IllegalArgumentException("CSP is not tree-structured.");
                        }
                    }
                    else
                    {
                        orderedVars.Add(neighbor);
                        parentConstraints.Put(neighbor, constraint);
                    }
                }
            }
            if (orderedVars.Size() < csp.getVariables().Size())
            {
                throw new IllegalArgumentException("Constraint graph is not connected.");
            }
        }
Пример #6
0
        public override Assignment <VAR, VAL> solve(CSP <VAR, VAL> csp)
        {
            Assignment <VAR, VAL> current = generateRandomAssignment(csp);

            fireStateChanged(csp, current, null);
            for (int i = 0; i < maxSteps && !currIsCancelled; ++i)
            {
                if (current.isSolution(csp))
                {
                    return(current);
                }
                else
                {
                    ISet <VAR> vars  = getConflictedVariables(current, csp);
                    VAR        var   = Util.selectRandomlyFromSet(vars);
                    VAL        value = getMinConflictValueFor(var, current, csp);
                    current.add(var, value);
                    fireStateChanged(csp, current, var);
                }
            }
            return(null);
        }
Пример #7
0
        /// <summary>
        /// Template method, which can be configured by overriding the three primitive operations below.
        /// </summary>
        /// <param name="csp"></param>
        /// <param name="assignment"></param>
        /// <returns>An assignment (possibly incomplete if task was cancelled) or null if no solution was found.</returns>
        private Assignment <VAR, VAL> backtrack(CSP <VAR, VAL> csp, Assignment <VAR, VAL> assignment)
        {
            Assignment <VAR, VAL> result = null;

            if (assignment.isComplete(csp.getVariables()) || currIsCancelled)
            {
                result = assignment;
            }
            else
            {
                VAR var = selectUnassignedVariable(csp, assignment);
                foreach (VAL value in orderDomainValues(csp, assignment, var))
                {
                    assignment.add(var, value);
                    fireStateChanged(csp, assignment, var);
                    if (assignment.isConsistent(csp.getConstraints(var)))
                    {
                        IInferenceLog <VAR, VAL> log = inference(csp, assignment, var);
                        if (!log.isEmpty())
                        {
                            fireStateChanged(csp, null, null);
                        }
                        if (!log.inconsistencyFound())
                        {
                            result = backtrack(csp, assignment);
                            if (result != null)
                            {
                                break;
                            }
                        }
                        log.undo(csp);
                    }
                    assignment.remove(var);
                }
            }
            return(result);
        }
Пример #8
0
 /**
  * Computes a solution to the given CSP, which specifies values for all
  * variables of the CSP such that all constraints are satisfied.
  *
  * @param csp a CSP to be solved.
  * @return the computed solution or empty if no solution was found.
  */
 public abstract Assignment <VAR, VAL> solve(CSP <VAR, VAL> csp);
Пример #9
0
 public ICollection <VAR> apply(CSP <VAR, VAL> csp, ICollection <VAR> vars)
 {
     return(new DegHeuristic <VAR, VAL>().apply(csp, new MrvHeuristic <VAR, VAL>().apply(csp, vars)));
 }
Пример #10
0
        /**
         * Establishes arc-consistency for (xi, xj).
         * @return value true if the domain of xi was reduced.
         */
        private bool makeArcConsistent(VAR xi, VAR xj, IConstraint <VAR, VAL> constraint, CSP <VAR, VAL> csp)
        {
            Domain <VAL>          currDomain = csp.getDomain(xi);
            ICollection <VAL>     newValues  = CollectionFactory.CreateQueue <VAL>();
            Assignment <VAR, VAL> assignment = new Assignment <VAR, VAL>();

            foreach (VAL vi in currDomain)
            {
                assignment.add(xi, vi);
                foreach (VAL vj in csp.getDomain(xj))
                {
                    assignment.add(xj, vj);
                    if (constraint.isSatisfiedWith(assignment))
                    {
                        newValues.Add(vi);
                        break;
                    }
                }
            }
            if (newValues.Size() < currDomain.size())
            {
                csp.setDomain(xi, new Domain <VAL>(newValues));
                return(true);
            }
            return(false);
        }
Пример #11
0
 /// <summary>
 /// Returns true if this assignment is consistent as well as complete with
 /// respect to the given CSP.
 /// </summary>
 /// <param name="csp"></param>
 /// <returns></returns>
 public bool isSolution(CSP <VAR, VAL> csp)
 {
     return(isConsistent(csp.getConstraints()) && isComplete(csp.getVariables()));
 }
Пример #12
0
        /// <summary>
        /// Applies a recursive backtracking search to solve the CSP.
        /// </summary>
        /// <param name="csp"></param>
        /// <returns></returns>
        public override Assignment <VAR, VAL> solve(CSP <VAR, VAL> csp)
        {
            Assignment <VAR, VAL> result = backtrack(csp, new Assignment <VAR, VAL>());

            return(result);
        }
Пример #13
0
 /// <summary>
 /// Primitive operation, which tries to optimize the CSP representation with respect to a new assignment.
 /// </summary>
 /// <param name="csp"></param>
 /// <param name="assignment"></param>
 /// <param name="var">The variable which just got a new value in the assignment.</param>
 /// <returns>
 /// An object which provides information about
 /// (1) whether changes have been performed,
 /// (2) possibly inferred empty domains, and
 /// (3) how to restore the original CSP.
 /// </returns>
 protected abstract IInferenceLog <VAR, VAL> inference(CSP <VAR, VAL> csp, Assignment <VAR, VAL> assignment, VAR var);
Пример #14
0
 /// <summary>
 /// Primitive operation, ordering the domain values of the specified variable.
 /// </summary>
 /// <param name="csp"></param>
 /// <param name="assignment"></param>
 /// <param name="var"></param>
 /// <returns></returns>
 protected abstract IEnumerable <VAL> orderDomainValues(CSP <VAR, VAL> csp, Assignment <VAR, VAL> assignment, VAR var);
Пример #15
0
 /// <summary>
 /// Primitive operation, selecting a not yet assigned variable.
 /// </summary>
 /// <param name="csp"></param>
 /// <param name="assignment"></param>
 /// <returns></returns>
 protected abstract VAR selectUnassignedVariable(CSP <VAR, VAL> csp, Assignment <VAR, VAL> assignment);
Пример #16
0
        private VAL getMinConflictValueFor(VAR var, Assignment <VAR, VAL> assignment, CSP <VAR, VAL> csp)
        {
            ICollection <IConstraint <VAR, VAL> > constraints = csp.getConstraints(var);
            Assignment <VAR, VAL> testAssignment = assignment.Clone();
            int minConflict = int.MaxValue;
            ICollection <VAL> resultCandidates = CollectionFactory.CreateQueue <VAL>();

            foreach (VAL value in csp.getDomain(var))
            {
                testAssignment.add(var, value);
                int currConflict = countConflicts(testAssignment, constraints);
                if (currConflict <= minConflict)
                {
                    if (currConflict < minConflict)
                    {
                        resultCandidates.Clear();
                        minConflict = currConflict;
                    }
                    resultCandidates.Add(value);
                }
            }
            return((!resultCandidates.IsEmpty()) ? Util.selectRandomlyFromList <VAL>(resultCandidates) : default(VAL));
        }