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)