Skip to content

CBCSolver

A class for interfacing with cbc to solve LPs

Methods

call_cbc(self, lp_file_path, solution_file_path)

Call cbc to solve an lp file

Parameters:

Name Type Description Default
lp_file_path str

The location of the lp to solve

required
solution_file_path str

Where to record the solution

required

Exceptions:

Type Description
SolverError

If CBC solver encountered an error

Source code in flipy/solvers/cbc_solver.py
def call_cbc(self, lp_file_path: str, solution_file_path: str):
    """ Call cbc to solve an lp file

    Raises
    ------
    SolverError
        If CBC solver encountered an error

    Parameters
    ----------
    lp_file_path:
        The location of the lp to solve
    solution_file_path:
        Where to record the solution
    """
    with open(os.devnull, 'w') as pipe:

        args = [self.bin_path, lp_file_path]
        if self.timeout:
            args.extend(['sec', str(self.timeout)])
        if self.mip_gap:
            args.extend(['ratio', str(self.mip_gap)])
        args.extend(['branch', 'printingOptions', 'all', 'solution', solution_file_path])

        with subprocess.Popen(args, stderr=pipe, stdout=pipe) as coin_proc:
            if coin_proc.wait() != 0:
                raise SolverError(f"Error while trying to execute {self.bin_path}")

read_solution(filename, lp_problem) classmethod

Read in variable values from a saved solution file

Parameters:

Name Type Description Default
filename str

The solution to read

required
lp_problem LpProblem

The Flipy object to set the variable values in

required

Returns:

Type Description
SolutionStatus

The status of the solution

Source code in flipy/solvers/cbc_solver.py
@classmethod
def read_solution(cls, filename: str, lp_problem: LpProblem) -> SolutionStatus:
    """ Read in variable values from a saved solution file

    Parameters
    ----------
    filename:
        The solution to read
    lp_problem:
        The Flipy object to set the variable values in

    Returns
    -------
    flipy.SolutionStatus
        The status of the solution
    """
    values = {}
    for var in lp_problem.lp_variables.values():
        values[var.name] = 0
    for constraint in lp_problem.lp_constraints.values():
        if constraint.slack:
            values[constraint.slack_variable.name] = 0

    with open(filename) as f:
        status_str = f.readline().split()[0]
        status = cls.STATUS_MAPPING.get(status_str, SolutionStatus.NotSolved)
        for line in f:
            if len(line) <= 2:
                break
            line = line.split()
            if line[0] == '**':
                line = line[1:]
            var_name = line[1]
            val = line[2]
            if var_name in values:
                values[var_name] = float(val)

    for var in lp_problem.lp_variables.values():
        var.set_value(values[var.name])
    for constraint in lp_problem.lp_constraints.values():
        if constraint.slack:
            constraint.slack_variable.set_value(values[constraint.slack_variable.name])
    return status

solve(self, lp_problem)

Form and solve the lp

Parameters:

Name Type Description Default
lp_problem LpProblem

The Flipy LP to solve

required

Exceptions:

Type Description
SolverError

If CBC solver encountered an error

Returns:

Type Description
SolutionStatus

The status of the solution

Source code in flipy/solvers/cbc_solver.py
def solve(self, lp_problem: LpProblem) -> SolutionStatus:
    """ Form and solve the lp

    Raises
    ------
    SolverError
        If CBC solver encountered an error

    Parameters
    ----------
    lp_problem:
        The Flipy LP to solve

    Returns
    -------
    flipy.SolutionStatus
        The status of the solution
    """
    with tempfile.TemporaryDirectory() as temp_dir:
        lp_file_path = os.path.join(temp_dir.name, 'problem.lp')
        solution_file_path = os.path.join(temp_dir.name, 'solution.sol')

        with open(lp_file_path, 'w') as f:
            lp_problem.write_lp(f)

        self.call_cbc(f.name, solution_file_path)

        if not os.path.exists(solution_file_path):
            return SolutionStatus.NotSolved

    return self.read_solution(solution_file_path, lp_problem)