Beispiel #1
0
        public PropagationResult Update(ref PropagatedProperty <T> ioState, bool inbForce = false)
        {
            PropagationResult result = UpdateSelf(ref ioState, inbForce);

            if ((result & PropagationResult.UpdateSelf) == 0)
            {
                result |= UpdateChildren(ref ioState, inbForce);
            }
            return(result);
        }
Beispiel #2
0
        public void SolveImpl(Action <string> Log, int depth)
        {
            // For each empty path space, try filling it.
            bool changed = false;

            for (byte feature = 3; feature <= 4; feature++)
            {
                for (int y = 1; y < board.GetLength(1) - 1; y++)
                {
                    for (int x = 1 + (y % 2); x < board.GetLength(0) - 1; x += 2)
                    {
                        if (board[x, y] != 0)
                        {
                            continue;
                        }
                        if (board[x - 1, y] == 2 || board[x, y - 1] == 2)
                        {
                            // Small optimization: don't need to check both sides of a white circle.
                            continue;
                        }
                        var backup = BackupState();
                        board[x, y] = feature;
                        PropagationResult result = PropagateConstraintsImpl(new Tuple <int, int>(x, y));
                        if (result != PropagationResult.CONTRADICTION && CheckNonPatternContradictions())
                        {
                            result = PropagationResult.CONTRADICTION;
                        }
                        if (result != PropagationResult.CONTRADICTION && depth > 0)
                        {
                            SolveImpl(Log, depth - 1);
                            if (!valid)
                            {
                                result = PropagationResult.CONTRADICTION;
                            }
                        }
                        RestoreBackup(backup);

                        if (result == PropagationResult.CONTRADICTION)
                        {
                            board[x, y] = feature == 3 ? (byte)4 : (byte)3;
                            PropagateConstraintsImpl(new Tuple <int, int>(x, y));
                            changed = true;
                        }
                    }
                }
            }
            if (changed)
            {
                // TODO: Make this iterative. No reason to keep stack frames and risk overflow.
                SolveImpl(Log, depth);
                return;
            }
            valid = PropagateConstraintsImpl(null) != PropagationResult.CONTRADICTION;
            // TODO: Parallelize.
        }
Beispiel #3
0
        public void SolveImpl(Action <string> Log, int depth)
        {
            // Для каждого пути попробуйте заполнить пустое пространство.
            bool changed = false;

            for (byte feature = 3; feature <= 4; feature++)
            {
                for (int y = 1; y < board.GetLength(1) - 1; y++)
                {
                    for (int x = 1 + (y % 2); x < board.GetLength(0) - 1; x += 2)
                    {
                        if (board[x, y] != 0)
                        {
                            continue;
                        }
                        if (board[x - 1, y] == 2 || board[x, y - 1] == 2)
                        {
                            // Заметка: не нужно проверять обе стороны белого круга.
                            continue;
                        }
                        var backup = BackupState();
                        board[x, y] = feature;
                        PropagationResult result = PropagateConstraintsImpl(new Tuple <int, int>(x, y));
                        if (result != PropagationResult.CONTRADICTION && CheckNonPatternContradictions())
                        {
                            result = PropagationResult.CONTRADICTION;
                        }
                        if (result != PropagationResult.CONTRADICTION && depth > 0)
                        {
                            SolveImpl(Log, depth - 1);
                            if (!valid)
                            {
                                result = PropagationResult.CONTRADICTION;
                            }
                        }
                        RestoreBackup(backup);

                        if (result == PropagationResult.CONTRADICTION)
                        {
                            board[x, y] = feature == 3 ? (byte)4 : (byte)3;
                            PropagateConstraintsImpl(new Tuple <int, int>(x, y));
                            changed = true;
                        }
                    }
                }
            }
            if (changed)
            {
                SolveImpl(Log, depth);
                return;
            }
            valid = PropagateConstraintsImpl(null) != PropagationResult.CONTRADICTION;
        }
        // old search method

        /*
         *      private void search2(IBestChoiceSearcher bestChoiceSearcher, PropagationResult result, List<Solution> solutions)
         *      {
         *              Set[,] s = result.matrix;
         *
         *  // Find the top list of possible choices of Set with maximum minFactor range.
         *              List<FactorRangeRecord> bestRecords = searchForTheBestRecords(s);
         *  // If the it is only one possible Set, after shorten will be matrix singleton
         *              bool isSingleton = bestRecords.Count == 1;
         *
         *  // Find the set to be shortened.
         *              FactorRangeRecord best = bestChoiceSearcher.chooseBestRecord(bestRecords);
         *              Set currentSet = s[best.Row, best.Col];
         *
         *              // Create the order in which we will try to find a solution, best possibility first.
         *              List<int> sortedMinutes = new List<int>(currentSet.MinimizationFactor.Keys);
         *              sortedMinutes.Sort(delegate(int i, int j)
         *              {
         *                      return currentSet.MinimizationFactor[i] - currentSet.MinimizationFactor[j];
         *              });
         *
         *              // Search for the solution.
         *              foreach (int minute in sortedMinutes)
         *              {
         *                      // TODO: Use the branch and bound prunning.
         *
         *                      // Copy the matrix.
         *                      Set[,] newMatrix = GenerationAlgorithmPESPUtil.cloneDiscreteSetMatrix(s);
         *
         *                      // Create a singleton set.
         *                      Set newSet = new Set(currentSet.Modulo);
         *                      newSet.Add(minute, currentSet.MinimizationFactor[minute]);
         *
         *                      // Remeber to the new matrix.
         *                      newMatrix[best.Row, best.Col] = newSet;
         *                      newMatrix[best.Col, best.Row] = new Set(newSet);
         *                      newMatrix[best.Col, best.Row].Reverse();
         *
         *                      // Propagate newly created constraints.
         *                      PropagationUtils.propagate(newMatrix, result.TrainLinesMap);
         *
         *                      // Check if the solution may be found.
         *                      if (!MatrixUtils.isValid(s))
         *                      {
         *                              continue;
         *                      }
         *
         *                      // If the solution is found, remember it, otherwise search for it.
         *                      if (isSingleton)
         *                      {
         *                              solutions.Add(new Solution(newMatrix));
         *                      }
         *                      else
         *                      {
         *                              search(new PropagationResult(newMatrix, result.TrainLinesMap), solutions);
         *                      }
         *              }
         *      }
         */

        /// <summary>
        /// Searches for solution.
        /// It is called recursively, backtracking all possiblities with respect to specific choice searcher.
        /// </summary>
        /// <param name="bestChoiceSearcher">The best choice searcher.</param>
        /// <param name="propagationResult">The propagation result.</param>
        /// <param name="solutions">The solutions.</param>
        /// <returns>True if solution found, terminate recursive calls. Otherwise continue in backtracking.</returns>
        private Boolean search(IBestChoiceSearcher bestChoiceSearcher, PropagationResult propagationResult, List <Solution> solutions)
        {
            //reportProgress();

            // retreive discrete set matrix after propagation from propagation result
            Set[,] discreteSetMatrix = propagationResult.DiscreteSetMatrix;

            // while until you can still find some solution (still can found best record)
            while (true)
            {
                // Propagate newly created constraints.
                PropagationUtil.propagate(discreteSetMatrix, propagationResult.TrainLinesMap);

                // Check if the solution may be found.
                if (!MatrixUtils.isValid(discreteSetMatrix))
                {
                    // No valid matrix - solution can not be found.
                    return(false);
                }

                // Find the set to be shortened.
                FactorRangeRecord bestRecord;

                // if no best record found ()
                if (!bestChoiceSearcher.chooseBestRecord(discreteSetMatrix, out bestRecord))
                {
                    // then solution found, matrix is single (contains singletons only).
                    solutions.Add(new Solution(discreteSetMatrix));

                    // End of recursive calls
                    return(true);
                }

                reportProgress();

                // fix one potential set with item founded as best
                Set[,] newMatrix = fixOnePotentialOfSetInMatrix(discreteSetMatrix, bestRecord);

                // matrix was changed, continue in recursive calls
                Boolean solutionFound = search(bestChoiceSearcher, new PropagationResult(newMatrix, propagationResult.TrainLinesMap), solutions);

                // Test if solution was found
                if (solutionFound)
                {
                    return(true);
                }

                // after return from recursive call, remove fixed object and try to
                discreteSetMatrix[bestRecord.Row, bestRecord.Col].Remove(bestRecord.MinItemOfSet);
                discreteSetMatrix[bestRecord.Col, bestRecord.Row].RemoveReverse(bestRecord.MinItemOfSet);
            }
        }
Beispiel #5
0
        /// <summary>
        /// Runs the bisection algorithm for initial phase of constraint propagation.
        /// </summary>
        /// <param name="constraints">List of constraints.</param>
        /// <param name="constraintSetsCreator">Creator of the sets of constraints.</param>
        /// <param name="lowerBoundStart">Lower bound for the bisection search.</param>
        /// <param name="upperBoundStart">Upper bound for the bisection search.</param>
        /// <returns>Result of the initial algorithm phase.</returns>
        public static PropagationResult Bisect(List <Constraint> constraints, IConstraintSetsCreator constraintSetsCreator, int lowerBoundStart, int upperBoundStart)
        {
            // create the result.
            PropagationResult result = new PropagationResult();

            //-------bisection-algorithm-for-finding-the-proper-bound-for-discret-set------
            // set default lower and upper bounds
            int lowerBound = lowerBoundStart;
            int upperBound = upperBoundStart;
            // set the boolean loop variable
            Boolean loop = true;

            int midpoint = 0;

            // loop while bounds are not crossed and loop
            while ((upperBound - lowerBound) > 1 && loop)
            {
                midpoint = (upperBound + lowerBound) / 2;

                // run rpopagation algorithm, which create constraintSet, constraintMatrix
                // and propagate it (make it stable)
                result = PropagationUtil.runPropagationAlgorithm(constraints, constraintSetsCreator, midpoint);

                // if the constraint matrix is stable (previously), and valid
                if (MatrixUtils.isValid(result.DiscreteSetMatrix))
                {
                    // change upperbound of interval, right part is thrown away
                    upperBound = midpoint;
                }
                else
                {
                    // change lowerbound of interval, left part is thrown away
                    lowerBound = midpoint;
                }
            }

            // if the current found value is not valid, move to the looser restrictions
            while (!MatrixUtils.isValid(result.DiscreteSetMatrix) && midpoint <= upperBoundStart)
            {
                result = PropagationUtil.runPropagationAlgorithm(constraints, constraintSetsCreator, ++midpoint);
            }

            // return the found result.
            return(result);
        }
        /// <summary>
        /// Runs the specialized generation algorithm.
        /// Propagetes constraints, searches for solutions and constructs timetables.
        /// </summary>
        /// <param name="constraints">The constraints.</param>
        /// <param name="constraintPropagator">The constraint propagator.</param>
        /// <param name="bestChoiceSearcher">The best choice searcher.</param>
        /// <returns>The timetables.</returns>
        public void runSpecializedGenerationAlgorithm(List <Constraint> constraints, IConstraintPropagator constraintPropagator,
                                                      IBestChoiceSearcher bestChoiceSearcher, List <Timetable> timetables)
        {
            // start time
            Stopwatch watch = new Stopwatch();

            watch.Start();

            // Propagate constraints with specific constraintPropagator
            PropagationResult propagationResult = constraintPropagator.runPropagationAlgorithm(constraints, GenerationAlgorithmDSAUtil.MODULO_DEFAULT);
            // Search for the solution with specific bestChoiceSearcher
            List <Solution> solutions = runSearchAlgorithm(bestChoiceSearcher, propagationResult);

            // finish time
            watch.Stop();
            TimeSpan runningTime = watch.Elapsed;

            // crete note for generated solutions
            String note = constraintPropagator.getDescription() + ", " + bestChoiceSearcher.getDescription();

            // Construct timetables from solutions generated above.
            runConstructionTimetableAlgorithm(solutions, propagationResult.TrainLinesMap, timetables, stepCount, note, runningTime);
        }
        /// <summary>
        /// Runs the search algorithm.
        /// Call method Search, which search for solutions.
        /// </summary>
        /// <param name="bestChoiceSearcher">The best choice searcher.</param>
        /// <param name="propagationResult">The propagation result.</param>
        /// <returns>The solutions.</returns>
        public List <Solution> runSearchAlgorithm(IBestChoiceSearcher bestChoiceSearcher, PropagationResult propagationResult)
        {
            List <Solution> solutions = new List <Solution>();

            search(bestChoiceSearcher, propagationResult, solutions);

            return(solutions);
        }