예제 #1
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);
        }
예제 #2
0
 /// <summary>
 /// Multiply 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)
 {
     return(new Rational <T, TPolicy>(Policy.Mul(a.Numerator, b.Numerator), Policy.Mul(a.Denominator, b.Denominator)).Normalize());
 }