示例#1
0
 /// <summary>
 /// Build a constraint involving two linear equations.
 /// </summary>
 /// <param name="lhsCoefficients">The coefficients of the linear expression on the left hand side of the constraint</param>
 /// <param name="lhsConstant">The constant term of the linear expression on the left hand side of the constraint</param>
 /// <param name="relationship">The type of (in)equality used in the constraint</param>
 /// <param name="rhsCoefficients">The coefficients of the linear expression on the right hand side of the constraint</param>
 /// <param name="rhsConstant">The constant term of the linear expression on the right hand side of the constraint</param>
 public LinearConstraint(T[] lhsCoefficients, T lhsConstant,
                         Relationship relationship,
                         T[] rhsCoefficients, T rhsConstant)
 {
     T[] sub = new T[lhsCoefficients.Length];
     for (int i = 0; i < sub.Length; ++i)
     {
         sub[i] = Policy.Sub(lhsCoefficients[i], rhsCoefficients[i]);
     }
     Coefficients = new Vector <T, TPolicy>(sub, false);
     Relationship = relationship;
     Value        = Policy.Sub(rhsConstant, lhsConstant);
 }
示例#2
0
        /// <summary>
        /// Subtract and normalize
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static Rational <T, TPolicy> operator -(Rational <T, TPolicy> a, Rational <T, TPolicy> b)
        {
            if (Policy.IsZero(a.Numerator))
            {
                return(b);
            }
            if (Policy.IsZero(b.Numerator))
            {
                return(a);
            }

            if (Policy.IsOne(a.Denominator) && Policy.IsOne(b.Denominator))
            {
                return(new Rational <T, TPolicy>(Policy.Sub(a.Numerator, b.Numerator), a.Denominator));
            }

            var d  = Policy.Lcd(a.Denominator, b.Denominator);
            var an = Policy.Mul(a.Numerator, (Policy.Div(d, a.Denominator)));
            var bn = Policy.Mul(b.Numerator, (Policy.Div(d, b.Denominator)));

            return(new Rational <T, TPolicy>(Policy.Sub(an, bn), d).Normalize());
        }
示例#3
0
        /// <summary>
        /// Returns the column with the most negative coefficient in the objective function row.
        /// </summary>
        /// <param name="tableau"></param>
        /// <returns></returns>
        private int?GetPivotColumn(SimplexTableau <T, TPolicy> tableau)
        {
            T   minValue = Policy.Zero();
            int?minPos   = null;

            for (int i = tableau.NumObjectiveFunctions; i < tableau.Width - 1; i++)
            {
                T entry = tableau.GetEntry(0, i);
                // check if the entry is strictly smaller than the current minimum
                // do not use a ulp/epsilon check
                if (Policy.IsBelowZero(Policy.Sub(entry, minValue)))
                {
                    minValue = entry;
                    minPos   = i;

                    // Bland's rule: chose the entering column with the lowest index
                    if (pivotSelection == PivotSelectionRule.BLAND && IsValidPivotColumn(tableau, i))
                    {
                        break;
                    }
                }
            }
            return(minPos);
        }
示例#4
0
        /// <summary>
        /// Create the tableau by itself.
        /// </summary>
        /// <param name="maximize">if true, goal is to maximize the objective function</param>
        /// <returns>created tableau</returns>
        protected Matrix <T, TPolicy> CreateTableau(bool maximize)
        {
            // create a matrix of the correct size
            int width = numDecisionVariables + numSlackVariables +
                        numArtificialVariables + NumObjectiveFunctions + 1; // + 1 is for RHS
            int height = constraints.Count + NumObjectiveFunctions;
            var matrix = new Matrix <T, TPolicy>(width, height);

            var minusOne = Policy.Sub(Policy.Zero(), Policy.One());

            // initialize the objective function rows
            if (NumObjectiveFunctions == 2)
            {
                matrix[0, 0] = minusOne;
            }

            int zIndex = (NumObjectiveFunctions == 1) ? 0 : 1;

            matrix[zIndex, zIndex] = maximize ? Policy.One() : minusOne;

            Vector <T, TPolicy> objectiveCoefficients = maximize ? f.Coefficients * minusOne : f.Coefficients;
            var rowData = matrix.GetRow(zIndex);

            CopyArray(objectiveCoefficients.Data, rowData);
            matrix.SetRow(zIndex, rowData);
            matrix[width - 1, zIndex] = maximize ? f.ConstantTerm : Policy.Mul(minusOne, f.ConstantTerm);

            if (!restrictToNonNegative)
            {
                matrix[SlackVariableOffset - 1, zIndex] = InvertedCoefficientSum(objectiveCoefficients);
            }

            // initialize the constraint rows
            int slackVar      = 0;
            int artificialVar = 0;

            for (int i = 0; i < constraints.Count; i++)
            {
                var constraint = constraints[i];
                int row        = NumObjectiveFunctions + i;

                rowData = matrix.GetRow(row);
                // decision variable coefficients
                CopyArray(constraint.Coefficients.Data, rowData);
                matrix.SetRow(row, rowData);
                // x-
                if (!restrictToNonNegative)
                {
                    matrix[SlackVariableOffset - 1, row] =
                        InvertedCoefficientSum(constraint.Coefficients);
                }

                // RHS
                matrix[width - 1, row] = constraint.Value;

                // slack variables
                if (constraint.Relationship == Relationship.LEQ)
                {
                    matrix[SlackVariableOffset + slackVar++, row] = Policy.One();  // slack
                }
                else if (constraint.Relationship == Relationship.GEQ)
                {
                    matrix[SlackVariableOffset + slackVar++, row] = minusOne; // excess
                }

                // artificial variables
                if ((constraint.Relationship == Relationship.EQ) ||
                    (constraint.Relationship == Relationship.GEQ))
                {
                    matrix[ArtificialVariableOffset + artificialVar, 0]     = Policy.One();
                    matrix[ArtificialVariableOffset + artificialVar++, row] = Policy.One();
                    matrix.SetRowVector(0, matrix.GetRowVector(0) - matrix.GetRowVector(row));
                }
            }

            return(matrix);
        }
示例#5
0
 /// <summary>
 /// True if |x - y| &lt;= eps
 /// </summary>
 /// <param name="x"></param>
 /// <param name="y"></param>
 /// <param name="eps"></param>
 /// <returns></returns>
 public static bool Equals(T x, T y, T eps)
 {
     return(Policy.IsBelowZero(Policy.Sub(Policy.Abs(Policy.Sub(y, x)), eps)));
 }