def run(): #TODO: # fill missing test based on the example_01_solvable.py # to make the test a bit more interesting: # * make the solver use artificial variables! model = Model("example_01_solvable") x1 = model.create_variable("x1") x2 = model.create_variable("x2") model.add_constraint(x1 + x2 <= 10) model.add_constraint(-1 * x1 + x2 >= 2) model.maximize(2 * x1 + x2) try: solution = model.solve() except: raise AssertionError( "This problem has a solution and your algorithm hasn't found it!") logging.info(solution) assert (solution.assignment == [ 4.0, 6.0 ]), "Your algorithm found an incorrect solution!" logging.info("Congratulations! This solution seems to be alright :)")
def run(): model = Model("example_01_solvable") x1 = model.create_variable("x1") x2 = model.create_variable("x2") model.add_constraint(x1 <= 150) model.add_constraint(x2 <= 250) model.add_constraint(2 * x1 + x2 <= 500) model.maximize(8 * x1 + 5 * x2) try: solution = model.solve() except: raise AssertionError( "This problem has a solution and your algorithm hasn't found it!") logging.info(solution) assert (solution.assignment == [ 125.0, 250.0 ]), "Your algorithm found an incorrect solution!" logging.info("Congratulations! This solution seems to be alright :)")
def run(): # fill missing test based on the example_01_solvable.py # to make the test a bit more interesting: # * make the model unfeasible in a way detectable by the 2-phase simplex # model = Model("example_05_unfeasible") x1 = model.create_variable("x1") x2 = model.create_variable("x2") model.maximize(x1) model.add_constraint(x1 + x2 == 150) model.add_constraint(x1 - x2 >= 250) try: solution = model.solve() except PositiveArtificialVariablesError: logging.info( "Congratulations! You found an unfeasible solution detectable with artificial variables :)" ) else: raise AssertionError( "This problem has no solution but your algorithm hasn't figured it out!" )
def run(): model = Model("example_05_unfeasible") x1 = model.create_variable("x1") x2 = model.create_variable("x2") model.add_constraint(2*x1 - x2 <= -1) model.add_constraint(x1 + x2 == 3) model.add_constraint(x1 + x2 >= 4) model.maximize(x1 + 3 * x2) solution = model.solve() assert solution.is_feasible == False, "Your algorithm found a solution to an unfeasible problem. This shouldn't happen..." logging.info("Congratulations! This problem is unfeasible and your algorithm has found that :)")
def run(): model = Model("example_03_unbounded") x1 = model.create_variable("x1") x2 = model.create_variable("x2") x3 = model.create_variable("x3") model.add_constraint(x1 - 3*x2 + 2*x3 <= 10) model.add_constraint(x1 + 5*x2 - 1*x3 >= -7) model.minimize(5 * x1 + 8 * x2) try: model.solve() raise AssertionError("Your algorithm found a solution to an unbounded problem. This shouldn't happen...") except: logging.info("Congratulations! This problem is unbounded and your algorithm has found that :)")
def run(): model = Model("example_03_unbounded") x1 = model.create_variable("x1") x2 = model.create_variable("x2") x3 = model.create_variable("x3") model.add_constraint(x1 + 3*x2 + 2*x3 >= 10) model.add_constraint(x1 + 5*x2 + 1*x3 >= -7) model.maximize(5 * x1 + 8 * x2) solution = model.solve() assert solution.is_bounded == False, "Your algorithm found a solution to an unbounded problem. This shouldn't happen..." logging.info("Congratulations! This problem is unbounded and your algorithm has found that :)")
def run(): model = Model("example_01_solvable") x1 = model.create_variable("x1") x2 = model.create_variable("x2") model.add_constraint(-1 * x1 <= 150) model.add_constraint(-1 * x2 <= 250) model.add_constraint(-2 * x1 - x2 <= 500) model.maximize(8 * x1 + 5 * x2) try: solution = model.solve() except UnboundedException: logging.info("Congratulations! You found an unfesiable solution :)") else: raise AssertionError( "This problem has no solution but your algorithm hasn't figured it out!" )
def run(): #TODO: # fill missing test based on the example_01_solvable.py # to make the test a bit more interesting: # * make the model unfeasible in a way detectable by the 2-phase simplex # model = Model("ex5") x1 = model.create_variable("x1") x2 = model.create_variable("x2") model.maximize(x1) model.add_constraint(x1 + x2 == 10) model.add_constraint(x1 - x2 >= 100) try: solution = model.solve() except ErrorEx5: logging.info("OK") else: raise AssertionError("NOT OK!!!")
def run(): model = Model("example_04_solvable_artificial_vars") x1 = model.create_variable("x1") x2 = model.create_variable("x2") model.add_constraint(2*x1 - x2 <= -1) model.add_constraint(x1 + x2 == 3) model.maximize(x1 + 3 * x2) try: solution = model.solve() except Exception as e: print(e) raise AssertionError("This problem has a solution and your algorithm hasn't found it!") logging.info(solution) assert (solution.assignment == [0.0, 3.0]), "Your algorithm found an incorrect solution!" logging.info("Congratulations! This solution seems to be alright :)")
def _normalize_model(self, model: Model) -> Model: """ _normalize_model(model: Model) -> Model: returns a normalized version of the given model """ """this method should create a new canonical model based on the current one # - canonical model has only the MAX objective # - canonical model has only EQ constraints (thanks to the additional slack / surplus variables) # you should add extra (slack, surplus) variables and store them somewhere as the solver attribute """ normalized_objective = model.objective.as_maximize() normalized_constraints = self._normalize_constraints(model) return Model("normalized model", model.variables, normalized_constraints, normalized_objective)
def run(): #TODO: # fill missing test based on the example_01_solvable.py # to make the test a bit more interesting: # * make the solver use artificial variables! model = Model("ex4") x1 = model.create_variable("x1") x2 = model.create_variable("x2") model.add_constraint(2*x1 - x2 <= -1) model.add_constraint(x1 + x2 == 3) model.maximize(x1 + 3*x2) try: solution = model.solve() except: raise AssertionError("Solution not found!") logging.info(solution) assert (solution.assignment == [0.0, 3.0]), "NOT OK!!!" logging.info("OK")
def run(): primal = Model("z2") l = primal.create_variable("l") s = primal.create_variable("s") k = primal.create_variable("k") primal.add_constraint(8 * l + 6 * s + k <= 960) primal.add_constraint(8 * l + 4 * s + 3 * k <= 800) primal.add_constraint(4 * l + 3 * s + k <= 320) primal.maximize(60 * l + 30 * s + 20 * k) dual = primal.dual() primal_solution = primal.solve() analyser = Analyser() analysis_results = analyser.analyse(primal_solution) analyser.interpret_results(primal_solution, analysis_results)
def run(): primal = Model("Zad1") # x1 -> SS - super # x2 -> S - standardowy # x3 -> O - oszczędny x1 = primal.create_variable("x1") x2 = primal.create_variable("x2") x3 = primal.create_variable("x3") primal.add_constraint(2 * x1 + 2 * x2 + 5 * x3 <= 40) primal.add_constraint(x1 + 3 * x2 + 2 * x3 <= 30) primal.add_constraint(3 * x1 + x2 + 3 * x3 <= 30) primal.maximize(32 * x1 + 24 * x2 + 48 * x3) expected_dual = Model("Zad1") y1 = expected_dual.create_variable("y1") y2 = expected_dual.create_variable("y2") y3 = expected_dual.create_variable("y3") expected_dual.add_constraint(2 * y1 + y2 + 3 * y3 >= 32) expected_dual.add_constraint(2 * y1 + 3 * y2 + y3 >= 24) expected_dual.add_constraint(5 * y1 + 2 * y2 + 3 * y3 >= 48) expected_dual.minimize(40 * y1 + 30 * y2 + 30 * y3) expected_bounds = [(19.6363636363, 44.57142857), (17.77777777, 53.333333333), (37.0, 61.99999999999)] dual = primal.dual() assert dual.is_equivalent( expected_dual), "dual wasn't calculated as expected" assert primal.is_equivalent( dual.dual()), "double dual should equal the initial model" primal_solution = primal.solve() dual_solution = dual.solve() assert math.isclose( primal_solution.objective_value(), dual_solution.objective_value(), abs_tol=0.000001 ), "dual and primal should have the same value at optimum" logging.info( "Congratulations! The dual creation seems to be implemented correctly :)\n" ) analyser = Analyser() analysis_results = analyser.analyse(primal_solution) analyser.interpret_results(primal_solution, analysis_results, logging.info) objective_analysis_results = analysis_results[ ObjectiveSensitivityAnalyser.name()] tolerance = 0.001 for (i, bounds_pair) in enumerate(objective_analysis_results): assert math.isclose( bounds_pair[0], expected_bounds[i][0], abs_tol=tolerance ), f"left bound of the coefficient range seems to be incorrect, expected {expected_bounds[i][0]}, got {bounds_pair[0]}" assert math.isclose( bounds_pair[1], expected_bounds[i][1], abs_tol=tolerance ), f"right bound of the coefficient range seems to be incorrect, expected {expected_bounds[i][1]}, got {bounds_pair[1]}" logging.info( "Congratulations! This cost coefficients analysis look alright :)") print(dual) print(analyser.interpret_results(primal_solution, analysis_results))
from saport.simplex.model import Model model = Model("z3") x = model.create_variable("x") y = model.create_variable("y") model.add_constraint(15 * x + 2 * y <= 60) model.add_constraint(5 * x + 15 * y >= 50) model.add_constraint(20 * x + 5 * y >= 40) model.minimize(8 * x + 4 * y) solution = model.solve() print(solution)
def run(): model = Model("example_07_cost_sensitivity") x1 = model.create_variable("x1") x2 = model.create_variable("x2") x3 = model.create_variable("x3") model.add_constraint(6 * x1 + 5 * x2 + 8 * x3 <= 60) model.add_constraint(10 * x1 + 20 * x2 + 10 * x3 <= 150) model.add_constraint(x1 <= 8) model.maximize(5 * x1 + 4.5 * x2 + 6 * x3) solution = model.solve() analyser = Analyser() analysis_results = analyser.analyse(solution) analyser.interpret_results(solution, analysis_results, logging.info) objective_analysis_results = analysis_results[ ObjectiveSensitivityAnalyser.name()] expected_bounds = [(4.636, 5.4), (4.167, 6.5), (float("-inf"), 6.571)] tolerance = 0.001 for (i, bounds_pair) in enumerate(objective_analysis_results): assert math.isclose( bounds_pair[0], expected_bounds[i][0], abs_tol=tolerance ), f"left bound of the coefficient range seems to be incorrect, expected {expected_bounds[i][0]}, got {bounds_pair[0]}" assert math.isclose( bounds_pair[1], expected_bounds[i][1], abs_tol=tolerance ), f"right bound of the coefficient range seems to be incorrect, expected {expected_bounds[i][1]}, got {bounds_pair[1]}" logging.info( "Congratulations! This cost coefficients analysis look alright :)")
from saport.simplex.model import Model model = Model("zadanie 4") xs = [model.create_variable(f'x{i}') for i in range(14)] model.add_constraint(xs[0] + xs[1] + xs[2] + xs[3] >= 150) model.add_constraint( xs[1] + xs[4] + xs[5] + xs[6] + xs[7] + 2 * xs[8] + 2 * xs[9] >= 200) model.add_constraint( xs[2] + 2 * xs[3] + xs[5] + 2 * xs[6] + 3 * xs[7] + 1 * xs[9] + 2 * xs[10] + 3 * xs[11] + 4 * xs[12] + 5 * xs[13] >= 150) model.minimize(95 * xs[0] + 20 * xs[1] + 60 * xs[2] + 25 * xs[3] + 125 * xs[4] + 90 * xs[5] + 55 * xs[6] + 20 * xs[7] + 50 * xs[8] + 15 * xs[9] + 130 * xs[10] + 95 * xs[11] + 60 * xs[12] + 25 * xs[13]) solution = model.solve() print(solution)
# TODO: model and solve assignment 2 from the PDF from saport.simplex.solver import Solver from saport.simplex.model import Model model = Model("Zadanie 2") x1 = model.create_variable("p1") x2 = model.create_variable("p2") x3 = model.create_variable("p3") x4 = model.create_variable("p4") expr1 = 0.8 * x1 + 2.4 * x2 + 0.9 * x3 + 0.4 * x4 expr2 = 0.6 * x1 + 0.6 * x2 + 0.3 * x3 + 0.3 * x4 model.add_constraint(expr1 >= 1200) model.add_constraint(expr2 >= 600) model.minimize(9.6 * x1 + 14.4 * x2 + 10.8 * x3 + 7.2 * x4) print("Before solving:") print(model) solution = model.solve() print("Solution: ") print(solution)
def run(): model = Model("example_03_unbounded") x1 = model.create_variable("x1") x2 = model.create_variable("x2") x3 = model.create_variable("x3") model.add_constraint(x1 + x2 >= -100) model.add_constraint(x1 - 2 * x3 >= -200) model.add_constraint(5 * x2 + 3 * x3 >= -300) model.maximize(9 * x1 + 9 * x2 + 7 * x3) try: solution = model.solve() except UnboundeLinearProgramException: logging.info("Congratulations! You found an infeasible solution!") else: raise AssertionError( "This problem has no solution but your algorithm hasn't figured it out!" )
def run(): model = Model("example_02_solvable") x1 = model.create_variable("x1") x2 = model.create_variable("x2") x3 = model.create_variable("x3") model.add_constraint(x1 + 3*x2 + 2*x3 <= 10) model.add_constraint(-1*x1 - 5*x2 - 1*x3 >= -8) model.minimize(-8 * x1 - 10 * x2 - 7 * x3) try: solution = model.solve() except: raise AssertionError("This problem has a solution and your algorithm hasn't found it!") logging.info(solution) assert (solution.assignment == [8.0, 0.0, 0.0]), "Your algorithm found an incorrect solution!" logging.info("Congratulations! This solution seems to be alright :)")
def run(): model = Model("example_03") x1 = model.create_variable("x1") x2 = model.create_variable("x2") x3 = model.create_variable("x3") model.add_constraint(x1 + x2 + x3 >= -250) model.add_constraint(x1 + 100 * x2 + 1000 * x3 >= -459) model.add_constraint(260 * x1 + 2 * x2 + 500 * x3 >= -5156) model.maximize(80 * x1 + 45 * x2 + 2 * x3) try: solution = model.solve() except UnboundeLinearProgramException: logging.info("Congratulations! You found an unfesiable solution :)") else: raise AssertionError( "This problem has no solution but your algorithm hasn't figured it out!" )
from saport.simplex.model import Model model = Model("z1") x = model.create_variable("x") y = model.create_variable("y") z = model.create_variable("z") model.add_constraint(x + y + z <= 30) model.add_constraint(x + 2*y + z >= 10) model.add_constraint(2 * y + z <= 20) model.maximize(2 * x + y + 3 * z) solution = model.solve() print(solution)
from saport.simplex.analyser import Analyser from saport.simplex.model import Model # remember to print the dual model (just print()) and the analysis results (analyser.interpret_results(solution, analysis_results)) # in case of doubt refer to examples 06 and 07 primal = Model("Zad1") ss = primal.create_variable("SS") s = primal.create_variable("S") o = primal.create_variable("O") primal.add_constraint(2 * ss + 2 * s + 5 * o <= 40) primal.add_constraint(ss + 3 * s + 2 * o <= 30) primal.add_constraint(3 * ss + s + 3 * o <= 30) primal.maximize(32 * ss + 24 * s + 48 * o) dual = primal.dual() print(dual) solution = primal.solve() analyser = Analyser() analysis_results = analyser.analyse(solution) analyser.interpret_results(solution, analysis_results)
def run(): #TODO: # fill missing test based on the example_01_solvable.py # to make the test a bit more interesting: # * make the model unbounded! # # TIP: you may use other solvers (e.g. https://online-optimizer.appspot.com) # to check if the problem is unbounded # logging.info("This test is empty but it shouldn't be, fix it!") # raise AssertionError("Test is empty") model = Model("example_03_unbounded") x1 = model.create_variable("x1") x2 = model.create_variable("x2") x3 = model.create_variable("x3") model.add_constraint(x1 - x2 + x3 <= 5) model.add_constraint(-2 * x1 + x2 <= 3) model.add_constraint(x2 - 2 * x3 <= 5) model.maximize(3 * x2 + x3) try: solution = model.solve() except Exception as e: logging.info("Solver throw an Exception: " + e.__str__()) # raise AssertionError(e.__str__()) assert ( e.__eq__("Linear Programming model is unbounded") ), "Your algorithm throw an Exception -> \"Linear Programming model is unbounded\"" logging.info("Congratulations! This Exception seems to be alright :)")
# TODO: model and solve assignment 4 from the PDF # How to use SAPORT? from saport.simplex.solver import Solver from saport.simplex.model import Model model = Model("Zadanie 4") # LICZBA SPOSOBÓW OGRANICZONA DO 5 PONIEWAŻ INNE NIE MAJĄ SENSU I MOŻNA JE ODRZUCIC x1 = model.create_variable("sps_1") #1x 105cm + 1x 75cm + 0x35cm => odpad: 20 x2 = model.create_variable("sps_2") #1x 105cm + 0x 75cm + 2x35cm => odpad: 25 x3 = model.create_variable("sps_3") #0x 105cm + 2x 75cm + 1x35cm => odpad: 15 x4 = model.create_variable("sps_4") #0x 105cm + 1x 75cm + 3x35cm => odpad: 20 x5 = model.create_variable("sps_5") #0x 105cm + 0x 75cm + 5x35cm => odpad: 25 expr1 = x1 + x2 expr2 = x1 + 2 * x3 + x4 expr3 = 2 * x2 + x3 + 3 * x4 + 5 * x5 model.add_constraint(expr1 == 150) model.add_constraint(expr2 == 200) model.add_constraint(expr3 == 150) model.minimize(20 * x1 + 25 * x2 + 15 * x3 + 20 * x4 + 25 * x5) print("Before solving:") print(model) solution = model.solve() print("Solution: ")
from saport.simplex.model import Model model = Model("zadanie 2") x1 = model.create_variable("x1") x2 = model.create_variable("x2") x3 = model.create_variable("x3") x4 = model.create_variable("x4") model.add_constraint(0.8 * x1 + 2.4 * x2 + 0.9 * x3 + 0.4 * x4 >= 1200) model.add_constraint(0.6 * x1 + 0.6 * x2 + 0.3 * x3 + 0.3 * x4 >= 600) model.minimize(9.6 * x1 + 14.4 * x2 + 10.8 * x3 + 7.2 * x4) solution = model.solve() print(solution)
# How to use SAPORT? # 1. Import the library from saport.simplex.model import Model from saport.simplex.solver import Solver # 2. Create a model model = Model("example") # 3. Add variables x1 = model.create_variable("x1") x2 = model.create_variable("x2") x3 = model.create_variable("x3") # 4. FYI: You can create expression and evaluate them expr1 = 0.16 * x1 - 0.94 * x2 + 0.9 * x3 print( f"Value of the expression for the specified assignment is {expr1.evaluate([1, 1, 2])}\n" ) # 5. Then add constraints to the model model.add_constraint(expr1 <= 1200) model.add_constraint(0.2 * x2 + 0.3 * x2 + 0.3 * x3 + 0.1 * x1 <= 600) # 6. Set the objective! model.minimize(1.1 * x1 + 3.4 * x2 + 2.2 * x3) # 7. You can print the model print("Before solving:") print(model)
from saport.simplex.solver import Solver from saport.simplex.model import Model from saport.simplex.expressions.expression import Expression model = Model("zadanie 4") x_i = [model.create_variable(f'x{i}') for i in range(14)] # constraints model.add_constraint(x_i[0] + x_i[1] + x_i[2] + x_i[3] >= 150) model.add_constraint(x_i[1] + x_i[4] + x_i[5] + x_i[6] + x_i[7] + 2 * x_i[8] + 2 * x_i[9] >= 200) model.add_constraint( x_i[2] + 2 * x_i[3] + x_i[5] + 2 * x_i[6] + 3 * x_i[7] + 1 * x_i[9] + 2 * x_i[10] + 3 * x_i[11] + 4 * x_i[12] + 5 * x_i[13] >= 150) model.minimize(sum(x_i, start=Expression())) model.solve(Solver())
def run(): #TODO: # fill missing test based on the example_01_solvable.py # to make the test a bit more interesting: # * minimize the objective (so the solver would have to normalize it) # * make some "=>" constraints # * the model still has to be solvable by the basix simplex withour artificial variables # # TIP: you may use other solvers (e.g. https://online-optimizer.appspot.com) # to find the correct solution model = Model("example_02_solvable") x1 = model.create_variable("x1") x2 = model.create_variable("x2") x3 = model.create_variable("x3") x4 = model.create_variable("x4") model.add_constraint(-2 * x1 - 4 * x2 - 3 * x3 - 7 * x4 >= -800) model.add_constraint(-4 * x1 - 5 * x2 - 3 * x3 - 2 * x4 >= -640) model.add_constraint(-4 * x1 - 1 * x2 - 4 * x3 - 1 * x4 >= -600) model.minimize(-80 * x1 - 60 * x2 - 30 * x3 - 50 * x4) try: solution = model.solve() except: raise AssertionError( "This problem has a solution and your algorithm hasn't found it!") logging.info(solution) assert (solution.assignment == [ 120.0, 0, 0, 80.0, 0.0, 0.0, 40 ]), "Your algorithm found an incorrect solution!" logging.info("Congratulations! This solution seems to be alright :)")
def run(): primal = Model("Zad2") # x1 -> ławki # x2 -> stoły # x3 -> krzesła x1 = primal.create_variable("x1") x2 = primal.create_variable("x2") x3 = primal.create_variable("x3") primal.add_constraint(8 * x1 + 6 * x2 + x3 <= 960) primal.add_constraint(8 * x1 + 4 * x2 + 3 * x3 <= 800) primal.add_constraint(4 * x1 + 3 * x2 + x3 <= 320) primal.maximize(60 * x1 + 30 * x2 + 20 * x3) expected_dual = Model("Zad2") y1 = expected_dual.create_variable("y1") y2 = expected_dual.create_variable("y2") y3 = expected_dual.create_variable("y3") expected_dual.add_constraint(8 * y1 + 8 * y2 + 4 * y3 >= 60) expected_dual.add_constraint(6 * y1 + 4 * y2 + 3 * y3 >= 30) expected_dual.add_constraint(y1 + 3 * y2 + y3 >= 20) expected_dual.minimize(960 * y1 + 800 * y2 + 320 * y3) expected_bounds = [(56.0, 80.0), (float("-inf"), 35.0), (15.0, 22.5)] dual = primal.dual() assert dual.is_equivalent( expected_dual), "dual wasn't calculated as expected" assert primal.is_equivalent( dual.dual()), "double dual should equal the initial model" primal_solution = primal.solve() dual_solution = dual.solve() assert math.isclose( primal_solution.objective_value(), dual_solution.objective_value(), abs_tol=0.000001 ), "dual and primal should have the same value at optimum" logging.info( "Congratulations! The dual creation seems to be implemented correctly :)\n" ) analyser = Analyser() analysis_results = analyser.analyse(primal_solution) analyser.interpret_results(primal_solution, analysis_results, logging.info) objective_analysis_results = analysis_results[ ObjectiveSensitivityAnalyser.name()] tolerance = 0.001 for (i, bounds_pair) in enumerate(objective_analysis_results): assert math.isclose( bounds_pair[0], expected_bounds[i][0], abs_tol=tolerance ), f"left bound of the coefficient range seems to be incorrect, expected {expected_bounds[i][0]}, got {bounds_pair[0]}" assert math.isclose( bounds_pair[1], expected_bounds[i][1], abs_tol=tolerance ), f"right bound of the coefficient range seems to be incorrect, expected {expected_bounds[i][1]}, got {bounds_pair[1]}" logging.info( "Congratulations! This cost coefficients analysis look alright :)") print(dual) print(analyser.interpret_results(primal_solution, analysis_results))
# TODO: model and solve assignment 1 from the PDF # How to use SAPORT? # 1. Import the library from saport.simplex.solver import Solver from saport.simplex.model import Model model = Model("Zadanie 1") x1 = model.create_variable("x1") x2 = model.create_variable("x2") x3 = model.create_variable("x3") expr1 = x1 + x2 + x3 expr2 = x1 + 2*x2 + x3 expr3 = 2*x2 + x3 model.add_constraint(expr1 <= 30) model.add_constraint(expr2 >= 10) model.add_constraint(expr3 <= 20) model.maximize(2* x1 + x2 + 3* x3) print("Before solving:") print(model) solution = model.solve() print("Solution: ") print(solution)