// 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);
            }
        }
예제 #2
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);
        }