Пример #1
0
def test_ipopt_solver(model_name):
    current_dir = pathlib.Path(__file__).parent
    osil_file = current_dir / 'models' / (model_name + '.osil')
    pyomo_model = read_pyomo_model(osil_file)
    problem = problem_from_pyomo_model(pyomo_model)

    atol = rtol = 1e-4

    galini = Galini()
    galini.update_configuration({
        'galini': {
            'constraint_violation_tol': 1e-2,
        },
        'logging': {
            'stdout': True,
        },
        'branch_and_cut': {
            'tolerance': atol,
            'relative_tolerance': rtol,
            'root_node_feasible_solution_search_timelimit': 0,
            'cuts': {
                'maxiter': 100,
            }
        },
        'cuts_generator': {
            'generators': ['outer_approximation'],
        },
        'ipopt': {
            'ipopt': {
                'acceptable_constr_viol_tol': 1e-3
            },
        },
    })
    set_timelimit(30)
    start_timelimit()
    solver = BranchAndBoundSolver(galini)
    solver.before_solve(pyomo_model, problem)
    solution = solver.solve(problem)

    assert solution.status.is_success()

    sol_file = current_dir / 'solutions' / (model_name + '.sol')
    expected_solution = read_solution(sol_file)

    expected_objective = expected_solution['objective']
    assert solution.objective is not None
    assert is_close(expected_objective,
                    solution.objective.value,
                    atol=atol,
                    rtol=rtol)

    expected_variables = expected_solution['variables']

    for var_sol in solution.variables:
        assert is_close(
            expected_variables[var_sol.name],
            var_sol.value,
            atol=atol,
            rtol=rtol,
        )
Пример #2
0
def test_at_root_node(galini, problem):
    solver_ipopt = galini.instantiate_solver('ipopt')
    solver_mip = galini.instantiate_solver("mip")
    run_id = 'test_run'

    # Test at root node
    start_timelimit()
    algo = BranchAndCutAlgorithm(galini, FakeSolver(), telemetry=None)
    algo._cuts_generators_manager.before_start_at_root(run_id, problem, None)
    relaxation = _linear_relaxation(problem)
    relaxed_problem = relaxation.relax(problem)
    nbs_cuts = []
    mip_sols = []
    for iteration in range(5):
        mip_solution = solver_mip.solve(relaxed_problem, logger=None)
        assert mip_solution.status.is_success()
        mip_sols.append(mip_solution.objective.value)
        # Generate new cuts
        new_cuts = algo._cuts_generators_manager.generate(
            run_id, problem, None, relaxed_problem, mip_solution, None, None)
        # Add cuts as constraints
        nbs_cuts.append(len(list(new_cuts)))
        for cut in new_cuts:
            new_cons = Constraint(cut.name, cut.expr, cut.lower_bound,
                                  cut.upper_bound)
            relaxation._relax_constraint(problem, relaxed_problem, new_cons)
    assert (np.allclose(mip_sols,
                        [-200.0, -196.85714285714283, -196.5, -196.0, -196.0]))
    assert (nbs_cuts == [2, 2, 2, 0, 0])

    # Test when branched on x0 in [0.5, 1]
    x0 = problem.variable_view(problem.variables[0])
    x0.set_lower_bound(0.5)
    relaxed_problem = relaxation.relax(problem)
    algo._cuts_generators_manager.before_start_at_node(run_id, problem, None)
    mip_sols = []
    mip_solution = None
    for iteration in range(5):
        mip_solution = solver_mip.solve(relaxed_problem, logger=None)
        assert mip_solution.status.is_success()
        mip_sols.append(mip_solution.objective.value)
        # Generate new cuts
        new_cuts = algo._cuts_generators_manager.generate(
            run_id, problem, None, relaxed_problem, mip_solution, None, None)
        # Add cuts as constraints
        for cut in new_cuts:
            new_cons = Constraint(cut.name, cut.expr, cut.lower_bound,
                                  cut.upper_bound)
            relaxation._relax_constraint(problem, relaxed_problem, new_cons)
    assert (np.allclose(mip_sols, [
        -193.88095238095238, -187.96808510638297, -187.42857142857147,
        -187.10869565217394, -187.10869565217394
    ]))
Пример #3
0
def test_adjacency_matrix(galini, problem):
    solver_ipopt = galini.instantiate_solver('ipopt')
    solver_mip = galini.instantiate_solver("mip")

    run_id = 'test_run'
    # Test adjacency matrix
    start_timelimit()
    triangle_cuts_gen = TriangleCutsGenerator(
        galini, galini._config.cuts_generator.triangle)
    triangle_cuts_gen.before_start_at_root(run_id, problem, None)
    assert (np.allclose(triangle_cuts_gen._get_adjacency_matrix(problem),
                        [[1, 1, 1, 0, 0, 1, 0, 1], [1, 0, 1, 1, 1, 0, 1, 1],
                         [1, 1, 1, 1, 0, 1, 1, 1], [0, 1, 1, 1, 1, 1, 1, 1],
                         [0, 1, 0, 1, 0, 1, 1, 1], [1, 0, 1, 1, 1, 1, 1, 1],
                         [0, 1, 1, 1, 1, 1, 0, 0], [1, 1, 1, 1, 1, 1, 0, 1]]))
Пример #4
0
def test_triange_cut_violations(galini, problem):
    run_id = 'test_run'
    start_timelimit()
    triangle_cuts_gen = TriangleCutsGenerator(
        galini, galini._config.cuts_generator.triangle)
    triangle_cuts_gen.before_start_at_root(run_id, problem, None)

    # Test triangle cut violations
    relaxation = _linear_relaxation(problem)
    relaxed_problem = relaxation.relax(problem)
    known_solution = {
        'x[0]': 0.5,
        'x[1]': 0.5,
        'x[2]': 0.5,
        'x[3]': 0.5,
        'x[4]': 0.5,
        'x[5]': 1.0,
        'x[6]': 0.5,
        'x[7]': 0.5,
        '_objvar': -2.00,
        '_aux_bilinear_x[4]_x[7]': 0.5,
        '_aux_bilinear_x[5]_x[6]': 0.5,
        '_aux_bilinear_x[3]_x[7]': 0.0,
        '_aux_bilinear_x[5]_x[7]': 0.5,
        '_aux_bilinear_x[3]_x[6]': 0.5,
        '_aux_bilinear_x[0]_x[7]': 0.5,
        '_aux_bilinear_x[1]_x[3]': 0.0,
        '_aux_bilinear_x[3]_x[4]': 0.5,
        '_aux_bilinear_x[1]_x[2]': 0.0,
        '_aux_bilinear_x[0]_x[5]': 0.5,
        '_aux_bilinear_x[0]_x[0]': 0.5,
        '_aux_bilinear_x[0]_x[1]': 0.5,
        '_aux_bilinear_x[1]_x[4]': 0.5,
        '_aux_bilinear_x[3]_x[3]': 0.0,
        '_aux_bilinear_x[7]_x[7]': 0.0,
        '_aux_bilinear_x[3]_x[5]': 0.5,
        '_aux_bilinear_x[1]_x[6]': 0.5,
        '_aux_bilinear_x[5]_x[5]': 1.0,
        '_aux_bilinear_x[1]_x[7]': 0.0,
        '_aux_bilinear_x[2]_x[2]': 0.5,
        '_aux_bilinear_x[2]_x[3]': 0.5,
        '_aux_bilinear_x[4]_x[6]': 0.0,
        '_aux_bilinear_x[2]_x[5]': 0.5,
        '_aux_bilinear_x[4]_x[5]': 0.5,
        '_aux_bilinear_x[2]_x[6]': 0.0,
        '_aux_bilinear_x[2]_x[7]': 0.5,
        '_aux_bilinear_x[0]_x[2]': 0.5,
    }
    mip_solution = Solution(status=FakeStatus(),
                            optimal_obj=OptimalObjective('f', -200.0),
                            optimal_vars=[
                                OptimalVariable(v.name, known_solution[v.name])
                                for v in relaxed_problem.variables
                            ])
    triangle_viol = triangle_cuts_gen._get_triangle_violations(
        relaxed_problem, mip_solution)
    expected_triangle_viol = [[0, 0, 0.5], [0, 1, -0.5], [0, 2, -0.5],
                              [0, 3, -0.5], [1, 0, 0.5], [1, 1, -0.5],
                              [1, 2, -0.5], [1, 3, -0.5], [2, 0, 0.0],
                              [2, 1, 0.0], [2, 2, -0.5], [2, 3, -0.5],
                              [3, 0, 0.0], [3, 1, 0.0], [3, 2, 0.0],
                              [3, 3, -1.0], [4, 0, 0.0], [4, 1, -0.5],
                              [4, 2, 0.0], [4, 3, -0.5], [5, 0, -1.0],
                              [5, 1, 0.0], [5, 2, 0.0], [5, 3, 0.0],
                              [6, 0, 0.0], [6, 1, -1.0], [6, 2, 0.0],
                              [6, 3, 0.0], [7, 0, -1.0], [7, 1, 0.0],
                              [7, 2, 0.0], [7, 3, 0.0], [8, 0, -0.5],
                              [8, 1, -0.5], [8, 2, 0.5], [8, 3, -0.5],
                              [9, 0, -0.5], [9, 1, -0.5], [9, 2, 0.5],
                              [9, 3, -0.5], [10, 0, -0.5], [10, 1, -0.5],
                              [10, 2, -0.5], [10, 3, 0.5], [11, 0, 0.5],
                              [11, 1, -0.5], [11, 2, -0.5], [11, 3, -0.5],
                              [12, 0, -0.5], [12, 1, 0.5], [12, 2, -0.5],
                              [12, 3, -0.5], [13, 0, 0.0], [13, 1, 0.0],
                              [13, 2, -0.5], [13, 3, -0.5], [14, 0, -0.5],
                              [14, 1, 0.5], [14, 2, -0.5], [14, 3, -0.5],
                              [15, 0, 0.5], [15, 1, -0.5], [15, 2, -0.5],
                              [15, 3, -0.5], [16, 0, -0.5], [16, 1, 0.0],
                              [16, 2, -0.5], [16, 3, 0.0], [17, 0, 0.0],
                              [17, 1, -0.5], [17, 2, 0.0], [17, 3, -0.5],
                              [18, 0, 0.0], [18, 1, 0.0], [18, 2, -0.5],
                              [18, 3, -0.5], [19, 0, 0.5], [19, 1, -0.5],
                              [19, 2, -0.5], [19, 3, -0.5], [20, 0, -0.5],
                              [20, 1, 0.5], [20, 2, -0.5], [20, 3, -0.5],
                              [21, 0, 0.0], [21, 1, -0.5], [21, 2, 0.0],
                              [21, 3, -0.5], [22, 0, -0.5], [22, 1, 0.0],
                              [22, 2, -0.5], [22, 3, 0.0], [23, 0, -0.5],
                              [23, 1, 0.0], [23, 2, -0.5], [23, 3, 0.0],
                              [24, 0, 0.0], [24, 1, -0.5], [24, 2, 0.0],
                              [24, 3, -0.5]]
    assert len(triangle_viol) == len(expected_triangle_viol)
    for actual, expected in zip(triangle_viol, expected_triangle_viol):
        assert np.allclose(actual, expected)
Пример #5
0
    def execute_with_problem(self, model, problem, args):
        galini = Galini()
        if args.config:
            galini.update_configuration(args.config)

        solver_cls = galini.get_solver(args.solver.lower())

        if solver_cls is None:
            available = ', '.join(solvers_reg.keys())
            print('Solver {} not available. Available solvers: {}'.format(
                args.solver, available))
            sys.exit(1)

        apply_logging_config(galini.get_configuration_group('logging'))
        solver = solver_cls(galini)

        galini_group = galini.get_configuration_group('galini')
        timelimit = galini_group.get('timelimit')
        elapsed_counter = galini.telemetry.create_gauge('elapsed_time', 0.0)

        set_timelimit(timelimit)
        start_timelimit()
        start_time = current_time()

        solver.before_solve(model, problem)

        solution = solver.solve(
            problem, known_optimal_objective=args.known_optimal_objective)

        elapsed_counter.set_value(seconds_elapsed_since(start_time))

        if solution is None:
            raise RuntimeError('Solver did not return a solution')

        obj_table = OutputTable('Objectives', [
            {
                'id': 'name',
                'name': 'Objective',
                'type': 't'
            },
            {
                'id': 'value',
                'name': 'Value',
                'type': 'f'
            },
        ])

        value = solution.objective.value
        if not problem.objective.original_sense.is_minimization():
            if value is not None:
                value = -value

        obj_table.add_row({
            'name': solution.objective.name,
            'value': value,
        })

        var_table = OutputTable('Variables', [
            {
                'id': 'name',
                'name': 'Variable',
                'type': 't'
            },
            {
                'id': 'value',
                'name': 'Value',
                'type': 'f'
            },
        ])
        for var in solution.variables:
            var_table.add_row({
                'name': var.name,
                'value': var.value,
            })

        counter_table = OutputTable('Counters', [
            {
                'id': 'name',
                'name': 'Name',
                'type': 't'
            },
            {
                'id': 'value',
                'name': 'Value',
                'type': 'f'
            },
        ])
        for counter in galini.telemetry.counters_values():
            counter_table.add_row(counter)

        print_output_table([obj_table, var_table, counter_table], args)