Skip to content

Commit 5d4b0f3

Browse files
authored
Merge pull request #40 from kit-ty-kate/mip_gap
Add the ?mip_gap parameter that allows unoptimized solutions to be returned
2 parents f6ee218 + 8edd856 commit 5d4b0f3

10 files changed

+31
-14
lines changed

src/abstract_solver.h

+2
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ class abstract_solver {
9292
virtual int solve() { return 0; };
9393
virtual int solve(int timeout) { return 0; };
9494

95+
virtual void set_mip_gap(double) = 0;
96+
9597
// ******************************************************************
9698
// abort should, if possible, do something which causes solve to
9799
// terminate.

src/glpk_solver.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ void glpk_solver::abort(void) {
6767
return;
6868
}
6969

70+
void glpk_solver::set_mip_gap(double mip_gap) {
71+
this->mip_gap = mip_gap;
72+
}
73+
7074
// solve the current lp problem
7175
int glpk_solver::solve(int timeout) {
7276
int status = 0, nb_objectives = objectives.size();
@@ -85,6 +89,7 @@ int glpk_solver::solve(int timeout) {
8589
this->mip_params.presolve = GLP_ON;
8690
this->mip_params.binarize = GLP_ON;
8791
this->mip_params.tm_lim = timeout;
92+
this->mip_params.mip_gap = this->mip_gap;
8893
this->mip_params.msg_lev = (verbosity > 1) ? GLP_MSG_ON : GLP_MSG_OFF;
8994
// one of GLP_MSG_OFF GLP_MSG_ERR GLP_MSG_ON GLP_MSG_ALL
9095

@@ -129,8 +134,10 @@ int glpk_solver::solve(int timeout) {
129134
close(save_stdout);
130135
}
131136
switch (status) {
137+
case GLP_EMIPGAP:
132138
case 0: {
133139
switch (glp_mip_status(lp)) {
140+
case GLP_FEAS:
134141
case GLP_OPT: return 1;
135142
case GLP_NOFEAS: return 0;
136143
default: return -1;

src/glpk_solver.h

+3
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ class glpk_solver: public abstract_solver, public scoeff_solver<double, 1, 1> {
2424
// Allocate some columns for integer variables
2525
int set_intvar_range(int rank, CUDFcoefficient lower, CUDFcoefficient upper);
2626

27+
void set_mip_gap(double);
28+
2729
// Write the lp on a file
2830
// int writelp(const char *filename);
2931

@@ -97,6 +99,7 @@ class glpk_solver: public abstract_solver, public scoeff_solver<double, 1, 1> {
9799
private:
98100
glp_iocp mip_params;
99101
bool aborted;
102+
double mip_gap;
100103

101104
};
102105

src/lp_solver.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ int lp_solver::init_solver(CUDFVersionedPackageList *all_versioned_packages, int
8888
// write the problem into a file
8989
int lp_solver::writelp(const char *filename) { return 0; }
9090

91+
void lp_solver::set_mip_gap(double mip_gap) {} // TODO ?
92+
9193
// solve the current problem
9294
int lp_solver::solve() {
9395
int status = 0;

src/lp_solver.h

+2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ class lp_solver: public abstract_solver, public scoeff_solver<CUDFcoefficient, 0
2020
// Write the lp on a file
2121
int writelp(const char *filename);
2222

23+
void set_mip_gap(double);
24+
2325
// Solve the problem
2426
int solve();
2527
int solve(int timeout);

src/mccs.ml

+3-3
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ external set_problem_request: problem -> request -> unit
6060
= "set_problem_request"
6161

6262
external call_solver:
63-
solver_backend -> string -> int -> problem -> Cudf.package list option
63+
solver_backend -> string -> int -> float -> problem -> Cudf.package list option
6464
= "call_solver"
6565

6666
external backends_list:
@@ -75,15 +75,15 @@ let problem_of_cudf cudf =
7575
pb
7676

7777
let resolve_cudf
78-
?(verbosity=0) ?timeout ?(solver=default_solver)
78+
?(verbosity=0) ?timeout ?(mip_gap=0.0) ?(solver=default_solver)
7979
criteria (preamble, _, _ as cudf) =
8080
let timeout = match timeout with
8181
| None -> 0
8282
| Some f -> int_of_float (1000. *. f)
8383
in
8484
set_verbosity (max 0 verbosity);
8585
let pb = problem_of_cudf cudf in
86-
match call_solver solver criteria timeout pb with
86+
match call_solver solver criteria timeout mip_gap pb with
8787
| None -> None
8888
| Some sol ->
8989
let univ = Cudf.load_universe sol in

src/mccs.mli

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ type solver_backend = [ `GLPK | `LP of string | `COIN_CLP | `COIN_CBC | `COIN_SY
1919
(** Resolve the given problem. The timeout is in seconds, default is to never
2020
time out. *)
2121
val resolve_cudf:
22-
?verbosity:int -> ?timeout:float -> ?solver:solver_backend ->
22+
?verbosity:int -> ?timeout:float -> ?mip_gap:float -> ?solver:solver_backend ->
2323
string -> Cudf.cudf -> Cudf.solution option
2424

2525
(** Deprecated, corresponds to the default solver backend selection only *)

src/mccs_stubs.cpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -657,11 +657,11 @@ void restore_sigint_handler() {
657657
#endif
658658

659659
// Allow C-c to interrupt the solver
660-
Solver_return call_mccs_protected(Solver solver, char *criteria, int timeout, CUDFproblem* cpb) {
660+
Solver_return call_mccs_protected(Solver solver, char *criteria, int timeout, double mip_gap, CUDFproblem* cpb) {
661661
Solver_return ret = { 0, "", cpb, NULL };
662662
try {
663663
install_sigint_handler();
664-
ret = call_mccs(solver, criteria, timeout, cpb, &mccs_current_solver);
664+
ret = call_mccs(solver, criteria, timeout, mip_gap, cpb, &mccs_current_solver);
665665
mccs_current_solver = NULL;
666666
restore_sigint_handler();
667667
} catch (...) {
@@ -672,9 +672,9 @@ Solver_return call_mccs_protected(Solver solver, char *criteria, int timeout, CU
672672
}
673673

674674
extern "C" value call_solver
675-
(value ml_solver_backend, value ml_criteria, value ml_timeout, value ml_problem)
675+
(value ml_solver_backend, value ml_criteria, value ml_timeout, value mip_gap, value ml_problem)
676676
{
677-
CAMLparam3(ml_criteria, ml_timeout, ml_problem);
677+
CAMLparam4(ml_criteria, ml_timeout, mip_gap, ml_problem);
678678
CAMLlocal2(results, pkg);
679679
problem * pb = Problem_pt(ml_problem);
680680
CUDFproblem * cpb = pb->pb_cudf_problem;
@@ -689,7 +689,7 @@ extern "C" value call_solver
689689
strcat(criteria, "]");
690690

691691
// caml_release_runtime_system ();
692-
ret = call_mccs_protected(solver, criteria, Int_val(ml_timeout), cpb);
692+
ret = call_mccs_protected(solver, criteria, Int_val(ml_timeout), Double_val(mip_gap), cpb);
693693
// caml_acquire_runtime_system ();
694694
delete[] criteria;
695695
switch (ret.success) {

src/mccscudf.cpp

+4-3
Original file line numberDiff line numberDiff line change
@@ -285,12 +285,12 @@ CriteriaList *get_criteria(char *crit_descr, bool first_level, vector<abstract_c
285285
return process_criteria(crit_descr, pos, first_level, criteria_with_property);
286286
}
287287

288-
Solver_return call_mccs(Solver solver_arg, char *criteria_arg, int timeout, CUDFproblem* the_problem) {
288+
Solver_return call_mccs(Solver solver_arg, char *criteria_arg, int timeout, double mip_gap, CUDFproblem* the_problem) {
289289
abstract_solver *solver;
290-
return call_mccs(solver_arg, criteria_arg, timeout, the_problem, &solver);
290+
return call_mccs(solver_arg, criteria_arg, timeout, mip_gap, the_problem, &solver);
291291
}
292292

293-
Solver_return call_mccs(Solver solver_arg, char *criteria_arg, int timeout, CUDFproblem* the_problem, abstract_solver **solver_ptr) {
293+
Solver_return call_mccs(Solver solver_arg, char *criteria_arg, int timeout, double mip_gap, CUDFproblem* the_problem, abstract_solver **solver_ptr) {
294294
CUDFproblem *problem = the_problem;
295295
vector<abstract_criteria *> criteria_with_property;
296296
CriteriaList *criteria = get_criteria(criteria_arg, false, &criteria_with_property);
@@ -377,6 +377,7 @@ Solver_return call_mccs(Solver solver_arg, char *criteria_arg, int timeout, CUDF
377377
if (verbosity > 0) PRINT_OUT("========\nConstraint generation error.\n");
378378
no_solution = true;
379379
}
380+
solver->set_mip_gap(mip_gap);
380381
if (! no_solution) {
381382
int s = (timeout > 0) ? solver->solve(timeout) : solver->solve();
382383
if (s <= 0) {

src/mccscudf.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ typedef struct {
1616
abstract_solver * solution; // May be NULL with success == 1 for unsatisfiable problems
1717
} Solver_return;
1818

19-
Solver_return call_mccs(Solver solver_arg, char *criteria_arg, int timeout, CUDFproblem* the_problem);
20-
Solver_return call_mccs(Solver solver_arg, char *criteria_arg, int timeout, CUDFproblem* the_problem, abstract_solver **solver);
19+
Solver_return call_mccs(Solver solver_arg, char *criteria_arg, int timeout, double mip_gap, CUDFproblem* the_problem);
20+
Solver_return call_mccs(Solver solver_arg, char *criteria_arg, int timeout, double mip_gap, CUDFproblem* the_problem, abstract_solver **solver);
2121

2222
int has_backend(Solver_backend backend);
2323

0 commit comments

Comments
 (0)