Ejemplo n.º 1
0
        public void DegeneracyTest()
        {
            #region Arrange
            var target = new Solver();

            var lc1 = new LinearConstraint()
            {
                Coefficients = new double[3] { 1, 1, 0 },
                Relationship = Relationship.LessThanOrEquals,
                Value = 1
            };

            var lc2 = new LinearConstraint()
            {
                Coefficients = new double[3] { 0, -1, 1 },
                Relationship = Relationship.LessThanOrEquals,
                Value = 0
            };

            var constraints = new List<LinearConstraint>() { lc1, lc2 };

            var goal = new Goal()
            {
                Coefficients = new double[3] { 1, 1, 1 },
                ConstantTerm = 0
            };

            var model = new Model()
            {
                Constraints = constraints,
                Goal = goal,
                GoalKind = GoalKind.Maximize
            };

            var expected = new Solution()
            {
                Decisions = new double[3] { 0, 1, 1 },
                Quality = SolutionQuality.Optimal,
                AlternateSolutionsExist = false,
                OptimalValue = 2
            };
            #endregion

            //Act
            var actual = target.Solve(model);

            //Assert
            CollectionAssert.AreEqual(expected.Decisions, actual.Decisions);
            Assert.AreEqual(expected.Quality, actual.Quality);
            Assert.AreEqual(expected.AlternateSolutionsExist, actual.AlternateSolutionsExist);
        }
Ejemplo n.º 2
0
        public void Simple2PhaseFromPaper()
        {
            #region Arrange
            var target = new Solver();

            var lc1 = new LinearConstraint()
            {
                Coefficients = new double[2] { 1, 1 },
                Relationship = Relationship.GreaterThanOrEquals,
                Value = 4
            };

            var lc2 = new LinearConstraint()
            {
                Coefficients = new double[2] { 1, -1 },
                Relationship = Relationship.GreaterThanOrEquals,
                Value = 1
            };

            var lc3 = new LinearConstraint()
            {
                Coefficients = new double[2] { -1, 2 },
                Relationship = Relationship.GreaterThanOrEquals,
                Value = -1
            };

            var constraints = new List<LinearConstraint>() { lc1, lc2, lc3 };

            var goal = new Goal()
            {
                Coefficients = new double[2] { 1, 2 },
                ConstantTerm = 0
            };

            var model = new Model()
            {
                Constraints = constraints,
                Goal = goal,
                GoalKind = GoalKind.Minimize
            };

            var expected = new Solution()
            {
                Decisions = new double[2] { 3, 1 },
                Quality = SolutionQuality.Optimal,
                AlternateSolutionsExist = false,
                OptimalValue = 5
            };
            #endregion

            //Act
            var actual = target.Solve(model);

            //Assert
            CollectionAssert.AreEqual(expected.Decisions, actual.Decisions);
            Assert.AreEqual(expected.Quality, actual.Quality);
            Assert.AreEqual(expected.AlternateSolutionsExist, actual.AlternateSolutionsExist);
        }
Ejemplo n.º 3
0
        public void TwoPhaseClassTest()
        {
            #region Arrange
            var target = new Solver();

            var lc1 = new LinearConstraint()
            {
                Coefficients = new double[2] { 1, 1 },
                Relationship = Relationship.LessThanOrEquals,
                Value = 35
            };

            var lc2 = new LinearConstraint()
            {
                Coefficients = new double[2] { 1, 2 },
                Relationship = Relationship.LessThanOrEquals,
                Value = 38
            };

            var lc3 = new LinearConstraint()
            {
                Coefficients = new double[2] { 2, 2 },
                Relationship = Relationship.LessThanOrEquals,
                Value = 50
            };

            var constraints = new List<LinearConstraint>() { lc1, lc2, lc3 };

            var goal = new Goal()
            {
                Coefficients = new double[2] { 350, 450 },
                ConstantTerm = 0
            };

            var model = new Model()
            {
                Constraints = constraints,
                Goal = goal,
                GoalKind = GoalKind.Maximize
            };

            var expected = new Solution()
            {
                Decisions = new double[2] { 12, 13 },
                Quality = SolutionQuality.Optimal,
                AlternateSolutionsExist = false,
                OptimalValue = 10050 // 12*350 + 13*450
            };

            var actual = target.Solve(model);

            #endregion
            ////Act

            ////Assert
            CollectionAssert.AreEqual(expected.Decisions, actual.Decisions);
            Assert.AreEqual(expected.Quality, actual.Quality);
            Assert.AreEqual(expected.AlternateSolutionsExist, actual.AlternateSolutionsExist);
        }
Ejemplo n.º 4
0
        public Solution Solve(Model model)
        {
            DenseVector testVect = DenseVector.Create(10, delegate(int s) { return s; });

            DenseMatrix coefficients = createMatrix(model);

            //gets the coefficients from the goal
            DenseVector objFunCoeffs = new DenseVector(model.Goal.Coefficients);

            //adds zeroes for the surplus/slack/artificial variables
            DenseVector objFunValues = DenseVector.Create((coefficients.ColumnCount), delegate(int s) { return 0; });
            objFunValues.SetSubVector(0, objFunCoeffs.Count, objFunCoeffs);

            //flips the sign of everything
            if (model.GoalKind == GoalKind.Maximize)
            {
                objFunValues = DenseVector.Create((coefficients.ColumnCount), delegate(int s) { return -objFunValues[s]; });
            }

            //here so I don't have to pass the model in :)
            numConstraints = model.Constraints.Count;

            //Maybe I could be smarter about where I put this (at the end of createMatrix?)
            //take care of artificial variable stuff
            if(numArtificial > 0)
            {
                //adds the z row to the coefficients matrix
                    //adds the column first
                coefficients = (DenseMatrix)coefficients.Append(DenseVector.Create((coefficients.RowCount), delegate(int s) { return 0; }).ToColumnMatrix());
                coefficients = (DenseMatrix)coefficients.InsertRow(coefficients.RowCount, DenseVector.Create(coefficients.ColumnCount, delegate(int s) {
                    if (s == coefficients.ColumnCount - 1)
                        return 1;
                    else
                        return -objFunValues[s];
                }));

                //adds a 0 to match the z row
                rhsValues = DenseVector.Create(rhsValues.Count + 1, delegate(int s)
                {
                    if (s == rhsValues.Count)
                    {
                        return model.Goal.ConstantTerm;
                    }
                    else
                    {
                        return rhsValues[s];
                    }
                });

                //changes the objFunValues to be the w thingy
                objFunValues = DenseVector.Create(coefficients.ColumnCount, delegate(int s)
                {
                    double sum = 0;

                    //minus 1 because we also added a column for z
                    if (s < coefficients.ColumnCount - numArtificial - 1)
                    {
                        //calculate each w row entry by
                        foreach (int index in artificialRows)
                        {
                            sum += coefficients[index, s];
                        }

                        return sum;
                    }
                    else
                    {
                        return 0;
                    }
                });

                //z is now a basic variable??
                basics.Add(coefficients.ColumnCount - 1);

                printMat(coefficients);

                //solves it for that
                optimize(coefficients, objFunValues, true);

                basics.Remove(coefficients.ColumnCount - 1);

                //gets rid of the last value
                rhsValues = (DenseVector)rhsValues.SubVector(0, (rhsValues.Count - 1));

                //chops off the z row and the artificial variables
                coefficients = (DenseMatrix)coefficients.SubMatrix(0, coefficients.RowCount - 1, 0, coefficients.ColumnCount - 1 - numArtificial);
            }

            printMat(coefficients);
            optimize(coefficients, objFunValues, false);

            /*
             * To find the solution:
             *      The first columns in the mattress (that aren't
             *      ssa variables) should be basic variables
             *      Find what the final value is by finding their indices
             *      in basics and then the value at that index in xprimes
             *      should be what you're looking for    I think
             *      At least it's somewhere in xprimes
             */
            double[] solution = new double[model.Goal.Coefficients.Length];
            double op = model.Goal.ConstantTerm;

            for(int i = 0; i < solution.Length; i++)
            {
                solution[i] = xPrime[basics.IndexOf(i), 0];
                op += solution[i] * model.Goal.Coefficients[i];
            }

            Solution sol = new Solution()
            {
                Decisions = solution,
                OptimalValue = op,
                AlternateSolutionsExist = false,
                Quality = SolutionQuality.Optimal
            };

            return sol;
        }