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); }
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. }
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); } }
/// <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); }