diff --git a/Program.cs b/Program.cs index cc7f847..80a681e 100644 --- a/Program.cs +++ b/Program.cs @@ -7,6 +7,8 @@ class lpr381 //simplex.simplexAlgo(); twoPhaseSimplex twoPhaseSimplex = new twoPhaseSimplex(); twoPhaseSimplex.twoPhaseSimplexAlgo(); + //chesssolver chesssolver = new chesssolver(); + //chesssolver.chessAlgo(); } } diff --git a/chess.cs b/chess.cs index ebbd4c1..2f25a44 100644 --- a/chess.cs +++ b/chess.cs @@ -3,8 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -namespace Backtracking -{ + class chesssolver { static int N; @@ -51,9 +50,9 @@ namespace Backtracking } return false; } - static void Main(string[] args) + public void chessAlgo() { - Console.WriteLine("state size of chess table exp '4' if you wish to make blocks out do exp 4[1][2]"); + Console.WriteLine("state size of chess table example: 4"); N = Convert.ToInt32(Console.ReadLine()); int[,] board = new int[N, N]; if (!theBoardSolver(board, 0)) @@ -64,4 +63,3 @@ namespace Backtracking Console.ReadLine(); } } -} \ No newline at end of file diff --git a/input.txt b/input.txt index be3008a..8840b15 100644 --- a/input.txt +++ b/input.txt @@ -1,4 +1,8 @@ -max +60 +30 +20 -+8 +6 +1 <= 48 -+4 +2 +1.5 >= 20 -+2 +1.5 +0.5 = 8 \ No newline at end of file +max +1 +1 ++8 +4 <= 160 ++4 +4 <= 100 ++1 +0 <= 17 ++1 +0 >= 5 ++0 +1 >= 2 ++1 -1 >= 0 ++1 -4 <= 0 \ No newline at end of file diff --git a/obj/Debug/net6.0/lpr381.csproj.CoreCompileInputs.cache b/obj/Debug/net6.0/lpr381.csproj.CoreCompileInputs.cache index 5c08ff5..393397b 100644 --- a/obj/Debug/net6.0/lpr381.csproj.CoreCompileInputs.cache +++ b/obj/Debug/net6.0/lpr381.csproj.CoreCompileInputs.cache @@ -1 +1 @@ -2378da97a7cf4743291d214cf9ba5b9a5bd52a98 +42cc27e0497d325b5a06d599f420fe32fe1e67ba diff --git a/obj/Debug/net6.0/lpr381.dll b/obj/Debug/net6.0/lpr381.dll index 08f62bf..c929f15 100644 Binary files a/obj/Debug/net6.0/lpr381.dll and b/obj/Debug/net6.0/lpr381.dll differ diff --git a/obj/Debug/net6.0/lpr381.pdb b/obj/Debug/net6.0/lpr381.pdb index bbd0735..c28b416 100644 Binary files a/obj/Debug/net6.0/lpr381.pdb and b/obj/Debug/net6.0/lpr381.pdb differ diff --git a/obj/Debug/net6.0/ref/lpr381.dll b/obj/Debug/net6.0/ref/lpr381.dll index 90c4238..32e9914 100644 Binary files a/obj/Debug/net6.0/ref/lpr381.dll and b/obj/Debug/net6.0/ref/lpr381.dll differ diff --git a/twoPhaseSimplex.cs b/twoPhaseSimplex.cs index 3f640d4..411935b 100644 --- a/twoPhaseSimplex.cs +++ b/twoPhaseSimplex.cs @@ -41,12 +41,42 @@ class twoPhaseSimplex table = prepareTable(newTable, constraintsList); // print table - printTable(table, varCount); + printTablePhaseOne(table, varCount); + + flipZ(table); + printTablePhaseOne(table, varCount); + bool isOptimal = isOptimalPhaseOne(table); + while (!isOptimal) + { + int pivotCol = findPivotCol(table); + List ratio = ratioTest(table, pivotCol); + int pivotRow = findPivotRow(ratio); + table = pivotTable(table, pivotRow, pivotCol); + printTablePhaseOne(table, varCount); + isOptimal = isOptimalPhaseOne(table); + } + + table = dropCol(table, varCount); + isOptimal = isOptimalPhaseTwo(table); + printTablePhaseTwo(table, varCount); + while (!isOptimal) + { + int pivotCol = findPivotCol(table); + List ratio = ratioTest(table, pivotCol); + int pivotRow = findPivotRow(ratio); + table = pivotTable(table, pivotRow, pivotCol); + printTablePhaseTwo(table, varCount); + isOptimal = isOptimalPhaseTwo(table); + } + + + } - void printTable(List> table, int varCount) + void printTablePhaseOne(List> table, int varCount) { + int count = 1; string[] headers = new string[table[0].Count]; for (int i = 0; i < table[0].Count; i++) { @@ -56,10 +86,48 @@ class twoPhaseSimplex } else if (i < table[0].Count - 1) { - headers[i] = "e" + (i - varCount + 1); - headers[i+1] = "a" + (i - varCount + 1); - headers[i+2] = "s" + (i - varCount + 1); + headers[i] = "e" + (count); + headers[i+1] = "a" + (count); + headers[i+2] = "s" + (count); i = i + 2; + count++; + } + else + { + headers[i] = "rhs"; + } + } + var conTable = new ConsoleTable(headers); + foreach (List row in table) + { + // convert row to object array + object[] rowArray = new object[row.Count]; + for (int i = 0; i < row.Count; i++) + { + rowArray[i] = row[i]; + } + conTable.AddRow(rowArray); + } + conTable.Write(Format.Alternative); + + } + + void printTablePhaseTwo(List> table, int varCount) + { + int count = 1; + string[] headers = new string[table[0].Count]; + for (int i = 0; i < table[0].Count; i++) + { + if (i < varCount) + { + headers[i] = "x" + (i + 1); + } + else if (i < table[0].Count - 1) + { + headers[i] = "e" + (count); + headers[i+1] = "s" + (count); + i = i + 1; + count++; } else { @@ -94,21 +162,32 @@ class twoPhaseSimplex } newTable.Add(newRow); } + List rowsWithW = new List(); List signs = new List(); foreach (Constraints constraint in constraints) { signs.Add(constraint.sign); } + // ammount of values in newTable startring from newTable[1]) + int varCount = 0; + for (int i = 1; i < newTable.Count; i++) + { + varCount = varCount + newTable[i].Count; + } for (int i = 0; i < signs.Count ; i++) { table[0].Add(0); table[0].Add(0); table[0].Add(0); + int temp = (newTable[i+1].Count-1) * signs.Count; + + // add 3 0s to each row for every column in table - for (int j = 0; j < newTable[i+1].Count-1; j++) + for (int j = 0; j < signs.Count ; j++) { if (signs[i] == ">=") { + // make s = 1 if (i == j) { table[i+1].Add(0); @@ -124,11 +203,13 @@ class twoPhaseSimplex } else if (signs[i] == "<=") { + //make e and a = 1 if (i == j) { - table[i+1].Add(1); + table[i+1].Add(-1); table[i+1].Add(1); table[i+1].Add(0); + rowsWithW.Add(i+1); } else { @@ -139,11 +220,13 @@ class twoPhaseSimplex } else if (signs[i] == "=") { + // make a = 1 if (i == j) { table[i+1].Add(0); table[i+1].Add(1); table[i+1].Add(0); + rowsWithW.Add(i+1); } else { @@ -155,14 +238,198 @@ class twoPhaseSimplex } } table[0].Add(0); + // create list of floats called wRow size table[0].Count - 1 + List wRow = new List(); + for (int i = 0; i < table[0].Count; i++) + { + wRow.Add(0); + } + for (int i = 0; i < table[0].Count; i++) + { + // if i is in rowsWithW + if (rowsWithW.Contains(i)) + { + for (int j = 0; j < wRow.Count; j++) + { + wRow[j] = wRow[j] + (-table[i][j]); + } + } + } + //add wRow to the start of table + table.Insert(1, wRow); + // remove intex newTable.Count-1 from table and place it in the back of table - for (int i = 1; i < table.Count; i++) + for (int i = 2; i < table.Count; i++) { table[i].RemoveAt(newTable.Count-1); - table[i].Add(newTable[i][newTable.Count-1]); + table[i].Add(newTable[i-1][newTable[i-1].Count-1]); } + // remove the value of newTable.Count-1 from table[1] and place it in the back of table[1] + float lastValue = table[1][newTable.Count-1]; + table[1].RemoveAt(newTable.Count-1); + table[1].Add(lastValue); + + return table; } + static List> flipZ(List> table) + { + for (int i = 0; i < table[0].Count; i++) + { + if (table[0][i] > 0) + { + table[0][i] = -table[0][i]; + } + } + return table; + } + + static int findPivotCol(List> table) + { + float largest = 0; + int largestIndex = 0; + for (int i = 0; i < table[0].Count; i++) + { + if (table[0][i] < largest) + { + largest = table[0][i]; + largestIndex = i; + } + } + return largestIndex; + } + + static List ratioTest(List> table, int testCol) + { + List ratios = new List(); + for (int i = 1; i < table.Count; i++) + { + if (table[i][testCol] != 0) + { + ratios.Add(table[i][table[i].Count - 1] / table[i][testCol]); + } + else + { + ratios.Add(float.MaxValue); + } + } + return ratios; + } + static int findPivotRow(List ratios) + { + float smallest = float.MaxValue; + int smallestIndex = 0; + for (int i = 0; i < ratios.Count; i++) + { + if (ratios[i] < smallest && ratios[i] > 0.0) + { + smallest = ratios[i]; + smallestIndex = i; + } + } + return smallestIndex; + } + + static List> pivotTable(List> table, int pivotRow, int pivotCol) + { + //clone table in to newTable + List> newTable = new List>(); + foreach (List row in table) + { + List newRow = new List(); + for (int i = 0; i < row.Count; i++) + { + newRow.Add(row[i]); + } + newTable.Add(newRow); + } + var pivotPoint = newTable[pivotRow + 1][pivotCol]; + // divide pivot row by pivot point + for (int i = 0; i < newTable[pivotRow + 1].Count; i++) + { + newTable[pivotRow + 1][i] = newTable[pivotRow + 1][i] / pivotPoint; + } + // current possition-(pivot_row*new_table pivot_point) + for (int i = 0; i < newTable.Count; i++) + { + if (i != pivotRow + 1) + { + var currentPossition = newTable[i][pivotCol]; + for (int j = 0; j < newTable[i].Count; j++) + { + newTable[i][j] = newTable[i][j] - (currentPossition * newTable[pivotRow + 1][j]); + } + } + } + return newTable; + } + + //check if the table is optimal first phase + // table is optimal if all values in table[1] are positive + + + static bool isOptimalPhaseOne(List> table) + { + int wIndex = 0; + for (int i = 0; i < table[1].Count; i++) + { + if (table[1][i] < 0) + { + wIndex = i; + } + } + if (wIndex == 0) + { + return true; + } + else + { + return false; + } + } + + + static bool isOptimalPhaseTwo(List> table) + { + int wIndex = 0; + for (int i = 0; i < table[0].Count; i++) + { + if (table[0][i] < 0) + { + wIndex = i; + } + } + if (wIndex == 0) + { + return true; + } + else + { + return false; + } + } + + + //drop all a coloumn from the table and drop w row from the table + static List> dropCol(List> table, int varCount) + { + table.RemoveAt(1); + + + // for each row in table drop the varCount-1th element + for (int i = 0; i < table.Count; i++) + { + for (int j = varCount + 1; j < table[i].Count - 1; j+=3) + { + table[i].RemoveAt(j); + j = j - 1; + } + } + return table; + + } + + } \ No newline at end of file