Пример #1
0
        public void SimplexTable_Solve_Successful(
            Decomposition decomposition, ObjectiveFunction objectiveFunction, Fraction expected)
        {
            var dut = new SimplexTable(decomposition, objectiveFunction, _logger).Calculate();

            Assert.AreEqual(expected, dut);
        }
Пример #2
0
 public void SimplexMethod_Solve_Successful(
     ObjectiveFunction objectiveFunction, Matrix matrix, int[] cornerPoint, Fraction expected)
 {
     var simplexMethodSolver = new SimplexMethodSolver(objectiveFunction, matrix, cornerPoint, _logger);
     var actual = simplexMethodSolver.Solve();
     Assert.AreEqual(expected, actual);
 }
Пример #3
0
        public Decomposition DecompositionByCornerPoint(IReadOnlyList<int> cornerPoint)
        {
            SwitchColumns(cornerPoint);
            Diagonalize();
            SwitchBackColumns(cornerPoint);

            var basicVariables = new List<int>();
            var freeVariables = new List<int>();
            for (var i = 0; i < cornerPoint.Count; i++)
                if (cornerPoint[i] != 0)
                    basicVariables.Add(i);
                else
                    freeVariables.Add(i);

            var coefficients = new Fraction[basicVariables.Count, freeVariables.Count + 1];
            for (var j = 0; j < freeVariables.Count; j++)
                for (var i = 0; i < basicVariables.Count; i++)
                    coefficients[i, j] = _items[i, freeVariables[j]];
            for (var i = 0; i < basicVariables.Count; i++)
                coefficients[i, coefficients.GetLength(1) - 1] = _items[i, _items.GetLength(1) - 1];

            return new Decomposition
            {
                BasicVariables = basicVariables.ToArray(),
                FreeVariables = freeVariables.ToArray(),
                Coefficients = coefficients
            };
        }
Пример #4
0
        public Fraction SolveWithArtificialBasic()
        {
            // Получаем начальную декомпозицию для искусственного базиса
            var dec = _augmentedConstraintList.DecompositionForArtificialBasic();

            // Вычисляем целевую функцию по декомпозиции для искусственного базиса
            var coeffs = new Fraction[dec.FreeVariables.Length + 1];
            for (var i = 0; i < coeffs.Length; i++)
            {
                Fraction sum = 0;
                for (var j = 0; j < dec.BasicVariables.Length; j++)
                    sum += dec.Coefficients[j, i];
                coeffs[i] = -sum;
            }
            coeffs[coeffs.Length - 1] *= -1; // ! Потом будет поменян знак, т.к. в симлекс таблице мы записываем обратное значение
            var objFunc = new ObjectiveFunction(coeffs);

            // Приводим составленую симплекс таблицу к нужному виду
            var artBasic = new SimplexTable(dec, objFunc, _loggerForArtBasic, _userChoiceForArtBasic, _isDecimalFractions)
                .ToArtificialBasic();

            _objectiveFunction.Substitution(artBasic);
            return new SimplexTable(artBasic, _objectiveFunction, _logger, _userChoice, _isDecimalFractions)
                .Calculate();
        }
Пример #5
0
        public void RemoveColumn(int column)
        {
            // Удаление свободной переменной
            var fv = FreeVariables.ToList();
            fv.RemoveAt(column);
            FreeVariables = fv.ToArray();

            // Удаление коэффициентов при свободной переменной
            var coefs = new Fraction[Coefficients.GetLength(0), Coefficients.GetLength(1) - 1];
            for (var i = 0; i < Coefficients.GetLength(0); i++)
            {
                var k = 0;
                for (var j = 0; j < Coefficients.GetLength(1); j++)
                {
                    if (j == column)
                        continue;
                    coefs[i, k++] = Coefficients[i, j];
                }
            }
            Coefficients = coefs;
        }
Пример #6
0
        private void solveBtn_Click(object sender, EventArgs e)
        {
            _label.Text = string.Empty;
            _labelArtBasic.Text = string.Empty;

            // Получение коэффициентов целевой функции
            var objFunc = new List<Fraction>();
            for (var i = 0; i < taskGridView.ColumnCount; i++)
                objFunc.Add(new Fraction(taskGridView.Rows[0].Cells[i].Value.ToString()));
            if (_isMaximize)
                objFunc = objFunc.Select(x => -1*x).ToList();

            // Получение коэффициентов матрицы ограничений
            var matrix = new Fraction[constraintsGridView.RowCount, constraintsGridView.ColumnCount];
            for (var i = 0; i < constraintsGridView.RowCount; i++)
                for (var j = 0; j < constraintsGridView.ColumnCount; j++)
                    matrix[i, j] = new Fraction(constraintsGridView.Rows[i].Cells[j].Value.ToString());

            // Получение опорных элементов заданных пользователем для симлекс метода
            var userChoice = new UserChoice();
            for (var i = 0; i < bearingElemsTextBox.Lines.Length; i++)
            {
                var coords = bearingElemsTextBox.Lines[i].Split(' ', ',', ';');
                userChoice.Choices.Add(i, coords.Select(s => Convert.ToInt32(s)).ToArray());
            }

            // Получение опорных элементов заданных пользователем для искусственного базиса
            var userChoiceForArtBasic = new UserChoice();
            for (var i = 0; i < bearingElemsArtBasicTextBox.Lines.Length; i++)
            {
                var coords = bearingElemsArtBasicTextBox.Lines[i].Split(' ', ',', ';');
                userChoiceForArtBasic.Choices.Add(i, coords.Select(s => Convert.ToInt32(s)).ToArray());
            }

            // Получение коэффициентов угловой точки
            var cornerPoint = new List<int>();
            for (var i = 0; i < cornerPointGridView.ColumnCount; i++)
            {
                if (cornerPointGridView.Rows[0].Cells[i].Value != null)
                    cornerPoint.Add((int) cornerPointGridView.Rows[0].Cells[i].Value);
            }

            // Решение задачи
            var solver = new SimplexMethodSolver(
                new ObjectiveFunction(objFunc),
                new Matrix(matrix),
                cornerPoint,
                new LabelLoger(_label),
                new LabelLoger(_labelArtBasic),
                userChoice,
                userChoiceForArtBasic,
                _isDecimalFractions);

            if (artBasicCheckBox.Checked)
                solver.SolveWithArtificialBasic();
            else
                solver.Solve();
        }
Пример #7
0
 public Matrix(Fraction[,] items)
 {
     _items = items;
 }
Пример #8
0
 /// <summary>
 /// internal function for negation
 /// </summary>
 private static Fraction Negate(Fraction frac1)
 {
     long iNumerator=-frac1.Numerator;
     long iDenominator=frac1.Denominator;
     return ( new Fraction(iNumerator, iDenominator) );
 }
Пример #9
0
 private static Fraction Multiply(Fraction frac1, Fraction frac2)
 {
     try
     {
         checked
         {
             long iNumerator=frac1.Numerator*frac2.Numerator;
             long iDenominator=frac1.Denominator*frac2.Denominator;
             return ( new Fraction(iNumerator, iDenominator) );
         }
     }
     catch(OverflowException)
     {
         throw new FractionException("Overflow occurred while performing arithemetic operation");
     }
     catch(Exception)
     {
         throw new FractionException("An error occurred while performing arithemetic operation");
     }
 }
Пример #10
0
 /// <summary>
 /// The function replicates current Fraction object
 /// </summary>
 public Fraction Duplicate()
 {
     Fraction frac=new Fraction();
     frac.Numerator=Numerator;
     frac.Denominator=Denominator;
     return frac;
 }
Пример #11
0
 /// <summary>
 /// The function takes a floating point number as an argument 
 /// and returns its corresponding reduced fraction
 /// </summary>
 public static Fraction ToFraction(double dValue)
 {
     try
     {
         checked
         {
             Fraction frac;
             if (dValue%1==0)	// if whole number
             {
                 frac=new Fraction( (long) dValue );
             }
             else
             {
                 double dTemp=dValue;
                 long iMultiple=1;
                 string strTemp=dValue.ToString();
                 while ( strTemp.IndexOf("E")>0 )	// if in the form like 12E-9
                 {
                     dTemp*=10;
                     iMultiple*=10;
                     strTemp=dTemp.ToString();
                 }
                 int i=0;
                 while ( strTemp[i]!='.' )
                     i++;
                 int iDigitsAfterDecimal=strTemp.Length-i-1;
                 while ( iDigitsAfterDecimal>0  )
                 {
                     dTemp*=10;
                     iMultiple*=10;
                     iDigitsAfterDecimal--;
                 }
                 frac=new Fraction( (int)Math.Round(dTemp) , iMultiple );
             }
             return frac;
         }
     }
     catch(OverflowException)
     {
         throw new FractionException("Conversion not possible due to overflow");
     }
     catch(Exception)
     {
         throw new FractionException("Conversion not possible");
     }
 }
Пример #12
0
        /// <summary>
        /// The function reduces(simplifies) a Fraction object by dividing both its numerator 
        /// and denominator by their GCD
        /// </summary>
        public static void ReduceFraction(Fraction frac)
        {
            try
            {
                if (frac.Numerator==0)
                {
                    frac.Denominator=1;
                    return;
                }

                long iGCD=GCD(frac.Numerator, frac.Denominator);
                frac.Numerator/=iGCD;
                frac.Denominator/=iGCD;

                if ( frac.Denominator<0 )	// if -ve sign in denominator
                {
                    //pass -ve sign to numerator
                    frac.Numerator*=-1;
                    frac.Denominator*=-1;
                }
            } // end try
            catch(Exception exp)
            {
                throw new FractionException("Cannot reduce Fraction: " + exp.Message);
            }
        }
Пример #13
0
        /// <summary>
        /// The function returns the inverse of a Fraction object
        /// </summary>
        public static Fraction Inverse(Fraction frac1)
        {
            if (frac1.Numerator==0)
                throw new FractionException("Operation not possible (Denominator cannot be assigned a ZERO Value)");

            long iNumerator=frac1.Denominator;
            long iDenominator=frac1.Numerator;
            return ( new Fraction(iNumerator, iDenominator));
        }