*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.

- obj
`numeric`

`vector`

if coefficients to specify the objective function. Note that arguments should have one value per decision variable (i.e. column in`mat`

).- 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`

).- row_ub
`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.- row_lb
`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.- col_lb
`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.- col_ub
`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.- is_integer
`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).- max
`logical`

(i.e.`TRUE`

or`FALSE`

) should the solver aim to maximize the objective function? Defaults to`FALSE`

.- cbc_args
`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).- initial_solution
`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:

- column_solution
`numeric`

values of the decision variables in the solution (same order as columns in the constraint matrix).- objective_value
`numeric`

objective value of the solution.- status
`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.- is_proven_optimal
`logical`

indicating if the solution proven to be optimal.- is_proven_dual_infeasible
`logical`

indicating if the dual is proven to be infeasible.- is_proven_infeasible
`logical`

indicating if the optimization problem is proven to be infeasible.- is_node_limit_reached
`logical`

indicating if the maximum number of nodes permitted for solving the optimization problem was reached.- is_solution_limit_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.- is_abandoned
`logical`

indicating if the optimization process was abandoned part way through solving the optimization problem.- is_iteration_limit_reached
`logical`

indicating if the maximum number of iterations permitted for solving the optimization problem was reached.- is_seconds_limit_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:

- log
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.- verbose
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.- presolve
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.- ratio
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.- sec
Maximum amount of time permitted for completing the optimization process. Defaults to

`"1e+100"`

. Note that time is measured based on the`TIMEM`

parameter.- timem
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.- threads
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.- maxso
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"
# }
```