public void SimplexTable_Solve_Successful( Decomposition decomposition, ObjectiveFunction objectiveFunction, Fraction expected) { var dut = new SimplexTable(decomposition, objectiveFunction, _logger).Calculate(); Assert.AreEqual(expected, dut); }
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); }
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 }; }
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(); }
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; }
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(); }
public Matrix(Fraction[,] items) { _items = items; }
/// <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) ); }
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"); } }
/// <summary> /// The function replicates current Fraction object /// </summary> public Fraction Duplicate() { Fraction frac=new Fraction(); frac.Numerator=Numerator; frac.Denominator=Denominator; return frac; }
/// <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"); } }
/// <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); } }
/// <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)); }