void CountSlacksAndArtificialsForConstraint(Constraint constraint, double[] xStar) { double rightSide = constraint.rightSide - LP.DotProduct(constraint.coeffs, xStar); switch (constraint.relation) { case Relation.Equal: nArtificials++; break; case Relation.GreaterOrEqual: nSlacks++; if (rightSide > 0) { nArtificials++; } break; case Relation.LessOrEqual: nSlacks++; if (rightSide < 0) { nArtificials++; } break; } }
public double GetMinimalValue() { if (Status == Status.Unknown || Status == Status.Feasible) { Minimize(); } if (Status == Status.Optimal) { double[] sol = MinimalSolution(); return(-LP.DotProduct(sol, costs, costs.Length)); //minus since we reversed the costs } return(0); }
void FillFirstStageSolverAndCosts( bool[] solverLowBoundIsSet, double[] solverLowBounds, bool[] solverUpperBoundIsSet, double[] solverUpperBounds, double[] solverCosts, Matrix A, int[] basis, double[] xStar) { Contract.Requires(solverUpperBounds != null); Contract.Requires(solverLowBounds != null); Contract.Requires(solverLowBoundIsSet != null); Contract.Requires(solverUpperBoundIsSet != null); Contract.Requires(solverCosts != null); Contract.Requires(A != null); Contract.Requires(xStar != null); int slackVar = NVars; int artificialVar = NVars + nSlacks; int row = 0; foreach (Constraint c in constraints) { Contract.Assume(row < basis.Length); //we need to bring the program to the form Ax=b double rs = c.rightSide - LP.DotProduct(xStar, c.coeffs, nVars); switch (c.relation) { case Relation.Equal: //no slack variable here if (rs >= 0) { SetZeroBound(solverLowBoundIsSet, solverLowBounds, artificialVar); Contract.Assume(artificialVar < solverCosts.Length); solverCosts[artificialVar] = -1; //we are maximizing, so the artificial, which is non-negatiive, will be pushed to zero } else { SetZeroBound(solverUpperBoundIsSet, solverUpperBounds, artificialVar); Contract.Assume(artificialVar < solverCosts.Length); solverCosts[artificialVar] = 1; } basis[row] = artificialVar; A[row, artificialVar++] = 1; break; case Relation.GreaterOrEqual: //introduce a non-positive slack variable, Contract.Assume(slackVar < solverUpperBoundIsSet.Length); Contract.Assume(slackVar < solverUpperBounds.Length); SetZeroBound(solverUpperBoundIsSet, solverUpperBounds, slackVar); A[row, slackVar] = 1; if (rs > 0) { //adding one artificial which is non-negative SetZeroBound(solverLowBoundIsSet, solverLowBounds, artificialVar); A[row, artificialVar] = 1; solverCosts[artificialVar] = -1; basis[row] = artificialVar++; } else { //we can put slackVar into basis, and avoid adding an artificial variable //We will have an equality c.coefficients*acceptableCosts+x[slackVar]=c.rightSide, or x[slackVar]=rs<=0. basis[row] = slackVar; } slackVar++; break; case Relation.LessOrEqual: //introduce a non-negative slack variable, Contract.Assume(slackVar < solverLowBoundIsSet.Length); Contract.Assume(slackVar < solverLowBounds.Length); SetZeroBound(solverLowBoundIsSet, solverLowBounds, slackVar); A[row, slackVar] = 1; if (rs < 0) { //adding one artificial which is non-positive SetZeroBound(solverUpperBoundIsSet, solverUpperBounds, artificialVar); A[row, artificialVar] = 1; Contract.Assume(artificialVar < solverCosts.Length); solverCosts[artificialVar] = 1; basis[row] = artificialVar++; } else { //we can put slackVar into basis, and avoid adding an artificial variable //We will have an equality c.coefficients*acceptableCosts+x[slackVar]=c.rightSide, or x[slackVar]=rs<=0. basis[row] = slackVar; } slackVar++; break; } xStar[basis[row]] = rs; row++; } }