//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); }
//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 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"); } }
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); }
//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"); } }