/// <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 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> /// Gets result of solving /// </summary> public new LppResult GetResult(SimplexTable table, LppForSimplexMethod problem) { if (!HaveNegativeFreeCoefficients(table)) return GetInitialProblemResult(table, problem); return HaveNegativeRowsWithoutNegativeElements(table) ? new LppResult(null, null) : null; }
/// <summary> /// Changes basis(returns new object) /// </summary> public SimplexTable ChangeBasis(SimplexTable table, SolvingElementIndexes solvingElement) { var tableCopy = new SimplexTable(table); if (solvingElement.RowIndex < 0 || solvingElement.CellIndex < 0) return tableCopy; tableCopy.ChangeBasis(solvingElement.RowIndex, solvingElement.CellIndex); return tableCopy; }
private UiDescription CutoffAddingStep(UiDescription userData) { SetNextStep(NextWeakenedProblemSolvingStep); var sLabel = _gomorySecond.GetFreeBasisVariableLabel(_currentSimplexTable); var cutoff = _gomorySecond.MakeCutoff(_currentSimplexTable, ((StepVariants)userData["creativeVar"].Value).Variants.ElementAt(0), InitialProblem); var prevSimplexTable = _currentSimplexTable; _currentSimplexTable = _gomorySecond.AddCutoff(_currentSimplexTable, sLabel, cutoff); var tableSettings = new SimplexTableViewSettings { RowCount = _currentSimplexTable.RowsCount, Variables = new List<string>(_currentSimplexTable.Variables) }; return new UiDescription { {"SimplexTableView", "prevTable", prevSimplexTable}, {"Label", "lab1", "Відсічення:"}, {"LimitationsArea", "limSystem", userData["limSystem"].Value}, {"Label", "lab2", "Нова симплекс-таблиця:"}, {"SimplexTableView", "table", "", _currentSimplexTable, true, true, tableSettings} }; }
/// <summary> /// Adds cutoff to simplex-table /// </summary> /// <param name="table"></param> /// <param name="basisVarLabel">Si</param> /// <param name="cutoff">Si - Sum(fractionalPart of coefficients) = - fractionalPart of free coefficient</param> public SimplexTable AddCutoff(SimplexTable table, string basisVarLabel, KeyValuePair<Fraction[], Fraction> cutoff) { var tableCopy = new SimplexTable(table); tableCopy.AddCell(basisVarLabel); tableCopy.AddRow(basisVarLabel, cutoff.Key, cutoff.Value); return tableCopy; }
/// <summary> /// Get free variable label( Si ) /// </summary> public string GetFreeBasisVariableLabel(SimplexTable table) { var label = string.Empty; for (var i = 1; i < 1000; i++) { label = "S" + i; if (!table.Variables.Contains(label)) break; } return label; }
/// <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); }
private Fraction GetCoefficientForCutoff(string variable, SimplexTable table, string creativeVar, ICollection<string> wholeConstraints) { var varIndex = table.IndexOf(variable); var creativeRow = table.GetRow(creativeVar); var varCoefFractionalPart = GetFractionalPart(creativeRow.Key[varIndex]); var freeCoefFractionalPart = GetFractionalPart(creativeRow.Value); if (wholeConstraints.Contains(variable)) return (varCoefFractionalPart <= freeCoefFractionalPart) ? varCoefFractionalPart : freeCoefFractionalPart / (1 - freeCoefFractionalPart) * (1 - varCoefFractionalPart); return (creativeRow.Key[varIndex] >= 0) ? creativeRow.Key[varIndex] : freeCoefFractionalPart / (1 - freeCoefFractionalPart) * (-1 * varCoefFractionalPart); }
/// <summary> /// Returns index of solving cell(or -1 if table has no positive rating) /// </summary> /// <param name="table">Table with calculated ratings</param> private int GetSolvingCellIndex(SimplexTable table) { var maxRatingIndex = -1; foreach (var rating in table.Ratings) { if (maxRatingIndex == -1) { if (rating.CompareTo(0) == 1) maxRatingIndex = table.Ratings.IndexOf(rating); continue; } if (rating.CompareTo(table.Ratings[maxRatingIndex]) == 1) maxRatingIndex = table.Ratings.IndexOf(rating); } return maxRatingIndex; }
/// <summary> /// Solves weakened problem(without whole constraints) by simplex-method /// </summary> /// <param name="problem">Initial problem</param> /// <param name="normalizedProblem"></param> /// <param name="lastSimplexTable">Last simplex-table(optimal plan)</param> /// <returns></returns> public LppResult SolveInitialWeekenedProblem(ProblemForGomory problem, out LppForSimplexMethod normalizedProblem, out SimplexTable lastSimplexTable) { normalizedProblem = _simplex.Normalize(problem); lastSimplexTable = _simplex.MakeFirstSimplexTable(normalizedProblem); lastSimplexTable = _simplex.Solve(lastSimplexTable); return _simplex.GetNormalizedProblemResult(lastSimplexTable, normalizedProblem); }
public SimplexTableView(SimplexTable inputTable) { InitializeComponent(); Init(); Value = new SimplexTable(inputTable); }
private bool HavePositiveRatings(SimplexTable table) { foreach (var rating in table.Ratings) if (rating > 0) return true; return false; }
/// <summary> /// Gets acceptable solution of normalixed problem /// </summary> public LppResult GetNormalizedProblemResult(SimplexTable table, LppForSimplexMethod problem) { return problem.GetNormalizedProblemResult(table); }
/// <summary> /// Gets acceptable solution of initial problem /// </summary> public LppResult GetInitialProblemResult(SimplexTable table, LppForSimplexMethod problem) { return problem.GetInitialProblemResult(table); }
/// <summary> /// Returns true if result there /// </summary> public new bool IsEnd(SimplexTable table) { return !HaveNegativeFreeCoefficients(table) || HaveNegativeRowsWithoutNegativeElements(table); }
/// <summary> /// Gets pair of indexes, that indicates solving element /// </summary> /// <param name="table">Table with calculated ratings</param> public new SolvingElementIndexes GetSolvingElement(SimplexTable table) { var rowIndex = GetSolvingRowIndex(table); return new SolvingElementIndexes { CellIndex = GetSolvingCellIndex(table, rowIndex), RowIndex = rowIndex }; }
/// <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; }
private bool HavePositiveCellsWithoutPositiveElements(SimplexTable table) { for (var j = 0; j < table.Variables.Count; j++) { if (table.GetRating(table.Variables.ElementAt(j)) <= 0) continue; var havePositive = false; for (var i = 0; i < table.RowsCount; i++) { if (table.GetMatrixElement(i, j) < 0) continue; havePositive = true; break; } if (!havePositive) return true; } return false; }
/// <summary> /// Gets result of solving /// </summary> public LppResult GetResult(SimplexTable table, LppForSimplexMethod problem) { if (!HavePositiveRatings(table)) return GetInitialProblemResult(table, problem); return HavePositiveCellsWithoutPositiveElements(table) ? new LppResult(null, null) : null; }
private void Bind(SimplexTable inputTable) { ClearAll(); _table = new SimplexTable(inputTable); SetHead(); SetRows(); SetRatings(); }
/// <summary> /// Gets pair of indexes, that indicates solving element /// </summary> /// <param name="table">Table with calculated ratings</param> public SolvingElementIndexes GetSolvingElement(SimplexTable table) { var cellIndex = GetSolvingCellIndex(table); return new SolvingElementIndexes { CellIndex = cellIndex, RowIndex = GetSolvingRowIndex(table, cellIndex) }; }
/// <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> /// Returns true if result there /// </summary> public bool IsEnd(SimplexTable table) { return !HavePositiveRatings(table) || HavePositiveCellsWithoutPositiveElements(table); }
/// <summary> /// Solves weakened problem(without whole constraints) by dual simplex-method /// </summary> public LppResult SolveWeekenedProblemWithCutoff(LppForSimplexMethod problem, SimplexTable firstTable, out SimplexTable lastTable) { lastTable = _dualSimplex.Solve(firstTable); return _dualSimplex.GetNormalizedProblemResult(lastTable, problem); }
private bool HaveNegativeFreeCoefficients(SimplexTable table) { foreach (var coefficient in table.GetBasis().Values) if (coefficient < 0) return true; return false; }
/// <summary> /// Returns new simplex-table with calculated ratings /// </summary> public SimplexTable CalculateRatings(SimplexTable table) { var tableCopy = new SimplexTable(table); tableCopy.CalculateRatings(); return tableCopy; }
private bool HaveNegativeRowsWithoutNegativeElements(SimplexTable table) { foreach (var basisVar in table.GetBasis()) { if (basisVar.Value >= 0) continue; var haveNegative = false; foreach (var tableElement in table.GetRow(basisVar.Key).Key) { if (tableElement >= 0) continue; haveNegative = true; break; } if (!haveNegative) return true; } return false; }
/// <summary> /// Gets initial problem result /// </summary> public LppResult GetInitialProblemResult(SimplexTable lastTable, LppForSimplexMethod normalizedForSimplexProblem) { return _simplex.GetInitialProblemResult(lastTable, normalizedForSimplexProblem); }
/// <summary> /// Solving by simplex-method /// </summary> public SimplexTable Solve(SimplexTable table) { var tableCopy = new SimplexTable(table); if (tableCopy.Ratings == null || tableCopy.Ratings.Count == 0) tableCopy = CalculateRatings(table); while (!IsEnd(tableCopy)) { var solvingElement = GetSolvingElement(tableCopy); tableCopy = NextSimplexTable(tableCopy, solvingElement); } return tableCopy; }