/// <summary> /// Gets variable, which indicates creative row /// </summary> public string GetCreativeVariable(SimplexTable table, ProblemForGomory problem) { var maxVariables = new List<string>(); var maxFractionalPart = new Fraction(); foreach (var basisVariable in table.GetBasis()) { if (!problem.WholeConstraints.Contains(basisVariable.Key)) continue; var fractionalPart = GetFractionalPart(basisVariable.Value); if (fractionalPart > maxFractionalPart) { maxVariables.Clear(); maxFractionalPart = fractionalPart; } if (fractionalPart == maxFractionalPart) maxVariables.Add(basisVariable.Key); } if (maxVariables.Count == 1) return maxVariables[0]; maxFractionalPart = new Fraction(); var maxVariable = string.Empty; foreach (var variable in maxVariables) { var sumOfFractionalParts = new Fraction(); foreach (var rowVariable in table.GetRow(variable).Key) sumOfFractionalParts += GetFractionalPart(rowVariable); var ratio = sumOfFractionalParts != 0 ? GetFractionalPart(table.GetRow(variable).Value) / sumOfFractionalParts : new Fraction(); if (ratio <= maxFractionalPart) continue; maxFractionalPart = ratio; maxVariable = variable; } return maxVariable; }
/// <summary> /// Represents maxCoefficient with value from input string /// </summary> /// <param name="value">Input string in format: "mC*M + fC", mC - mCoefficient(Fraction: n/d), /// fC - free coefficient(Fraction: n/d), /// M - label(char)</param> /// <exception cref="NullReferenceException"></exception> /// <exception cref="FormatException"></exception> public MaxCoefficient(string value) { var index = value.IndexOf('M'); if (index == -1) { _mCoefficient = new Fraction(); _freeCoefficient = new Fraction(value); return; } var mCoefficientStr = value.Substring(0, index); var freeCoefficientStr = value.Substring(index + 1); if (mCoefficientStr == string.Empty) mCoefficientStr = "1/1"; else if (mCoefficientStr == "-") mCoefficientStr = "-1/1"; if (freeCoefficientStr == string.Empty) freeCoefficientStr = "0/0"; if (mCoefficientStr.IndexOf('/') == -1) mCoefficientStr = mCoefficientStr + "/1"; if (freeCoefficientStr.IndexOf('/') == -1) freeCoefficientStr = freeCoefficientStr + "/1"; _mCoefficient = new Fraction(mCoefficientStr); _freeCoefficient = new Fraction(freeCoefficientStr); }
/// <summary> /// Represents copy of symplex-table /// </summary> public SimplexTable(SimplexTable table) { _allVariables = new Dictionary<int, string>(table._allVariables); // _basisVariables = new Dictionary<int, int>(table._basisVariables); // _rows = new Dictionary<int, Fraction[]>(); foreach (var row in table._rows) { var tmp = new Fraction[row.Value.Count()]; for (var i = 0; i < row.Value.Count(); i++) tmp[i] = new Fraction(row.Value[i]); _rows.Add(row.Key, tmp); } // _freeCoefficients = new Dictionary<int, Fraction>(); foreach (var fCoef in table._freeCoefficients) _freeCoefficients.Add(fCoef.Key, new Fraction(fCoef.Value)); // _targetFunctionCoefficients = new Dictionary<int, MaxCoefficient>(); foreach (var tfCoef in table._targetFunctionCoefficients) _targetFunctionCoefficients.Add(tfCoef.Key, new MaxCoefficient(tfCoef.Value)); // if (table._ratings == null) return; _ratings = new Dictionary<int, MaxCoefficient>(); foreach (var rating in table._ratings) _ratings.Add(rating.Key, new MaxCoefficient(rating.Value)); // FunctionValue = ReferenceEquals(table.FunctionValue, null) ? null : new MaxCoefficient(table.FunctionValue); }
//================================================= /// <summary> /// Represents math Constraint(equality or inequality) /// </summary> public Constraint(ICollection<Variable> leftSide, string sign, Fraction rightSide) { if (leftSide.Count == 0) throw new FormatException("Formula shouldn't be empty"); if (sign != ">" && sign != ">=" && sign != "<" && sign != "<=" && sign != "=") throw new FormatException("Invalid format of comparison sign"); _leftSide = new List<Variable>(leftSide); Sign = sign; _rightSide = new Fraction(rightSide); }
/// <summary> /// Makes cutoff /// </summary> public new KeyValuePair<Fraction[], Fraction> MakeCutoff(SimplexTable table, string creativeVar, ProblemForGomory problem) { var j = 0; var creativeRow = table.GetRow(creativeVar); var row = new Fraction[creativeRow.Key.Length + 1]; foreach (var variable in table.Variables) row[j++] = GetCoefficientForCutoff(variable, table, creativeVar, problem.WholeConstraints) * -1; row[j] = new Fraction(1, 1); return new KeyValuePair<Fraction[], Fraction>(row, GetFractionalPart(creativeRow.Value) * -1); }
public LppResult GetResult() { if (tfUnlimitedRadio.Checked) return new LppResult(null, null); if (setIncompatibleRadio.Checked) return new LppResult(new Dictionary<string, Fraction>(), null); var coordinates = new Dictionary<string, Fraction>(); var value = new Fraction(tfValueTextBox.Text); for (var i = 0; i < coordinatesDataGrid.Columns.Count; i++) { coordinates.Add(coordinatesDataGrid.Columns[i].HeaderText, new Fraction(coordinatesDataGrid.Rows[0].Cells[i].Value.ToString())); } return new LppResult(coordinates, value); }
//======================================================================= /// <summary> /// Represents result of solving the linear programming problem\n /// (If both input parameters == null - target function unlimited bottom\n /// (If point != null and functionValue == null - set of admissible solutions of incompatible) /// </summary> public LppResult(IDictionary<string, Fraction> point, Fraction functionValue) { if (ReferenceEquals(point, null)) { Value = null; Coordinates = null; return; } Coordinates = new Dictionary<string, Fraction>(point); if (ReferenceEquals(functionValue, null)) { Value = null; return; } Value = new Fraction(functionValue); }
/// <summary> /// Method for value comparison of current and input fractions /// </summary> /// <param name="fraction">Fraction for comparison</param> /// <returns>Return true if values of input and current fractions are equal</returns> /// <exception cref="NullReferenceException"></exception> public bool Equals(Fraction fraction) { if (ReferenceEquals(null, fraction)) return false; if (ReferenceEquals(this, fraction)) return true; return fraction.Numerator == Numerator && fraction.Denominator == Denominator; }
/// <summary> /// Represents copy of variable /// </summary> /// <exception cref="NullReferenceException"></exception> public Variable(Variable variable) { _coefficient = new Fraction(variable._coefficient); SetLabel(variable.Label); Power = variable.Power; }
/// <summary> /// Makes cutoff /// </summary> public KeyValuePair<Fraction[], Fraction> MakeCutoff(SimplexTable table, string creativeVar, ProblemForGomory problem) { var j = 0; var creativeRow = table.GetRow(creativeVar); var row = new Fraction[creativeRow.Key.Length + 1]; foreach (var coefficient in creativeRow.Key) row[j++] = GetFractionalPart(coefficient) * -1; row[j] = new Fraction(1, 1); return new KeyValuePair<Fraction[], Fraction>(row, GetFractionalPart(creativeRow.Value) * -1); }
/// <summary> /// Calculates fractional part of fraction /// </summary> protected static Fraction GetFractionalPart(Fraction fraction) { if (fraction == 0) return new Fraction(); var wholePart = fraction.Numerator < 0 ? (fraction.Numerator - fraction.Denominator) / fraction.Denominator : fraction.Numerator / fraction.Denominator; return fraction - wholePart; }
/// <summary> /// Sabtract fraction from current fraction /// </summary> public void Subtract(Fraction fraction) { if (Numerator == 0) { Numerator = fraction.Numerator * -1; Denominator = fraction.Denominator; return; } if (fraction.Numerator == 0) return; Numerator = Numerator * fraction.Denominator - fraction.Numerator * Denominator; Denominator = Denominator * fraction.Denominator; Normalize(); }
private Constraint CutoffConstraint(KeyValuePair<Fraction[], Fraction> cutoff, string cutoffVariable) { var leftSide = new List<Variable>(); var rightSide = new Fraction(cutoff.Value); leftSide.Add(new Variable(new Fraction("1/1"), cutoffVariable)); foreach (var variable in _currentSimplexTable.Variables) { var index = _currentSimplexTable.IndexOf(variable); leftSide.Add(new Variable(cutoff.Key[index], variable)); } return new Constraint(leftSide, "=", rightSide); }
/// <summary> /// Represents variable: this.coefficient = coefficient, this.label = label, power = 1 /// </summary> /// <param name="coefficient"></param> /// <param name="label">Should be in format: letter+index(x23)</param> /// <exception cref="NullReferenceException"></exception> /// <exception cref="FormatException"></exception> public Variable(string coefficient, string label) { _coefficient = new Fraction(coefficient); SetLabel(label); Power = 1; }
/// <summary> /// Represents variable: coefficient = 0, label = "x", power = 1 /// </summary> public Variable() { _coefficient = new Fraction(); Label = "x"; Power = 1; }
/// <summary> /// Adds input constraint to current /// </summary> /// <param name="constraint">Constraint that must be equal</param> /// <exception cref="FormatException">If one of the constraints is not equal</exception> public void Add(Constraint constraint) { if (constraint.Sign != "=" || Sign != "=") throw new FormatException("Constraints must be equal constraints"); var current = new EqualityConstraint(LeftSide, RightSide); var input = new EqualityConstraint(constraint.LeftSide, constraint.RightSide); current.Add(input); _leftSide = new List<Variable>(current.LeftSide); _rightSide = current.RightSide; }
/// <summary> /// Multiplys Constraint(left and right sides) by fraction /// </summary> /// <exception cref="NullReferenceException"></exception> public void Multiply(Fraction fraction) { for (var i = 0; i < _leftSide.Count; i++) { _leftSide[i] = new Variable(_leftSide[i]); _leftSide[i].Multiply(fraction); } //foreach (Variable var in this._leftSide) // var.Multiply(fraction); if (fraction < 0) ChangeSign(); _rightSide *= fraction; }
private void RefreshTable() { var vars = new Dictionary<int, string>(); var rows = new Dictionary<int, Fraction[]>(); var freeCoefficients = new Dictionary<int, Fraction>(); int i; for (i = 0; i < Rows.Count - 1; i++) { vars.Add(i, Rows[i].Cells[0].Value.ToString()); var tmp = new Fraction[_table.Variables.Count]; for (var j = 1; j < Rows[i].Cells.Count - 1; j++) tmp[j - 1] = new Fraction(Rows[i].Cells[j].Value.ToString()); rows.Add(i, tmp); freeCoefficients.Add(i, new Fraction(Rows[i].Cells[Rows[i].Cells.Count - 1].Value.ToString())); } _table.CopyRows(vars, rows, freeCoefficients); var ratings = new Dictionary<int, MaxCoefficient>(); int k; for (k = 1; k < Rows[i].Cells.Count - 1; k++) { if (Rows[i].Cells[k].Value == null) { ratings = null; break; } ratings[k - 1] = new MaxCoefficient(Rows[i].Cells[k].Value.ToString()); } _table.CopyRatings(ratings); _table.FunctionValue = Rows[i].Cells[k].Value == null || Rows[i].Cells[k].Value.ToString() == "" ? null : new MaxCoefficient(Rows[i].Cells[k].Value.ToString()); }
/// <summary> /// Returns index of solving row(or -1 if solving row has no positive elements or solvingCellIndex == -1) /// </summary> private int GetSolvingRowIndex(SimplexTable table, int solvingCellIndex) { if (solvingCellIndex < 0) return -1; var minRatioIndex = -1; var minRatio = new Fraction(); for (var i = 0; i < table.RowsCount; i++) { var matrixElement = table.GetMatrixElement(i, solvingCellIndex); if (matrixElement <= 0) continue; var freeCoefficient = table.GetFreeCoefficient(i); var currRatio = freeCoefficient / matrixElement; if (currRatio >= minRatio && minRatioIndex != -1) continue; minRatioIndex = i; minRatio = currRatio; } return minRatioIndex; }
/// <summary> /// Represents fraction with value from input fraction /// </summary> /// <exception cref="NullReferenceException"></exception> public Fraction(Fraction fraction) { Numerator = fraction.Numerator; Denominator = fraction.Denominator; Normalize(); }
/// <summary> /// Adds var to current variable /// </summary> /// <exception cref="NullReferenceException"></exception> public void Add(Variable var) { if (var.Label != Label || var.Power != Power) throw new FormatException("Input variable must be with same labels and powers"); _coefficient += var._coefficient; }
/// <summary> /// Multiplys variable by fraction /// </summary> /// <exception cref="NullReferenceException"></exception> public void Multiply(Fraction fraction) { _coefficient *= fraction; }
/// <summary> /// Calculates variable value /// </summary> /// <param name="varValue"></param> /// <exception cref="NullReferenceException"></exception> public Fraction Calculate(Fraction varValue) { var result = new Fraction(varValue); for (var i = 1; i < Power; i++) result *= result; result *= _coefficient; return result; }
/// <summary> /// Divide current fraction to fraction /// </summary> public void Divide(Fraction fraction) { if (fraction.Numerator == 0) throw new DivideByZeroException("Divide(Fraction): divide fraction by zero"); Numerator = Numerator * fraction.Denominator; Denominator = Denominator * fraction.Numerator; Normalize(); }
/// <summary> /// Divides variable by fraction /// </summary> /// <exception cref="NullReferenceException"></exception> /// <exception cref="DivideByZeroException"></exception> public void Divide(Fraction fraction) { _coefficient /= fraction; }
/// <summary> /// Multiply fraction to current fraction /// </summary> /// <param name="fraction"></param> public void Multiply(Fraction fraction) { Numerator = Numerator * fraction.Numerator; Denominator = Denominator * fraction.Denominator; Normalize(); }
/// <summary> /// Represents variable: this.coefficient = coefficient, label = "x", power = 1 /// </summary> /// <exception cref="NullReferenceException"></exception> public Variable(string coefficient) { _coefficient = new Fraction(coefficient); Label = "x"; Power = 1; }
/// <summary> /// Represents math Constraint(copy of input Constraint) /// </summary> public Constraint(Constraint constraint) { _leftSide = new List<Variable>(constraint._leftSide); Sign = constraint.Sign; _rightSide = new Fraction(constraint._rightSide); }
/// <summary> /// Represents variable: this.coefficient = coefficient, this.label = label, this.power = power /// </summary> /// <param name="coefficient"></param> /// <param name="label">Should be in format: letter+index(x23)</param> /// <param name="power"></param> /// <exception cref="NullReferenceException"></exception> /// <exception cref="FormatException"></exception> public Variable(Fraction coefficient, string label, int power) { _coefficient = new Fraction(coefficient); SetLabel(label); if (power <= 0) throw new FormatException("Power must be more than zero"); Power = power; }
/// <summary> /// Sets Constraint free constant /// </summary> protected void SetRightSide(Fraction rightSide) { _rightSide = new Fraction(rightSide); }