def test_4_certificate_of_optimality(self): """Check for Dual Optimal Solution.""" print "Solving by Dual Simplex." z_starN1, x_star_b1, matrix_B1, matrix_N1, Nu1, Beta1, opt_value1 = pt2.dual_simplex_solver( self.x_starB1, self.matrix_B1, self.matrix_N1, self.z_star_n1, self.b1, self.c1, self.Beta1, self.Nu1, self.objective) self.assertAlmostEqual(self.optimal_solution, -1 * opt_value1, 3) self.assertAlmostEqual(self.x_b_solution.all(), x_star_b1.all(), 3) self.assertAlmostEqual(self.z_n_solution.all(), z_starN1.all(), 3)
def primal_dual_simplex_solver(z_starN, matrix_B, matrix_N, x_star_b, b, c, Beta, Nu, optimal_value): """Primal Problem solver.""" # Step 1: Convert z*N to nonnegative to make it Dual Feasible temp_c = -1 * np.ones((len(c), 1)) z_starN = -1 * temp_c z_starN, x_star_b, matrix_B, matrix_N, Nu, Beta, sol = pt2.dual_simplex_solver( x_star_b, matrix_B, matrix_N, z_starN, b, temp_c, Beta, Nu, optimal_value) A_matrix = -1 * np.dot(linalg.inv(matrix_B), matrix_N) row_matrix_a = [] indices_rows_matrix_a = [] # First Loop to pull x*B and corresponding A matrix row for the decision variables # and multiply them to their coefficients in the objective function. for i in range(len(c)): if i + 1 in Beta: index = np.where(Beta == i + 1) optimal_value += c[i] * x_star_b[index].squeeze() row_matrix_a.append(c[i] * (A_matrix[index, :].squeeze())) indices_rows_matrix_a.append(Nu) indices_rows_matrix_a = np.asarray(indices_rows_matrix_a) array_row_matrix_a = np.asarray(row_matrix_a) summed_array_to_substitute = [] # Second Loop to check if we have multiple rows pulled out from matrix_a. Then check the # coefficients for the same decision variables and then add them. for i in indices_rows_matrix_a[0, :]: temp = 0 item = np.where(indices_rows_matrix_a == i) temp += np.sum(array_row_matrix_a[item].squeeze()) if array_row_matrix_a[item].size != 0: summed_array_to_substitute.append(temp) # Now we got the summed array for the rows we substituted in original objective # So, Third Loop is to check and sum if we have multiple coefficients for the same # decision variables in this new objective function. summed_array_to_substitute = np.asarray(summed_array_to_substitute) for i in range(1, len(Nu) + 1): item = np.where(Nu == i) temp_sum = summed_array_to_substitute[item].squeeze( ) + c[item].squeeze() if temp_sum.size != 0: temp_c[i - 1] = summed_array_to_substitute[item].squeeze( ) + c[item].squeeze() else: temp_c[i - 1] = summed_array_to_substitute[i - 1].squeeze() z_starN = -1 * temp_c if np.min(z_starN) >= 0.0: print "\t[Optimal Solution found]" print "Optimal Solution is: ", optimal_value print "z*N: \n", z_starN else: pt1.primal_simplex_solver(z_starN, matrix_B, matrix_N, x_star_b, b, c, Beta, Nu, optimal_value) return z_starN, x_star_b, matrix_B, matrix_N, Nu, Beta, optimal_value
def test_2_dual_solution(self): """Check for Dual Optimal Solution.""" print "Solving by Dual Simplex." z_starN1, x_star_b1, matrix_B1, matrix_N1, Nu1, Beta1, opt_value1 = pt2.dual_simplex_solver( self.x_starB, self.matrix_B, self.matrix_N, self.z_star_n, self.b, self.c, self.Beta, self.Nu, self.objective) xb = np.dot(linalg.inv(matrix_B1), self.b) self.assertEqual(xb.all(), x_star_b1.all(), msg="x*b != inv(B) * b") self.assertGreaterEqual(z_starN1.all(), 0.00000) self.assertAlmostEqual(self.optimal_solution, opt_value1, 3) self.assertAlmostEqual(self.x_b_solution.all(), x_star_b1.all(), 3) self.assertAlmostEqual(self.z_n_solution.all(), z_starN1.all(), 3) self.assertAlmostEqual(self.b_solution.all(), matrix_B1.all(), 3) self.assertAlmostEqual(self.n_solution.all(), matrix_N1.all(), 3) self.assertEqual(all(self.beta_solution), all(Beta1)) self.assertEqual(all(self.nu_solution), all(Nu1))
def primal_dual_simplex_solver(z_starN, matrix_B, matrix_N, x_star_b, b, c, Beta, Nu, optimal_value): """Primal Problem solver.""" # step 1 z_starN = np.absolute(z_starN) z_starN, x_star_b, matrix_B, matrix_N, Beta, sol = pt2.dual_simplex_solver( x_star_b, matrix_B, matrix_N, z_starN, b, c, Beta, Nu) A_matrix = -1 * np.dot(linalg.inv(matrix_B), matrix_N) # print "A_matrix: ", A_matrix # optimal_value = 0 arr = [] index_arr = [] for i in range(len(c)): if i + 1 in Beta: index = np.where(Beta == i + 1) optimal_value += c[i] * x_star_b[index].squeeze() arr.append(c[i] * (A_matrix[index, :].squeeze())) index_arr.append(Nu) index_arr = np.asarray(index_arr) arr_indx = np.asarray(arr) another_arr = [] for i in index_arr[0, :]: sumo = 0 item = np.where(index_arr == i) sumo += np.sum(arr_indx[item].squeeze()) if arr_indx[item].size != 0: another_arr.append(sumo) another_arr = np.asarray(another_arr) for i in range(1, len(Nu) + 1): item = np.where(Nu == i) sume = another_arr[item].squeeze() + c[item].squeeze() if sume.size != 0: z_starN[i - 1] = another_arr[item].squeeze() + c[item].squeeze() else: z_starN[i - 1] = another_arr[i - 1].squeeze() if np.min(z_starN) >= 0.0: print "Optimal Solution: ", optimal_value, z_starN else: c = 1 * z_starN pt1.primal_simplex_solver(z_starN, matrix_B, matrix_N, x_star_b, b, c, Beta, Nu) return z_starN, x_star_b, matrix_B, matrix_N, Beta, optimal_value
def test_4_complementary_slackness(self): """Check for Complementary Slackness.""" print "Solving by Dual Simplex." z_starN1, x_star_b1, matrix_B1, matrix_N1, Nu1, Beta1, opt_value1 = pt2.dual_simplex_solver(self.x_starB1, self.matrix_B1, self.matrix_N1, self.z_star_n1, self.b1, self.c1, self.Beta1, self.Nu1, self.objective) self.assertEqual(all(self.beta_solution_for_dual), all(Beta1)) self.assertEqual(all(self.nu_solution_for_dual), all(Nu1))
def __init__(self, parent=None): """The start point.""" parser = argparse.ArgumentParser(description='Linear Program Solver.') parser.add_argument('A_csv', help='The csv for A matrix.') parser.add_argument('b_csv', help='The csv for b vector.') parser.add_argument('c_csv', help='The csv for c vector.') args = parser.parse_args() # Fetch the data for A matrix data_a = csv.reader(open(args.A_csv, 'rb')) a = [] for row in data_a: a.append(row) rows_a = len(a) cols_a = len(row) a = np.array([a]).reshape(rows_a, cols_a).astype(np.float) # Fetch the data for b vector data_b = csv.reader(open(args.b_csv, 'rb')) self.b = [] for row in data_b: self.b.append(row) rows_b = len(self.b) cols_b = len(row) self.b = np.array([self.b]).reshape(rows_b, cols_b).astype(np.float) # Fetch the data for c vector data_c = csv.reader(open(args.c_csv, 'rb')) self.c = [] for row in data_c: self.c.append(row) rows_c = len(self.c) cols_c = len(row) self.c = np.array([self.c]).reshape(rows_c, cols_c).astype(np.float) self.Nu = np.arange(1, rows_c + 1) self.Beta = np.arange(len(self.Nu) + 1, rows_b + len(self.Nu) + 1) split_a = np.hsplit(a, [rows_c, rows_b + rows_c]) matrix_N = split_a[0] matrix_B = split_a[1] rows_N, cols_N = np.shape(matrix_N) rows_B, cols_B = np.shape(matrix_B) # Check for matrices consistency if cols_N == rows_c and rows_a == rows_b == rows_B == cols_B == rows_N: print("Everything is consistent!") else: print("[Error]: Data is inconsistent! Check the CSVs.") sys.exit() x_starB = self.b z_star_n = -1 * self.c objective = 0 # For Primal Infeasibility if min(x_starB) < 0.0 and min(z_star_n) >= 0.0: print "[Error]: The problem is Primal Infeasible." print "So, performing Dual Simplex Method..." pt2.dual_simplex_solver(x_starB, matrix_B, matrix_N, z_star_n, self.b, self.c, self.Beta, self.Nu, objective) sys.exit() # For Dual Infeasibility if min(z_star_n) < 0.0 and min(x_starB) >= 0.0: print "[Error]: The problem is Dual Infeasible." print "So, performing Primal Simplex Method..." pt1.primal_simplex_solver(z_star_n, matrix_B, matrix_N, x_starB, self.b, self.c, self.Beta, self.Nu, objective) sys.exit() # For Dual and Primal Infeasibility if min(z_star_n) < 0.0 and min(x_starB) < 0.0: print "The problem is Dual and Primal Infeasible." pt3.primal_dual_simplex_solver(z_star_n, matrix_B, matrix_N, x_starB, self.b, self.c, self.Beta, self.Nu, objective) sys.exit()