public ProblemNode(LinearProgram problem, bool solved, double[] xValues, double zValue) { this.Problem = problem; this.Solved = solved; this.XValues = xValues; this.ZValue = zValue; }
public static bool CheckIfIPIsSolved(LinearProgram LinearProgram) { double[,] problemMatrix = LinearProgram.LinearProgramMatrix; for (int i = 1; i < LinearProgram.ColumnCount - 1; i++) { double tempValue = Math.Round(problemMatrix[0, i], 5); if (tempValue < 0 && LinearProgram.Type == LPType.Max) { return(false); } if (tempValue > 0 && (LinearProgram.Type == LPType.Min || LinearProgram.IsTwoPhase)) { return(false); } } for (int j = 0; j < LinearProgram.RowCount; j++) { double tempValue = Math.Round(problemMatrix[j, LinearProgram.ColumnCount - 1], 5); if (tempValue < 0) { return(false); } } return(true); }
public static double[] findXValues(LinearProgram lp) { double[] xValues = new double[lp.CountX]; for (int c = 1; c < lp.CountX + 1; c++) { double x = 0; bool basic = true; int count1 = 0; for (int r = 1; r < lp.RowCount; r++) { double currentValue = lp.LinearProgramMatrix[r, c]; if (currentValue != 1 && currentValue != 0) { basic = false; } if (currentValue == 1) { x = Math.Round(lp.LinearProgramMatrix[r, lp.ColumnCount - 1], 5); count1++; } } if (basic && count1 == 1) { xValues[c - 1] = x; } } return(xValues); }
public static bool CheckIfIPIsSolved(LinearProgram LinearProgram, bool Integer) { if (!CheckIfIPIsSolved(LinearProgram)) { return(false); } if (!Integer) { return(true); } double[] xValues = findXValues(LinearProgram); //TODO: OPTIMIZE THIS //for (int i = 0; i < xValues.Length; i++) // xValues[i] = Math.Round(LinearProgram.LinearProgramMatrix[i + 1, LinearProgram.ColumnCount - 1], 5); for (int i = 0; i < xValues.Length; i++) { if (xValues[i] % 1 != 0) { return(false); } } return(true); }
public TwoPhase(LinearProgram linearProgram) : base(linearProgram) { LinearProgram = linearProgram; FormatTwoPhase(); }
//TODO move this to another place, as ratio test has been taken out and can be used for simplex override public LinearProgram Solve() { int tableauNumber = 0; bool done = false; bool answerFound = true; Console.WriteLine("\nPhase 1 - Table 1"); LinearProgram.DisplayCurrentTable(); //Loops till final table do { tableauNumber++; int pivotCol = 0; int pivotRow = 0; if (RatioTest(out pivotRow, out pivotCol)) { done = true; break; } CalculateNewCellValues(pivotRow, pivotCol); //Displays the table Console.WriteLine("\nTable " + tableauNumber); LinearProgram.DisplayCurrentTable(); done = true; answerFound = true; if (CheckIfContinue()) { done = false; answerFound = false; } } while (!done); if (answerFound) { PrimalSimplex simplex = new PrimalSimplex(LinearProgram); LinearProgram = simplex.Solve(); } //Checks if there is an answer //TODO Handle the case when there is no solution found, as currently it will display no solution but still return the lp //if (answerFound == true) //{ //} //else //{ // Console.WriteLine("No Solution"); //} return(LinearProgram); }
public static bool IsSpecialCase(LinearProgram LinearProgram) { if (IsInfeasable(LinearProgram)) { return(true); } if (IsUnbounded(LinearProgram)) { return(true); } return(false); }
public static void GetShadowPrices(double[,] lpFormattedMatrix, LinearProgram lp) { double[,] matrix = lpFormattedMatrix; //for (int i = 1; i < matrix.GetLength(0); i++) //{ for (int j = lp.CountX + 1; j < matrix.GetLength(1) - 1; j++) { double sprice = matrix[0, j]; Console.Write(string.Format("{0}\n ", sprice)); } Console.Write(Environment.NewLine + Environment.NewLine); //} }
public static void GetRangesForRHS(double[,] lpformattedMatrix, LinearProgram lp) { double[,] matrix = lpformattedMatrix; for (int i = 1; i < matrix.GetLength(0); i++) { double rhs = matrix[i, matrix.GetLength(1) - 1]; for (int j = lp.CountX + 1; j < matrix.GetLength(1) - 1; j++) { double bInverse = matrix[i, j]; double a = (matrix[i, j] + matrix[i, j] + rhs); Console.Write(string.Format("{0} ", bInverse)); } Console.Write(string.Format("{0} ", rhs)); Console.Write(Environment.NewLine + Environment.NewLine); } }
private static bool IsInfeasable(LinearProgram LinearProgram) { //Check infeasable double minValue = double.MaxValue; int minLocation = 0; for (int j = 1; j < LinearProgram.RowCount; j++) { if (LinearProgram.LinearProgramMatrix[j, LinearProgram.ColumnCount - 1] < minValue) { minValue = Math.Round(LinearProgram.LinearProgramMatrix[j, LinearProgram.ColumnCount - 1], 5); minLocation = j; } } if (minValue >= 0) { return(false); } bool valid = false; for (int i = 1; i < LinearProgram.ColumnCount - 1; i++) { if (Math.Round(LinearProgram.LinearProgramMatrix[minLocation, i], 5) < 0) { valid = true; break; } } if (!valid) { Console.WriteLine("===== Lp is infeasable ====="); return(true); } return(false); }
private static bool IsUnbounded(LinearProgram LinearProgram) { double[,] problemMatrix = LinearProgram.LinearProgramMatrix; double minValue = problemMatrix[0, 0]; int minLocation = 0; for (int i = 0; i < LinearProgram.ColumnCount - 2; i++) { if (problemMatrix[0, i] < minValue) { minValue = problemMatrix[0, i]; minLocation = i; } } if (minValue > 0) { return(false); } int rhs = LinearProgram.ColumnCount - 1; bool valid = false; for (int i = 0; i < LinearProgram.RowCount; i++) { double ratio = problemMatrix[i, rhs] / problemMatrix[i, minLocation]; if (ratio > 0) { valid = true; break; } } if (!valid) { Console.WriteLine("Lp is unbounded"); return(true); } return(false); }
public LpFormatter(List <String> unformattedLP, Algorithm algorithm) { this.unformattedLP = unformattedLP; //linearProgram = new LinearProgram(0, 0, 0, 0, new double[0, 0], new double[0, 0], new double[0, 0], new List<int>(), new List<int>(), new List<string>(), new double[0, 0]); linearProgram = new LinearProgram { CountA = 0, CountS = 0, CountE = 0, ListOfA = new List <int>(), ColOfA = new List <int>(), ColY = new List <int>(), ColINTRestricted = new List <int>(), CanonicalForm = new List <string>() }; switch (algorithm) { case Algorithm.Primal: FormatLPTwoPhase(); break; case Algorithm.TwoPhase: FormatLPTwoPhase(); break; case Algorithm.Dual: FormatLPDual(); break; case Algorithm.BranchAndBound: FormatLPDual(); break; case Algorithm.CuttingPlane: FormatLPDual(); break; default: break; } }
//Only works when one new slack variable is added public static double[,] AddRow(double[] row, LinearProgram linearProgram) { double[,] newArray = new double[linearProgram.RowCount + 1, linearProgram.ColumnCount + 1]; for (int c = 0; c < linearProgram.ColumnCount - 1; c++) { for (int r = 0; r < linearProgram.RowCount; r++) { newArray[r, c] = linearProgram.LinearProgramMatrix[r, c]; } } for (int i = 0; i < linearProgram.RowCount; i++) { newArray[i, linearProgram.ColumnCount] = linearProgram.LinearProgramMatrix[i, linearProgram.ColumnCount - 1]; } for (int i = 0; i < linearProgram.RowCount; i++) { newArray[i, linearProgram.ColumnCount - 1] = 0; } for (int i = 0; i < row.Length; i++) { newArray[linearProgram.RowCount, i] = row[i]; } return(newArray); }
public LinearProgram Solve() { int targetRow = 0; double fractionDifferance = 1; for (int c = 1; c < linearProgram.CountX + 1; c++) { for (int r = 1; r < linearProgram.RowCount; r++) { double currentCell = linearProgram.LinearProgramMatrix[r, c]; double currentValue = linearProgram.LinearProgramMatrix[r, linearProgram.ColumnCount - 1]; if (currentCell != 0 && currentCell != 1) { break; } if (currentCell == 1) { double thisFraction = Math.Abs(currentValue) - (int)Math.Abs(currentValue); double tempDiff = Math.Abs(0.5 - thisFraction); if (tempDiff < fractionDifferance) { targetRow = r; fractionDifferance = tempDiff; } } } } if (fractionDifferance == 1) { return(linearProgram); } double[] fractionArray = new double[linearProgram.ColumnCount + 1]; for (int i = 0; i < linearProgram.ColumnCount; i++) { fractionArray[i] = linearProgram.LinearProgramMatrix[targetRow, i]; if (fractionArray[i] % 1 == 0) { fractionArray[i] = 0; } else if (fractionArray[i] > 0) { fractionArray[i] -= (int)fractionArray[i]; } else { fractionArray[i] += (((int)fractionArray[i] * -1) + 1); } fractionArray[i] = Math.Round(fractionArray[i], 9); fractionArray[i] *= -1; } fractionArray[fractionArray.Length - 1] = fractionArray[fractionArray.Length - 2]; fractionArray[fractionArray.Length - 2] = 1; linearProgram.LinearProgramMatrix = LpTools.AddRow(fractionArray, linearProgram); linearProgram.CountS++; Dual dual = new Dual(linearProgram); LinearProgram solvedLp = dual.Solve(); while (!LpTools.CheckIfIPIsSolved(solvedLp, true)) { if (LpTools.IsSpecialCase(solvedLp)) { return(solvedLp); } solvedLp = new CuttingPlane(solvedLp).Solve(); } return(solvedLp); }
//Loop this? public static void SensitivityAnalysisMenu() { try { //Sensitivity Analysis Menu Console.WriteLine(@" IP SOLVER ________________________________________________________________________________________ SENSITIVITY ANALYSIS 1. Display the range of a selected Non-Basic Variable. 2. Apply and display a change of a selected Non-Basic Variable. 3. Display the range of a selected Basic Variable. 4. Apply and display a change of a selected Basic Variable. 5. Display the range of a selected constraint right-hand-side value. 6. Apply and display a change of a selected constraint right-hand-side value. 7. Display the range of a selected variable in a Non-Basic Variable column. 8. Apply and display a change of a selected variable in a Non-Basic Variable column. 9. Add a new activity to an optimal solution. 10. Add a new constraint to an optimal solution. 11. Display the shadow prices. 12. Duality "); Console.WriteLine("\nSolved LP\n"); linearProgram.DisplayCurrentTable(); Console.WriteLine(); int userInputSensitivityAnalysis = int.Parse(Console.ReadLine()); SensitivityMenu smenu = (SensitivityMenu)userInputSensitivityAnalysis; switch (smenu) { case SensitivityMenu.display1: //TODO Display the range of a selected Non-Basic Variable. //SensivitityAnalysis.GetNonBasicVariables(linearProgram); Console.WriteLine("Enter the column Number: (Z Column = Column 0)"); int rowNumber = int.Parse(Console.ReadLine()); Console.WriteLine("Ranges for Non Basic Variables"); SensivitityAnalysis.GetNBVRange(SensivitityAnalysis.GetFormatedSensistivityMatrix(linearProgram.LinearProgramMatrix), rowNumber); Console.ReadKey(); break; case SensitivityMenu.display2: //TODO Display the range of a selected Non-Basic Variable. Console.WriteLine("Enter the column Number: (Z Column = Column 0)"); int columnNumber = int.Parse(Console.ReadLine()); Console.WriteLine("Enter the row Number: (Z Column = Column 0)"); rowNumber = int.Parse(Console.ReadLine()); if (linearProgram.GetBasicVariables()[columnNumber] != 0) { Console.WriteLine("Not NBV"); } else { Console.WriteLine("ENter NEw Value:"); int valuenew = int.Parse(Console.ReadLine()); linearProgram.LinearProgramMatrix[rowNumber, columnNumber] = valuenew; linearProgram.DisplayCurrentTable(); if (LpTools.CheckIfIPIsSolved(linearProgram)) { Console.WriteLine("No Change"); Console.ReadKey(); } else { LinearProgram linearProgramNew = (LinearProgram)linearProgram.Clone(); Dual dual2 = new Dual(linearProgramNew); dual2.Solve(); if (LpTools.CheckIfIPIsSolved(linearProgramNew)) { linearProgramNew.DisplaySolution(); } else { Console.WriteLine("No solution"); Console.ReadKey(); } } } break; case SensitivityMenu.display3: //TODO Display the range of a selected Basic Variable. Console.WriteLine("Enter the column Number: (Z Column = Column 0)"); rowNumber = int.Parse(Console.ReadLine()); Console.WriteLine("Ranges for Basic variables"); SensivitityAnalysis.GetRangesForSelectedBV(SensivitityAnalysis.GetFormatedSensistivityMatrix(linearProgram.LinearProgramMatrix), rowNumber); Console.ReadKey(); break; case SensitivityMenu.display4: //TODO Apply and display a change of a selected Basic Variable. break; case SensitivityMenu.display5: //TODO Display the range of a selected constraint right-hand-side value. //Console.WriteLine("Enter the row Number: (Z Row = Row 0)"); //rowNumber = int.Parse(Console.ReadLine()); Console.WriteLine("Ranges for RHS variables"); SensivitityAnalysis.GetRangesForRHS(SensivitityAnalysis.GetFormatedSensistivityMatrix(linearProgram.LinearProgramMatrix), linearProgram); Console.ReadKey(); break; case SensitivityMenu.display6: //TODO Apply and display a change of a selected constraint right-hand-side value. break; case SensitivityMenu.display7: //TODO Display the range of a selected variable in a Non-Basic Variable column. break; case SensitivityMenu.display8: //TODO Apply and display a change of a selected variable in a Non-Basic Variable column. Console.WriteLine("Under Construction"); Console.ReadKey(); break; case SensitivityMenu.display9: //TODO Add a new activity to an optimal solution. break; case SensitivityMenu.display10: //TODO Add a new constraint to an optimal solution. Console.WriteLine("Enter the X Number: (Z Row = Row 0)"); rowNumber = int.Parse(Console.ReadLine()); Console.WriteLine("Type:\n1. <= \n2 . >="); int sign = int.Parse(Console.ReadLine()); Console.WriteLine("RHS:"); int rhs = int.Parse(Console.ReadLine()); linearProgram = LpTools.AddBasicConstraint(linearProgram, rowNumber, sign - 1, rhs); Console.WriteLine("New Table"); linearProgram.DisplayCurrentTable(); LinearProgram newLP = (LinearProgram)linearProgram.Clone(); Dual dual = new Dual(newLP); dual.Solve(); if (LpTools.CheckIfIPIsSolved(newLP)) { linearProgram.DisplaySolution(); } else { Console.WriteLine("No solution"); Console.ReadKey(); } break; case SensitivityMenu.display11: //TODO Display the shadow prices. Console.WriteLine("shadow prices."); SensivitityAnalysis.GetShadowPrices(SensivitityAnalysis.GetFormatedSensistivityMatrix(linearProgram.LinearProgramMatrix), linearProgram); Console.ReadKey(); break; case SensitivityMenu.display12: //TODO Duality Duality duality = new Duality(linearProgram); duality.DeterminDuality(); Console.ReadKey(); break; default: break; } } catch (FormatException) { Console.WriteLine("Invalid Input"); } }
//New Main Menu with file,Alg& sensitivity ananlysis selection public static void Menu() { GetInputAndOutputFiles(); //TODO Move this to different place #region Stuff to Move List <String> unformatedLP = FileHandler.ReadLP(); foreach (var item in unformatedLP) { Console.WriteLine(item); } #endregion bool done = false; do { try { Console.WriteLine(@" IP SOLVER ________________________________________________________ PLEASE SELECT AN ALGORITHM 1.PRIMAL 2.TWO PHASE 3.DUAL 4.BRANCH & BOUND 5.CUTTING PLANE "); int userinput = int.Parse(Console.ReadLine()); Algorithm menu = (Algorithm)userinput; switch (menu) { case Algorithm.Primal: linearProgram = new LpFormatter(unformatedLP, Algorithm.Primal).GetLinearProgram(); linearProgram.DisplayCanonicalForm(); PrimalSimplex simplex = new PrimalSimplex(linearProgram); linearProgram = simplex.Solve(); break; case Algorithm.TwoPhase: linearProgram = new LpFormatter(unformatedLP, Algorithm.TwoPhase).GetLinearProgram(); linearProgram.IsTwoPhase = true; TwoPhase twoPhase = new TwoPhase(linearProgram); linearProgram.DisplayCanonicalForm(); linearProgram = twoPhase.Solve(); break; case Algorithm.Dual: linearProgram = new LpFormatter(unformatedLP, Algorithm.Dual).GetLinearProgram(); linearProgram.DisplayCanonicalForm(); Dual dual = new Dual(linearProgram); linearProgram = dual.Solve(); break; case Algorithm.BranchAndBound: linearProgram = new LpFormatter(unformatedLP, Algorithm.Dual).GetLinearProgram(); linearProgram.DisplayCanonicalForm(); Dual bbDual = new Dual(linearProgram); linearProgram = bbDual.Solve(); BranchAndBound BB = new BranchAndBound(linearProgram); linearProgram = BB.Solve(); break; case Algorithm.CuttingPlane: linearProgram = new LpFormatter(unformatedLP, Algorithm.Dual).GetLinearProgram(); linearProgram.DisplayCanonicalForm(); Dual cutDual = new Dual(linearProgram); linearProgram = cutDual.Solve(); CuttingPlane cutingPlane = new CuttingPlane(linearProgram); linearProgram = cutingPlane.Solve(); break; default: break; } //todo check for input errors, set done to false if there arent any done = true; } catch (FormatException) { done = false; Console.WriteLine("Invalid Input"); } } while (!done); if (LpTools.CheckIfIPIsSolved(linearProgram)) { linearProgram.DisplaySolution(); } else { Console.WriteLine("No Solution!"); Console.ReadKey(); } Console.Clear(); if (LpTools.CheckIfIPIsSolved(linearProgram)) { do { SensitivityAnalysisMenu(); } while (true); } }
//TODO: WILL BREAK IF SOLUTION IS NOT YET SOLVED OR IF YOU ADD CONSTRAINT TO A COLUMN WITH NO X SOLUTION public static LinearProgram AddBasicConstraint (LinearProgram linearProgram, int column, int ConstraintType, int rhs) { if (ConstraintType != GREATER_THAN && ConstraintType != LESS_THAN) { throw new ArgumentException ("The argument passed to AddBasicConstraint for ConstraintType does not match the expected value"); } LinearProgram tempLp = (LinearProgram)linearProgram.Clone(); int constraintRow = linearProgram.RowCount; double[,] newArray = new double[linearProgram.RowCount + 1, linearProgram.ColumnCount + 1]; for (int c = 0; c < linearProgram.ColumnCount - 1; c++) { for (int r = 0; r < linearProgram.RowCount; r++) { newArray[r, c] = linearProgram.LinearProgramMatrix[r, c]; } } for (int i = 0; i < linearProgram.RowCount; i++) { newArray[i, linearProgram.ColumnCount] = linearProgram.LinearProgramMatrix[i, linearProgram.ColumnCount - 1]; } for (int i = 0; i < linearProgram.RowCount; i++) { newArray[i, linearProgram.ColumnCount - 1] = 0; } newArray[constraintRow, column] = 1; newArray[constraintRow, linearProgram.ColumnCount] = rhs; newArray[constraintRow, linearProgram.ColumnCount - 1] = 1; //Constraint has been added, now check vilidity int conflictingRow = 0; for (int i = 0; i < linearProgram.RowCount; i++) { if (newArray[i, column] == 1) { conflictingRow = i; break; } } if (ConstraintType == GREATER_THAN) { tempLp.CountE++; for (int i = 0; i < linearProgram.ColumnCount + 1; i++) { newArray[constraintRow, i] = newArray[constraintRow, i] - newArray[conflictingRow, i]; } newArray[constraintRow, linearProgram.ColumnCount - 1] *= -1; } else { tempLp.CountS++; for (int i = 0; i < linearProgram.ColumnCount + 1; i++) { newArray[constraintRow, i] = newArray[constraintRow, i] - newArray[conflictingRow, i]; } } if (newArray[constraintRow, linearProgram.ColumnCount - 1] < 0) { for (int i = 0; i < linearProgram.ColumnCount + 1; i++) { newArray[constraintRow, i] *= -1; } } tempLp.LinearProgramMatrix = newArray; tempLp.DisplayCurrentTable(); return(tempLp); }
public BranchAndBound(LinearProgram problem) { problems = new List <ProblemNode>(); problems.Add(new ProblemNode(problem, false, null, 0)); type = problem.Type; }
public Dual(LinearProgram linearProgram) : base(linearProgram) { LinearProgram = linearProgram; }
public Duality(LinearProgram optimalSoltution) { OptimalSoltution = optimalSoltution; originalLP = new LpFormatter(FileHandler.ReadLP(), Algorithm.Dual).GetLinearProgram(); }
public Simplex(LinearProgram linearProgram) { LinearProgram = linearProgram; }
override public LinearProgram Solve() { int tableauNumber = 1; bool done = false; bool answerFound = false; int pivotRow = 0; int pivotCol = 0; Console.WriteLine("\nPhase 1 - Table 1"); LinearProgram.DisplayCurrentTable(); //Loops till final table do { tableauNumber++; pivotRow = 0; if (RatioTest(out pivotRow, out pivotCol)) { done = true; break; } CalculateNewCellValues(pivotRow, pivotCol); Console.WriteLine("\nPhase 1 - Table " + tableauNumber); LinearProgram.DisplayCurrentTable(); done = true; answerFound = true; if (CheckIfContinue()) { done = false; answerFound = false; } double wRHS = Math.Round(LinearProgram.LinearProgramMatrix[0, LinearProgram.ColumnCount - 1], 10); //Checks if the W rhs amount is 0 if (wRHS == 0) { done = true; answerFound = true; } } while (!done); //Checks if an answer is found if (answerFound) { //Finds BVs double[] bvs = LinearProgram.GetBasicVariables(); List <int> bvCols = new List <int>(); for (int i = 0; i < bvs.Length; i++) { if (bvs[i] != 0) { bvCols.Add(i); } } bool deleteNegatives = false; //If A is BV, delete Negatives for (int aCol = 0; aCol < LinearProgram.ColOfA.Count; aCol++) { for (int bvCol = 0; bvCol < bvCols.Count; bvCol++) { if (LinearProgram.ColOfA[aCol] + 1 == bvCols[bvCol]) { //Breaks out of outer loop aCol = LinearProgram.ColOfA.Count; deleteNegatives = true; break; } } } //Deletes the A's if (Math.Round(LinearProgram.LinearProgramMatrix[0, LinearProgram.ColumnCount - 1], 10) == 0) { if (deleteNegatives) { for (int i = 0; i < LinearProgram.ColumnCount; i++) { if (LinearProgram.LinearProgramMatrix[0, i] < 0) { for (int j = 0; j < LinearProgram.RowCount; j++) { LinearProgram.LinearProgramMatrix[j, i] = 0; } } } } for (int i = 0; i < simplexLP.GetLength(0); i++) { for (int j = 0; j < simplexLP.GetLength(1); j++) { simplexLP[i, j] = LinearProgram.LinearProgramMatrix[i + 1, j + 1]; } } //Sets the Amounts in the A coulmns to 0 foreach (var item in LinearProgram.ColOfA) { if (!bvCols.Contains(item + 1)) { for (int i = 0; i < simplexLP.GetLength(0); i++) { simplexLP[i, item] = 0; } } } LinearProgram.IsTwoPhase = false; Console.WriteLine("\nPhase 2 - Initial Table"); LinearProgram.LinearProgramMatrix = simplexLP; LinearProgram.DisplayCurrentTable(); PrimalSimplex simplex = new PrimalSimplex(LinearProgram); //Calls the appropriate simplex method LinearProgram = simplex.Solve(); ///TODO handle what happens if theres no solution } else { Console.WriteLine("No Solution"); } } //else //{ // if (pivotRow == 0) // { // Console.WriteLine("This LP is unbounded and has no solution"); // } // Console.WriteLine("No Solution"); //} return(LinearProgram); }
public CuttingPlane(LinearProgram linearProgram) { this.linearProgram = linearProgram; }
public PrimalSimplex(LinearProgram linearProgram) : base(linearProgram) { LinearProgram = linearProgram; }
public void DeterminDuality() { originalLP.DisplayCurrentTable(); LinearProgram duality = (LinearProgram)originalLP.Clone(); if (originalLP.Type == LPType.Max) { duality.Type = LPType.Min; } else { duality.Type = LPType.Max; } duality.LinearProgramMatrix = new double[originalLP.CountX + 1, originalLP.RowCount]; //Fill X Values for (int i = 1; i < originalLP.RowCount; i++) { for (int j = 0; j <= originalLP.CountX; j++) { duality.LinearProgramMatrix[j, i] = originalLP.LinearProgramMatrix[i, j]; } } double[] rhs = new double[originalLP.CountX + 1]; //Fill RHS for (int i = 1; i <= originalLP.CountX; i++) { rhs[i] = originalLP.LinearProgramMatrix[0, i]; } duality.CountA = 0; duality.CountS = 0; duality.CountE = originalLP.CountX; duality.CountX = originalLP.RowCount - 1; double[,] eArray = new double[duality.CountE + 1, duality.CountE]; //Handle URS for (int i = 0; i < eArray.GetLength(1); i++) { eArray[i + 1, i] = 1; } double[,] finalLP = new double[duality.RowCount, duality.ColumnCount + eArray.GetLength(0)]; for (int i = 0; i < finalLP.GetLength(0); i++) { int mainCol = 0; //Saves the LP for (int orgCol = 0; orgCol < duality.ColumnCount; orgCol++) { finalLP[i, orgCol] = duality.LinearProgramMatrix[i, orgCol] * -1; mainCol++; } //Saves the E's for (int eCol = 0; eCol < duality.CountE; eCol++) { finalLP[i, mainCol] = eArray[i, eCol]; mainCol++; } //Saves the RHS finalLP[i, duality.ColumnCount + duality.CountE] = rhs[i]; } for (int i = 1; i < originalLP.RowCount; i++) { finalLP[0, i] = originalLP.LinearProgramMatrix[i, originalLP.ColumnCount - 1] * -1; } duality.LinearProgramMatrix = finalLP; duality.LinearProgramMatrix[0, 0] = 1; Console.WriteLine("Duality Initial Table"); duality.DisplayCurrentTable(); Console.WriteLine(); Dual dual = new Dual(duality); duality = dual.Solve(); Console.WriteLine(); if (optimalSoltution.GetBasicVariables()[0] == duality.GetBasicVariables()[0]) { Console.WriteLine("Strong Duality"); } else { Console.WriteLine("Weak Duality"); } }