CBC (COIN-OR branch and cut) is an open-source mixed integer programming solver (Forrest & Lougee-Heimer 2005). It is developed as part of the Computational Infrastructure for Operations Research (COIN-OR) project. By leveraging the CBC solver, this function can be used to generate solutions to optimization problems.
numeric
vector
if coefficients to specify the
objective function. Note that arguments should have one value per decision
variable (i.e. column in mat
).
matrix (i.e. matrix
or Matrix-class
)
of constraint coefficients. Here, each column corresponds to a different
decision variable, and each row corresponds to a different constraint.
To improve performance, it is recommended to specify the matrix using
a sparse format (see sparseMatrix
).
numeric
vector
of upper bounds for constraints.
Note that arguments should have one value per constraint
(i.e. row in mat
).
Defaults to a vector
of infinity (Inf
) values for each
constraint.
numeric
vector
of lower bounds for constraints.
Note that arguments should have one value per constraint
(i.e. row in mat
).
Defaults to a vector
of negative infinity (-Inf
) values for
each constraint.
numeric
vector
of lower bounds for decision
variables. Note that arguments should have one value per decision variable
(i.e. column in mat
).
Defaults to a vector
of negative infinity (-Inf
) values for
each variable.
numeric
vector
of upper bounds for decision
variables. Note that arguments should have one value per decision variable
(i.e. column in mat
).
Defaults to a vector
of infinity (Inf
) values for each
variable.
logical
vector
indicating if (TRUE
)
each decision variable is integer or (FALSE
) not an integer.
Note that arguments should have one value per decision variable
(i.e. column in mat
).
Defaults to a vector
of FALSE
values for each variable
(meaning that all variables are continuous).
logical
(i.e. TRUE
or FALSE
) should the
solver aim to maximize the objective function? Defaults to FALSE
.
list
of character
CBC arguments to customize the optimization
procedures (see CBC parameters section for details). Defaults to
list()
, such that default settings are used to generate solutions.
Note that all arguments must be supplied as a character
object
(see below for examples).
numeric
initial values
for starting solution. Missing (NA
) values can be used to indicate
that the starting value for a solution should be automatically calculated.
Note that only initial values for integer variables
(per argument to is_integer
) are actually used to generate solutions.
This is due to the behavior of the CBC solver.
Defaults to NULL
such that the starting solution is automatically
generated.
A list
containing the solution and additional information.
Specifically, it contains the following elements:
numeric
values of the decision variables
in the solution (same order as columns in the constraint matrix).
numeric
objective value of the solution.
character
description of the optimization process
when it finished. This description is based on the result of the
following elements. For example, an "optimal"
status indicates
that the optimization process finished because it found an optimal solution.
Also, if a maximum time limit was specified (using cbc_args
), an
"timelimit"
status indicates that the optimization process
finished because it ran out of time. Furthermore, an "infeasible"
status indicates that there is no possible solution to the specified
optimization problem. This "infeasible"
status could potentially
mean that there was a mistake when constructing the input data.
logical
indicating if the solution proven
to be optimal.
logical
indicating if the
dual is proven to be infeasible.
logical
indicating if the optimization
problem is proven to be infeasible.
logical
indicating if the maximum
number of nodes permitted for solving the optimization problem was
reached.
logical
indicating if the maximum
number of solutions (including those generated before finding the final
solution) permitted for solving the optimization problem was reached.
logical
indicating if the optimization process
was abandoned part way through solving the optimization problem.
logical
indicating if the maximum
number of iterations permitted for solving the optimization problem was
reached.
logical
indicating if the maximum
number of seconds permitted for for solving the optimization problem was
reached.
Many different parameters can be specified to customize the optimization process (see the user manual full list). Among all these parameters, some of the most useful parameters include the following:
Should information be printed during the solve process? Defaults
to "1"
meaning that information will be printed to the console.
To prevent this, a value of "0"
can be specified.
The level of detail to provide when printing information
to the console. Defaults to "1"
for a relatively small amount of
detail. For maximum detail, a value of "15"
can be specified.
Should the optimization process include a pre-processing
step that attempts to simplify the optimization problem? Defaults to
"On"
such that this pre-processing step is performed. To disable
this step, a value of "Off"
can be specified.
Optimality gap for solving the problem. The optimization
process will stop when the performance of the best found solution
is near enough to optimality based on this parameter. For example,
a value of 0.15 means that the optimization process will stop
when the best found solution is within 15
Defaults to "0"
, such that only an optimal solution is returned.
Maximum amount of time permitted for completing the
optimization process. Defaults to "1e+100"
. Note that time is
measured based on the TIMEM
parameter.
Method to measure time. Defaults to "cpu"
such that
timing is measured using CPU time. To specify that time should be
measured based on overall time elapsed (e.g. based on a wall clock),
a value of "elapsed"
can be specified.
Number of threads to use for solving the optimization
problem. For example, a value of "4"
indicates that four
threads should be used. Defaults to "0"
, such that the number of
threads is automatically determined.
Maximum number of solutions permitted to examine during the
optimization process. For example, a value of "1"
can be used
to obtain the first feasible solution.
Forrest J and Lougee-Heimer R (2005) CBC User Guide. In Emerging theory, Methods, and Applications (pp. 257--277). INFORMS, Catonsville, MD. doi:10.1287/educ.1053.0020 .
# \dontrun{
# Mathematically define a mixed integer programming problem
## maximize:
## 1 * x + 2 * y + 0.5 * z (eqn 1a)
## subject to:
## x + y <= 1 (eqn 1b)
## 3 * x + 4 * z >= 5 (eqn 1c)
## z = 4 (eqn 1d)
## 0 <= x <= 10 (eqn 1e)
## 0 <= y <= 11 (eqn 1f)
## 0 <= z <= 13 (eqn 1g)
## x, y, z is integer (eqn 1h)
# Create variables to represent this problem
### define objective function (eqn 1a)
obj <- c(1, 2, 0.5)
## define constraint matrix (eqns 1c--1d)
A <- matrix(c(1, 1, 0, 3, 0, 4, 0, 0, 1), byrow = TRUE, nrow = 3)
print(A)
#> [,1] [,2] [,3]
#> [1,] 1 1 0
#> [2,] 3 0 4
#> [3,] 0 0 1
## note that we could also define the constraint matrix using a
## sparse format to reduce memory consumption
## (though not needed for such a small problem)
library(Matrix)
A_sp <- sparseMatrix(
i = c(1, 2, 1, 2, 3),
j = c(1, 1, 2, 3, 3),
x = c(1, 3, 1, 4, 1))
print(A_sp)
#> 3 x 3 sparse Matrix of class "dgCMatrix"
#>
#> [1,] 1 1 .
#> [2,] 3 . 4
#> [3,] . . 1
## define upper and lower bounds for constraints (eqns 1c--1d)
row_ub <- c(1, Inf, 4)
row_lb <- c(-Inf, 5, 4)
## define upper and lower bounds for decision variables (eqns 1e--1g)
col_ub <- c(10, 11, 13)
col_lb <- c(0, 0, 0)
## specify which decision variables are integer (eqn 1h)
is_integer <- c(TRUE, TRUE, TRUE)
# Generate solution
## run solver (with default settings)
result <- cbc_solve(
obj = obj, mat = A, is_integer = is_integer,
row_lb = row_lb, row_ub = row_ub,
col_lb = col_lb, col_ub = col_ub,
max = TRUE)
## print result
print(result)
#> $column_solution
#> [1] 0 1 4
#>
#> $objective_value
#> [1] 4
#>
#> $is_proven_optimal
#> [1] TRUE
#>
#> $is_proven_dual_infeasible
#> [1] FALSE
#>
#> $is_proven_infeasible
#> [1] FALSE
#>
#> $is_node_limit_reached
#> [1] FALSE
#>
#> $is_solution_limit_reached
#> [1] FALSE
#>
#> $is_abandoned
#> [1] FALSE
#>
#> $is_iteration_limit_reached
#> [1] FALSE
#>
#> $is_seconds_limit_reached
#> [1] FALSE
#>
#> attr(,"class")
#> [1] "rcbc_milp_result"
## extract information from result
objective_value(result) # objective value of solution
#> [1] 4
column_solution(result) # decision variable values in solution
#> [1] 0 1 4
solution_status(result) # status description
#> [1] "optimal"
# Generate a solution with customized settings
## specify that only a single thread should be used,
## we only need a solution within 20% of optimality,
## and that we can only 2 (wall clock) seconds for the solution
cbc_args <- list(threads = "1", ratio = "0.2", sec = "2", timem = "elapsed")
## run solver (with customized settings)
result2 <- cbc_solve(
obj = obj, mat = A, is_integer = is_integer,
row_lb = row_lb, row_ub = row_ub,
col_lb = col_lb, col_ub = col_ub,
max = TRUE, cbc_args = cbc_args)
## print result
## we can see that this result is exactly the same as the previous
## result, so these customized settings did not really any influence.
## this is because the optimization problem is incredibly simple
## and so \emph{CBC} can find the optimal solution pretty much instantly
## we would expect such customized settings to have an influence
## when solving more complex problems
print(result2)
#> $column_solution
#> [1] 0 1 4
#>
#> $objective_value
#> [1] 4
#>
#> $is_proven_optimal
#> [1] TRUE
#>
#> $is_proven_dual_infeasible
#> [1] FALSE
#>
#> $is_proven_infeasible
#> [1] FALSE
#>
#> $is_node_limit_reached
#> [1] FALSE
#>
#> $is_solution_limit_reached
#> [1] FALSE
#>
#> $is_abandoned
#> [1] FALSE
#>
#> $is_iteration_limit_reached
#> [1] FALSE
#>
#> $is_seconds_limit_reached
#> [1] FALSE
#>
#> attr(,"class")
#> [1] "rcbc_milp_result"
# }