mirror of
https://github.com/ANL-CEEESA/MIPLearn.jl.git
synced 2025-12-06 08:28:52 -06:00
Conclude JumpModel
This commit is contained in:
@@ -12,7 +12,24 @@ function _add_constrs(
|
|||||||
constrs_sense,
|
constrs_sense,
|
||||||
constrs_rhs,
|
constrs_rhs,
|
||||||
stats,
|
stats,
|
||||||
) end
|
)
|
||||||
|
n, m = length(var_names), length(constrs_rhs)
|
||||||
|
vars = [variable_by_name(model, v) for v in var_names]
|
||||||
|
for i = 1:m
|
||||||
|
lhs = sum(constrs_lhs[i, j] * vars[j] for j = 1:n)
|
||||||
|
sense = constrs_sense[i]
|
||||||
|
rhs = constrs_rhs[i]
|
||||||
|
if sense == "="
|
||||||
|
@constraint(model, lhs == rhs)
|
||||||
|
elseif sense == ">"
|
||||||
|
@constraint(model, lhs >= rhs)
|
||||||
|
elseif sense == "<"
|
||||||
|
@constraint(model, lhs <= rhs)
|
||||||
|
else
|
||||||
|
error("Unknown sense: $sense")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function _extract_after_load(model::JuMP.Model, h5)
|
function _extract_after_load(model::JuMP.Model, h5)
|
||||||
if JuMP.objective_sense(model) == MOI.MIN_SENSE
|
if JuMP.objective_sense(model) == MOI.MIN_SENSE
|
||||||
@@ -230,7 +247,12 @@ function _extract_after_mip(model::JuMP.Model, h5)
|
|||||||
h5.put_array("mip_constr_slacks", slacks)
|
h5.put_array("mip_constr_slacks", slacks)
|
||||||
end
|
end
|
||||||
|
|
||||||
function _fix_variables(model::JuMP.Model, var_names, var_values, stats) end
|
function _fix_variables(model::JuMP.Model, var_names, var_values, stats)
|
||||||
|
vars = [variable_by_name(model, v) for v in var_names]
|
||||||
|
for (i, var) in enumerate(vars)
|
||||||
|
fix(var, var_values[i], force=true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function _optimize(model::JuMP.Model)
|
function _optimize(model::JuMP.Model)
|
||||||
optimize!(model)
|
optimize!(model)
|
||||||
@@ -245,9 +267,18 @@ function _relax(model::JuMP.Model)
|
|||||||
return relaxed
|
return relaxed
|
||||||
end
|
end
|
||||||
|
|
||||||
function _set_warm_starts(model::JuMP.Model, var_names, var_values, stats) end
|
function _set_warm_starts(model::JuMP.Model, var_names, var_values, stats)
|
||||||
|
(n_starts, _) = size(var_values)
|
||||||
|
n_starts == 1 || error("JuMP does not support multiple warm starts")
|
||||||
|
vars = [variable_by_name(model, v) for v in var_names]
|
||||||
|
for (i, var) in enumerate(vars)
|
||||||
|
set_start_value(var, var_values[i])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function _write(model::JuMP.Model, filename) end
|
function _write(model::JuMP.Model, filename)
|
||||||
|
write_to_file(model, filename)
|
||||||
|
end
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -258,15 +289,21 @@ function __init_solvers_jump__()
|
|||||||
self.inner = inner
|
self.inner = inner
|
||||||
end
|
end
|
||||||
|
|
||||||
add_constrs(self, var_names, constrs_lhs, constrs_sense, constrs_rhs, stats) =
|
add_constrs(
|
||||||
_add_constrs(
|
self,
|
||||||
self.inner,
|
var_names,
|
||||||
var_names,
|
constrs_lhs,
|
||||||
constrs_lhs,
|
constrs_sense,
|
||||||
constrs_sense,
|
constrs_rhs,
|
||||||
constrs_rhs,
|
stats = nothing,
|
||||||
stats,
|
) = _add_constrs(
|
||||||
)
|
self.inner,
|
||||||
|
from_str_array(var_names),
|
||||||
|
constrs_lhs,
|
||||||
|
from_str_array(constrs_sense),
|
||||||
|
constrs_rhs,
|
||||||
|
stats,
|
||||||
|
)
|
||||||
|
|
||||||
extract_after_load(self, h5) = _extract_after_load(self.inner, h5)
|
extract_after_load(self, h5) = _extract_after_load(self.inner, h5)
|
||||||
|
|
||||||
@@ -274,15 +311,15 @@ function __init_solvers_jump__()
|
|||||||
|
|
||||||
extract_after_mip(self, h5) = _extract_after_mip(self.inner, h5)
|
extract_after_mip(self, h5) = _extract_after_mip(self.inner, h5)
|
||||||
|
|
||||||
fix_variables(self, var_names, var_values, stats) =
|
fix_variables(self, var_names, var_values, stats = nothing) =
|
||||||
_fix_variables(self.inner, var_names, var_values, stats)
|
_fix_variables(self.inner, from_str_array(var_names), var_values, stats)
|
||||||
|
|
||||||
optimize(self) = _optimize(self.inner)
|
optimize(self) = _optimize(self.inner)
|
||||||
|
|
||||||
relax(self) = Class(_relax(self.inner))
|
relax(self) = Class(_relax(self.inner))
|
||||||
|
|
||||||
set_warm_starts(self, var_names, var_values, stats) =
|
set_warm_starts(self, var_names, var_values, stats = nothing) =
|
||||||
_set_warm_starts(self.inner, var_names, var_values, stats)
|
_set_warm_starts(self.inner, from_str_array(var_names), var_values, stats)
|
||||||
|
|
||||||
write(self, filename) = _write(self.inner, filename)
|
write(self, filename) = _write(self.inner, filename)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ version = "0.1.0"
|
|||||||
[deps]
|
[deps]
|
||||||
HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f"
|
HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f"
|
||||||
HiGHS = "87dc4568-4c63-4d18-b0c0-bb2238e4078b"
|
HiGHS = "87dc4568-4c63-4d18-b0c0-bb2238e4078b"
|
||||||
|
JuMP = "4076af6c-e467-56ae-b986-b466b2749572"
|
||||||
JuliaFormatter = "98e50ef6-434e-11e9-1051-2b60c6c9e899"
|
JuliaFormatter = "98e50ef6-434e-11e9-1051-2b60c6c9e899"
|
||||||
Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
|
Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
|
||||||
MIPLearn = "2b1277c3-b477-4c49-a15e-7ba350325c68"
|
MIPLearn = "2b1277c3-b477-4c49-a15e-7ba350325c68"
|
||||||
|
|||||||
BIN
test/fixtures/bell5.h5
vendored
BIN
test/fixtures/bell5.h5
vendored
Binary file not shown.
@@ -1,3 +1,6 @@
|
|||||||
|
using JuMP
|
||||||
|
import MIPLearn: from_str_array, to_str_array
|
||||||
|
|
||||||
function build_model()
|
function build_model()
|
||||||
data = SetCoverData(
|
data = SetCoverData(
|
||||||
costs = [5, 10, 12, 6, 8],
|
costs = [5, 10, 12, 6, 8],
|
||||||
@@ -12,6 +15,10 @@ end
|
|||||||
|
|
||||||
function test_solvers_jump()
|
function test_solvers_jump()
|
||||||
test_solvers_jump_extract()
|
test_solvers_jump_extract()
|
||||||
|
test_solvers_jump_add_constrs()
|
||||||
|
test_solvers_jump_fix_vars()
|
||||||
|
test_solvers_jump_warm_starts()
|
||||||
|
test_solvers_jump_write()
|
||||||
end
|
end
|
||||||
|
|
||||||
function test_solvers_jump_extract()
|
function test_solvers_jump_extract()
|
||||||
@@ -30,7 +37,7 @@ function test_solvers_jump_extract()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function test_str_array(key, expected)
|
function test_str_array(key, expected)
|
||||||
actual = MIPLearn.from_str_array(h5.get_array(key))
|
actual = from_str_array(h5.get_array(key))
|
||||||
@debug actual, expected
|
@debug actual, expected
|
||||||
@test actual !== nothing
|
@test actual !== nothing
|
||||||
@test all(actual .== expected)
|
@test all(actual .== expected)
|
||||||
@@ -74,7 +81,7 @@ function test_solvers_jump_extract()
|
|||||||
test_array("lp_var_reduced_costs", [-5, 0, 6, 0, 2])
|
test_array("lp_var_reduced_costs", [-5, 0, 6, 0, 2])
|
||||||
test_array("lp_var_values", [1, 0, 0, 1, 0])
|
test_array("lp_var_values", [1, 0, 0, 1, 0])
|
||||||
test_str_array("lp_var_basis_status", ["U", "B", "L", "B", "L"])
|
test_str_array("lp_var_basis_status", ["U", "B", "L", "B", "L"])
|
||||||
test_str_array("lp_constr_basis_status", ["B","N","N"])
|
test_str_array("lp_constr_basis_status", ["B", "N", "N"])
|
||||||
test_array("lp_constr_sa_rhs_up", [2, 2, 1])
|
test_array("lp_constr_sa_rhs_up", [2, 2, 1])
|
||||||
test_array("lp_constr_sa_rhs_down", [-Inf, 1, 0])
|
test_array("lp_constr_sa_rhs_down", [-Inf, 1, 0])
|
||||||
test_array("lp_var_sa_obj_up", [10, Inf, Inf, 8, Inf])
|
test_array("lp_var_sa_obj_up", [10, Inf, Inf, 8, Inf])
|
||||||
@@ -96,3 +103,54 @@ function test_solvers_jump_extract()
|
|||||||
mip_wallclock_time = h5.get_scalar("mip_wallclock_time")
|
mip_wallclock_time = h5.get_scalar("mip_wallclock_time")
|
||||||
@test mip_wallclock_time >= 0
|
@test mip_wallclock_time >= 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function test_solvers_jump_add_constrs()
|
||||||
|
h5 = H5File(tempname(), "w")
|
||||||
|
model = build_model()
|
||||||
|
model.extract_after_load(h5)
|
||||||
|
model.add_constrs(
|
||||||
|
to_str_array(["x[2]", "x[3]"]),
|
||||||
|
[
|
||||||
|
0 1
|
||||||
|
1 0
|
||||||
|
],
|
||||||
|
to_str_array(["=", "="]),
|
||||||
|
[0, 0],
|
||||||
|
)
|
||||||
|
model.optimize()
|
||||||
|
model.extract_after_mip(h5)
|
||||||
|
@test all(h5.get_array("mip_var_values") .≈ [1, 0, 0, 0, 1])
|
||||||
|
end
|
||||||
|
|
||||||
|
function test_solvers_jump_fix_vars()
|
||||||
|
h5 = H5File(tempname(), "w")
|
||||||
|
model = build_model()
|
||||||
|
model.extract_after_load(h5)
|
||||||
|
model.fix_variables(
|
||||||
|
to_str_array(["x[2]", "x[3]"]),
|
||||||
|
[0, 0],
|
||||||
|
)
|
||||||
|
model.optimize()
|
||||||
|
model.extract_after_mip(h5)
|
||||||
|
@test all(h5.get_array("mip_var_values") .≈ [1, 0, 0, 0, 1])
|
||||||
|
end
|
||||||
|
|
||||||
|
function test_solvers_jump_warm_starts()
|
||||||
|
# TODO: Check presence of warm start on log file
|
||||||
|
h5 = H5File(tempname(), "w")
|
||||||
|
model = build_model()
|
||||||
|
model.extract_after_load(h5)
|
||||||
|
model.set_warm_starts(
|
||||||
|
to_str_array(["x[0]", "x[1]", "x[2]", "x[3]", "x[4]"]),
|
||||||
|
[1 0 0 0 1],
|
||||||
|
)
|
||||||
|
model.optimize()
|
||||||
|
end
|
||||||
|
|
||||||
|
function test_solvers_jump_write()
|
||||||
|
mps_filename = "$(tempname()).mps"
|
||||||
|
model = build_model()
|
||||||
|
model.write(mps_filename)
|
||||||
|
@test isfile(mps_filename)
|
||||||
|
rm(mps_filename)
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user