예제 #1
0
        public void DuplexMethodSolverTest2()
        {
            DenseMatrix a = DenseMatrix.OfArray(new double[,]
                                                {
                                                    { 1, 0, 2, 2, -3, 3 },
                                                    { 0, 1, 0, -1, 0, 1 },
                                                    { 1, 0, 1, 3, 2, 1 }
                                                });
            DenseVector b = new DenseVector(new double[] { 15, 0, 13 });
            DenseVector c = new DenseVector(new double[] { 3, 0.5, 4, 4, 1, 5 });
            DenseVector dLower = new DenseVector(new double[] { 0, 0, 0, 0, 0, 0 });
            DenseVector dUpper = new DenseVector(new double[] { 3, 5, 4, 3, 3, 4 });

            DenseVector expectedResult = new DenseVector(new double[] { 3,  0, 4, 1.1818, 0.6364, 1.1818 });

            var qps = new DuplexMethodBoundsSolver(a, b, c, dLower, dUpper);
            var actualResult = qps.Solve();
            Assert.AreEqual(expectedResult, RoundVector(actualResult, 4));
            Assert.AreEqual(36.2727, Math.Round(qps.ResultCost, 4));
        }
예제 #2
0
        public void DuplexMethodSolverTest1()
        {
            DenseMatrix a = DenseMatrix.OfArray(new double[,]
                                                {
                                                    { 2, 1, -1, 0, 0, 1 },
                                                    { 1, 0, 1, 1, 0, 0 },
                                                    { 0, 1, 0, 0, 1, 0 }
                                                });
            DenseVector b = new DenseVector(new double[] { 2, 5, 0 });
            DenseVector c = new DenseVector(new double[] { 3, 2, 0, 3, -2, -4 });
            DenseVector dLower = new DenseVector(new double[] { 0, -1, 2, 1, -1, 0 });
            DenseVector dUpper = new DenseVector(new double[] { 2, 4, 4, 3, 3, 5 });

            DenseVector expectedResult = new DenseVector(new double[] { 3.0 / 2, 1, 2, 3.0 / 2, -1, 0 });

            var qps = new DuplexMethodBoundsSolver(a, b, c, dLower, dUpper);
            var actualResult = qps.Solve();
            Assert.AreEqual(expectedResult, actualResult);
            Assert.AreEqual(13, qps.ResultCost);
        }
예제 #3
0
        public void DuplexMethodSolverTest3()
        {
            DenseMatrix a = DenseMatrix.OfArray(new double[,]
                                                {
                                                    { 1, 0, 0, 12, 1, -3, 4, -1 },
                                                    { 0, 1, 0, 11, 12, 3, 5, 3 },
                                                    { 0, 0, 1, 1, 0, 22, -2, 1 }
                                                });
            DenseVector b = new DenseVector(new double[] { 40, 107, 61 });
            DenseVector c = new DenseVector(new double[] { 2, 1, -2, -1, 4, -5, 5, 5 });
            DenseVector dLower = new DenseVector(new double[] { 0, 0, 0, 0, 0, 0, 0, 0 });
            DenseVector dUpper = new DenseVector(new double[] { 3, 5, 5, 3, 4, 5, 6, 3 });

            DenseVector expectedResult = new DenseVector(new double[] { 3, 5, 0, 1.8779, 2.7545, 3.0965, 6, 3 });

            var qps = new DuplexMethodBoundsSolver(a, b, c, dLower, dUpper);
            var actualResult = qps.Solve();
            Assert.AreEqual(expectedResult, RoundVector(actualResult, 4));
            Assert.AreEqual(49.6577, Math.Round(qps.ResultCost, 4));
        }
예제 #4
0
        public void DuplexMethodSolverTest8()
        {
            DenseMatrix a = DenseMatrix.OfArray(new double[,]
                                                {
                                                    { 1, 3, 1, -1, 0, -3, 2, 1 },
                                                    { 2, 1, 3, -1, 1, 4, 1, 1 },
                                                    { -1, 0, 2, -2, 2, 1, 1, 1 }
                                                });
            DenseVector b = new DenseVector(new double[] { 4, 12, 4 });
            DenseVector c = new DenseVector(new double[] { 2, -1, 2, 3, -2, 3, 4, 1 });
            DenseVector dLower = new DenseVector(new double[] { -1, -1, -1, -1, -1, -1, -1, -1 });
            DenseVector dUpper = new DenseVector(new double[] { 2, 3, 1, 4, 3, 2, 4, 4 });

            DenseVector expectedResult = new DenseVector(new double[] { -1, 0.4074, 1, 4, -0.3704, 1.7407, 4, 4 });

            var qps = new DuplexMethodBoundsSolver(a, b, c, dLower, dUpper);
            var actualResult = qps.Solve();
            Assert.AreEqual(expectedResult, RoundVector(actualResult, 4));
            Assert.AreEqual(37.5556, Math.Round(qps.ResultCost, 4));
        }
예제 #5
0
        public void DuplexMethodSolverTest7()
        {
            DenseMatrix a = DenseMatrix.OfArray(new double[,]
                                                {
                                                    { 2, 1, 0, 3, -1, -1 },
                                                    { 0, 1, 2, 1, 0, 3 },
                                                    { 3, 0, 1, 1, 1, 1 }
                                                });
            DenseVector b = new DenseVector(new double[] { 2, 2, 5 });
            DenseVector c = new DenseVector(new double[] { 0, -1, 1, 0, 4, 3 });
            DenseVector dLower = new DenseVector(new double[] { 2, 0, -1, -3, 2, 1 });
            DenseVector dUpper = new DenseVector(new double[] { 7, 3, 2, 3, 4, 5 });

            var qps = new DuplexMethodBoundsSolver(a, b, c, dLower, dUpper);
            Assert.Catch<ArithmeticException>(() => qps.Solve());
        }
예제 #6
0
        public void DuplexMethodSolverTest5()
        {
            DenseMatrix a = DenseMatrix.OfArray(new double[,]
                                                {
                                                    { 1, 7, 2, 0, 1, -1, 4 },
                                                    { 0, 5, 6, 1, 0, -3, 2 },
                                                    { 3, 2, 2, 1, 1, 1, 5 }
                                                });
            DenseVector b = new DenseVector(new double[] { 1, 4, 7 });
            DenseVector c = new DenseVector(new double[] { 1, 2, 1, -3, 3, 1, 0 });
            DenseVector dLower = new DenseVector(new double[] { -1, 1, -2, 0, 1, 2, 4 });
            DenseVector dUpper = new DenseVector(new double[] { 3, 2, 2, 5, 3, 4, 5 });

            var qps = new DuplexMethodBoundsSolver(a, b, c, dLower, dUpper);
            Assert.Catch<ArithmeticException>(() => qps.Solve());
        }
예제 #7
0
        public void DuplexMethodSolverTest4()
        {
            DenseMatrix a = DenseMatrix.OfArray(new double[,]
                                                {
                                                    { 1, -3, 2, 0, 1, -1, 4, -1, 0 },
                                                    { 1, -1, 6, 1, 0, -2, 2, 2, 0 },
                                                    { 2, 2, -1, 1, 0, -3, 8, -1, 1 },
                                                    { 4, 1, 0, 0, 1, -1, 0, -1, 1 },
                                                    { 1, 1, 1, 1, 1, 1, 1, 1, 1 }
                                                });
            DenseVector b = new DenseVector(new double[] { 3, 9, 9, 5, 9 });
            DenseVector c = new DenseVector(new double[] { -1, 5, -2, 4, 3, 1, 2, 8, 3 });
            DenseVector dLower = new DenseVector(new double[] { 0, 0, 0, 0, 0, 0, 0, 0, 0 });
            DenseVector dUpper = new DenseVector(new double[] { 5, 5, 5, 5, 5, 5, 5, 5, 5 });

            DenseVector expectedResult = new DenseVector(new double[] { 1.1579, 0.6942, 0, 0, 2.8797, 0, 1.0627, 3.2055, 0 });

            var qps = new DuplexMethodBoundsSolver(a, b, c, dLower, dUpper);
            var actualResult = qps.Solve();
            Assert.AreEqual(expectedResult, RoundVector(actualResult, 4));
            Assert.AreEqual(38.7218, Math.Round(qps.ResultCost, 4));
        }
예제 #8
0
        private BAndBTask MakeUpperTask(BAndBTask oldTask, DuplexMethodBoundsSolver solvedProblem)
        {
            var newStartX = DenseVector.OfVector(solvedProblem.ResultX);
            var newStartBaseJ = new List<int>(solvedProblem.ResultBaseJ);

            var newLowerBound = DenseVector.OfVector(oldTask.LowerBound);
            newLowerBound[NonIntegerJ] = Math.Floor(solvedProblem.ResultX[NonIntegerJ]) + 1;
            return new BAndBTask(newLowerBound, oldTask.UpperBound, newStartX, newStartBaseJ);
        }
예제 #9
0
        public DenseVector Solve()
        {
            Eps = Math.Round(Math.Pow(0.1, MeaningDecimals), MeaningDecimals);
            RecordCost = StartRecord;
            Tasks = new Stack<BAndBTask>();
            Tasks.Push(new BAndBTask(dLower, dUpper));
            IterationCount = 0;
            while (Tasks.Any())
            {
                IterationCount++;
                var task = Tasks.Pop();
                var dms = new DuplexMethodBoundsSolver(A, b, c, task.LowerBound, task.UpperBound,
                    task.StartX, task.StartBaseJ);

                try
                {
                    dms.Solve();
                    dms.RoundResult();
                }
                catch (ArithmeticException)
                {
                    continue;
                }

                if (dms.ResultCost <= RecordCost)
                    continue;

                if (AreAllInteger(dms.ResultX))
                {
                    RecordCost = dms.ResultCost;
                    RecordX = DenseVector.OfVector(dms.ResultX);
                    HasResult = true;
                }
                else
                {
                    Tasks.Push(MakeLowerTask(task, dms));
                    Tasks.Push(MakeUpperTask(task, dms));
                }
            }

            if (!HasResult)
                throw new ArithmeticException("Plans not found");

            ResultCost = RecordCost;
            ResultX = RecordX;
            return ResultX;
        }