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++;
            }
        }