static bool Solve(ISolverShell solver, ProjSolv.Parameters parameters) { bool executionLimitExceeded = false, retval = true; if (!solver.Solve(parameters, out executionLimitExceeded)) { System.Console.WriteLine(" Error - Solve failed"); ++s_cExecutionFailed; retval = false; } if (executionLimitExceeded) { System.Console.WriteLine(" Warning - one or more execution limits were exceeded"); ++s_cExecutionLimitExceeded; } return(retval); }
private static void Test_dummy_ideal_position() { //just test for equation (x-500)^2 -> min ISolverShell solver = new SolverShell(); solver.AddVariableWithIdealPosition(0, 10, 0.000001); solver.AddFixedVariable(1, 500); solver.AddGoalTwoVariablesAreClose(0, 1, 100000.0); // The default parameters have too large a QpscConvergenceQuotient and too // small an OuterProjectIterationsLimit (we don't add constraints here so the // inner iterations do nothing and all movement is done by the QPSC step adjustments // in the outer iterations). ProjSolv.Parameters parameters = new ProjSolv.Parameters(); parameters.QpscConvergenceQuotient = 1e-14; parameters.OuterProjectIterationsLimit = 0; // no limit Solve(solver, parameters); System.Console.WriteLine(solver.GetVariableResolvedPosition(0)); System.Console.WriteLine(solver.GetVariableResolvedPosition(1)); }
internal Qpsc(Parameters solverParameters, int cVariables) { this.solverParameters = solverParameters; this.matrixQ = new MatrixCell[cVariables][]; this.vectorWiDi = new double[cVariables]; this.vectorQpscVars = new QpscVar[cVariables]; this.gradientVector = new double[cVariables]; this.vectorQg = new double[cVariables]; this.vectorPrevY = new double[cVariables]; this.vectorCurY = new double[cVariables]; }
/// <summary> /// Sets Variable.ActualPos to the positions of the Variables that minimally satisfy the constraints /// along this axis. This overload takes a parameter specification. /// </summary> /// <param name="solverParameters">Solution-generation options.</param> /// <returns>The only failure condition is if there are one or more unsatisfiable constraints, such as cycles /// or mutually exclusive equality constraints; if these are encountered, a list of lists of these /// constraints is returned, where each list contains a single cycle, which may be of length one for /// unsatisfiable equality constraints. Otherwise, the return value is null.</returns> public Solution Solve(Parameters solverParameters) { if (null != solverParameters) { this.solverParams = (Parameters)solverParameters.Clone(); } // Reset some parameter defaults to per-solver-instance values. if (this.solverParams.OuterProjectIterationsLimit < 0) { // If this came in 0, it stays that way, and there is no limit. Otherwise, set it to a value // reflecting the expectation of convergence roughly log-linearly in the number of variables. #if SHARPKIT //https://github.com/SharpKit/SharpKit/issues/4 integer rounding issue this.solverParams.OuterProjectIterationsLimit = 100 * (((int)Math.Log(this.numberOfVariables, 2.0)) + 1); #else this.solverParams.OuterProjectIterationsLimit = 100 * ((int)Math.Log(this.numberOfVariables, 2.0) + 1); #endif } if (this.solverParams.InnerProjectIterationsLimit < 0) { // If this came in 0, it stays that way, and there is no limit. Otherwise, assume that for // any pass, each constraint may be violated (most likely this happens only on the first pass), // and add some extra based upon constraint count. Now that we split and retry on unsatisfied // constraints, assume that any constraint may be seen twice on a pass. #if SHARPKIT //https://github.com/SharpKit/SharpKit/issues/4 integer rounding issue this.solverParams.InnerProjectIterationsLimit = (this.numberOfConstraints * 2) + (100 * (((int)Math.Log(this.numberOfConstraints, 2.0)) + 1)); #else this.solverParams.InnerProjectIterationsLimit = (this.numberOfConstraints * 2) + (100 * ((int)Math.Log(this.numberOfConstraints, 2.0) + 1)); #endif } // ReSolving can be done for updated constraints. bool isReSolve = !this.allConstraints.IsEmpty; CheckForUpdatedConstraints(); this.solverSolution = new Solution { MinInnerProjectIterations = int.MaxValue }; this.allConstraints.MaxConstraintTreeDepth = 0; this.allConstraints.SolverParameters = this.solverParams; // // First set up all the internal stuff we'll use for solutions. // #if CACHE_STATS cacheStats.Clear(); #endif // CACHE_STATS // If no constraints have been loaded, there's nothing to do. Two distinct variables // are required to create a constraint, so this also ensures a minimum number of variables. if (0 == this.numberOfConstraints) { // For Qpsc, we may have neighbours but no constraints. if (!this.IsQpsc) { return (Solution)this.solverSolution.Clone(); } } else if (!isReSolve) { SetupConstraints(); } // This is the number of unsatisfiable constraints encountered. this.allConstraints.NumberOfUnsatisfiableConstraints = 0; // Merge Equality constraints first. These do not do any constraint-splitting, and thus // remain in the same blocks, always satisfied, regardless of whether we're solving the full // Qpsc or the simpler loop. MergeEqualityConstraints(); // Prepare for timeout checking. if (this.solverParams.TimeLimit > 0) { this.timeoutStopwatch = new Stopwatch(); this.timeoutStopwatch.Start(); } // // Done with initial setup. Now if we have neighbour pairs, we do the full SolveQpsc logic // complete with Gradient projection. Otherwise, we have a much simpler Project/Split loop. // if (this.IsQpsc) { this.SolveQpsc(); } else { this.SolveByStandaloneProject(); this.CalculateStandaloneProjectGoalFunctionValue(); } // We initialized this to int.MaxValue so make sure it's sane if we didn't complete a Project iteration. if (this.solverSolution.MinInnerProjectIterations > this.solverSolution.MaxInnerProjectIterations) { // Probably this is 0. this.solverSolution.MinInnerProjectIterations = this.solverSolution.MaxInnerProjectIterations; } #if CACHE_STATS cacheStats.Print(); Console.WriteLine(" NumFinalBlocks = {0}, MinCacheBlocks = {1}, MaxCacheSize = {2}", allBlocks.Count, violationCacheMinBlockCutoff, ViolationCache.MaxConstraints); #endif // CACHE_STATS // Done. Caller will copy each var.ActualPos back to the Nodes. If we had any unsatisfiable // constraints, copy them back out to the caller. this.solverSolution.NumberOfUnsatisfiableConstraints = this.allConstraints.NumberOfUnsatisfiableConstraints; #if BLOCK_STATS int minBlockVars = this.numberOfVariables; int maxBlockVars = 0; foreach (Block block in allBlocks.Vector) { if (minBlockVars > block.Variables.Count) { minBlockVars = block.Variables.Count; } if (maxBlockVars < block.Variables.Count) { maxBlockVars = block.Variables.Count; } } // endforeach block Console.WriteLine("Num final Blocks: {0}, Min Block Vars: {1}, Max Block Vars: {2}", allBlocks.Count, minBlockVars, maxBlockVars); #endif // BLOCK_STATS this.solverSolution.MaxConstraintTreeDepth = this.allConstraints.MaxConstraintTreeDepth; return (Solution)this.solverSolution.Clone(); } // end Solve()
internal bool VerifyConstraint(Parameters solverParameters, Constraint cst, bool isHorizontal, ref bool violationsSeen) { if (cst.IsUnsatisfiable) { return true; } bool hasViolation = cst.Violation > solverParameters.GapTolerance; if (cst.IsEquality) { hasViolation = Math.Abs(cst.Violation) > solverParameters.GapTolerance; } if (hasViolation) { if (!violationsSeen) { WriteLine(" {0} Violation(s) of Constraint(s) that were not marked Unsatisfiable:", isHorizontal ? "X" : "Y"); violationsSeen = true; } if (TestGlobals.VerboseLevel >= 1) { WriteLine(" {0}", cst); } } return !hasViolation; }
/// <summary> /// Constructor taking OverlapRemoval parameter and solver parameters. /// </summary> /// <param name="allowDeferToVertical"></param> /// <param name="solverParameters"></param> public OverlapRemovalParameters(bool allowDeferToVertical, Parameters solverParameters) { this.AllowDeferToVertical = allowDeferToVertical; this.SolverParameters = solverParameters; }
/// <summary> /// Constructor taking solver parameters. /// </summary> /// <param name="solverParameters"></param> public OverlapRemovalParameters(Parameters solverParameters) { this.SolverParameters = solverParameters; AllowDeferToVertical = true; }