While highs_solve() is convenient for one-shot problems,
the solver API gives fine-grained control for building models
incrementally, modifying problems, and performing warm-starts.
Build a model and create a solver from it:
library(highs)
model <- highs_model(
L = c(2, 4, 3),
lower = 0,
A = matrix(c(3, 4, 2, 2, 1, 2, 1, 3, 2), nrow = 3, byrow = TRUE),
rhs = c(60, 40, 80),
maximum = TRUE
)
solver <- hi_new_solver(model)hi_solver_run(solver)
#> [1] 0
hi_solver_status_message(solver)
#> [1] "Optimal"
sol <- hi_solver_get_solution(solver)
sol$col_value
#> [1] 0.000000 6.666667 16.666667After solving, retrieve detailed solver information:
info <- hi_solver_info(solver)
info$objective_function_value
#> [1] 76.66667
info$simplex_iteration_count
#> [1] 2
info$primal_solution_status
#> [1] "Feasible"Change objective coefficients, bounds, and constraints without rebuilding from scratch:
# Change the objective coefficient for variable 1 (0-based indexing)
hi_solver_set_objective(solver, index = 0L, coeff = 10.0)
#> [1] 0
# Change variable bounds
hi_solver_set_variable_bounds(solver, index = 0L, lower = 1.0, upper = 20.0)
#> [1] 0
# Change constraint bounds
hi_solver_set_constraint_bounds(solver, index = 0L, lower = -Inf, upper = 50.0)
#> [1] 0
# Re-solve
hi_solver_run(solver)
#> [1] 0
hi_solver_get_solution(solver)$col_value
#> [1] 16.66667 0.00000 0.00000Grow the model dynamically:
solver <- hi_new_solver(model)
# Add a new variable with bounds [0, 15]
hi_solver_add_vars(solver, lower = 0, upper = 15)
#> [1] 0
cat("Columns after add:", hi_solver_get_num_col(solver), "\n")
#> Columns after add: 4
# Add a new constraint: x1 + x2 + x3 + x4 <= 100
hi_solver_add_rows(solver,
lhs = -Inf, rhs = 100,
start = 0L,
index = 0L:3L,
value = rep(1.0, 4)
)
#> [1] 0
cat("Rows after add:", hi_solver_get_num_row(solver), "\n")
#> Rows after add: 4solver <- hi_new_solver(model)
hi_solver_get_lp_costs(solver)
#> [1] 2 4 3
hi_solver_get_num_col(solver)
#> [1] 3
hi_solver_get_num_row(solver)
#> [1] 3highs_solver() WrapperFor an object-oriented style, use highs_solver() which
returns an environment with methods:
hw <- highs_solver(model)
hw$solve()
#> ERROR: getOptionIndex: Option "pdlp_features_off" is unknown
#> [1] 0
hw$status_message()
#> [1] "Optimal"
hw$solution()$col_value
#> [1] 0.000000 6.666667 16.666667
hw$info()$objective_function_value
#> [1] 76.66667
# Modify and re-solve
hw$L(1, 10.0) # set cost of variable 1 to 10
#> [1] 0
hw$vbounds(1, 1, 20) # set bounds of variable 1 to [1, 20]
#> [1] 0
hw$solve()
#> ERROR: getOptionIndex: Option "pdlp_features_off" is unknown
#> [1] 0
hw$solution()$col_value
#> [1] 20 0 0solver <- hi_new_solver(model)
temp <- tempfile(fileext = ".mps")
hi_solver_write_model(solver, temp)
#> WARNING: Column names are not present, or contain duplicates: using names with prefix "c", beginning with suffix 0
#>
#> WARNING: Row names are not present, or contain duplicates: using names with prefix "r", beginning with suffix 0
#>
#> Writing the model to /tmp/RtmpRAr2Nn/file53de732c74f61.mps
#> [1] 1
# Read into a fresh solver
solver2 <- hi_new_solver(highs_model(L = 0))
hi_solver_read_model(solver2, temp)
#> [1] 0
hi_solver_run(solver2)
#> [1] 0
hi_solver_get_solution(solver2)$col_value
#> [1] 0.000000 6.666667 16.666667
unlink(temp)solver <- hi_new_solver(model)
hi_solver_version(solver)
#> [1] "1.14.0"
hi_solver_run(solver)
#> [1] 0
hi_solver_get_run_time(solver)
#> [1] 0.000241518