+/*
+ * Copyright (C) 2005-2011 University of Karlsruhe. All right reserved.
+ *
+ * This file is part of libFirm.
+ *
+ * This file may be distributed and/or modified under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.GPL included in the
+ * packaging of this file.
+ *
+ * Licensees holding valid libFirm Professional Edition licenses may use
+ * this file in accordance with the libFirm Commercial License.
+ * Agreement provided with the Software.
+ *
+ * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+ * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE.
+ */
+
/**
- * Author: Matthias Braun
- * Copyright: (c) Universitaet Karlsruhe
- * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
+ * @file
+ * @author Matthias Braun
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
+#include <math.h>
#include "obst.h"
typedef struct _gurobi_t {
lpp_t *lpp;
GRBenv *env;
+ GRBenv *modelenv;
GRBmodel *model;
} gurobi_t;
gurobi_t *grb = XMALLOCZ(gurobi_t);
grb->lpp = lpp;
- error = GRBloadenv(&grb->env, NULL);
+ /* /tmp/firm_gurobi.log is a hack (see below) */
+ error = GRBloadenv(&grb->env, "/tmp/firm_gurobi.log");
check_gurobi_error(grb, error);
+ /* Matze: do not set the FILE* for logging output. Because:
+ * a) the function is deprecated
+ * b) gurobi closes the FILE handle when it is done, which leads to
+ * very unexpected effects when you pass stdout or stderr as logging
+ * output.
+ * The only thing gurobi sanely supports is giving a string with a filename
+ * :-( ...so we use /tmp/firm_gurobi.log as a temporary measure...
+ */
+#if 0
error = GRBsetlogfile(grb->env, lpp->log);
check_gurobi_error(grb, error);
+#else
+ if (lpp->log != stdout && lpp->log != stderr) {
+ error = GRBsetintparam(grb->env, GRB_INT_PAR_OUTPUTFLAG, 0);
+ check_gurobi_error(grb, error);
+ }
+#endif
return grb;
}
static void free_gurobi(gurobi_t *grb)
{
+ GRBfreemodel(grb->model);
GRBfreeenv(grb->env);
free(grb);
}
*/
static void gurobi_construct(gurobi_t *grb)
{
- const matrix_elem_t *elem;
- int i, o;
- //int sv_cnt;
- //int *indices;
- //double *startv;
- int numcols, numrows, numentries;
- int objsen, *matbeg, *matcnt, *matind;
- double *obj, *rhs, *matval, *lb;
- char *sense, *vartype;
- char **colname, **rowname;
- struct obstack obst;
- lpp_t *lpp = grb->lpp;
- int error;
+ int i, o;
+ //int sv_cnt;
+ //int *indices;
+ //double *startv;
+ int numcols, numrows, numentries;
+ int objsen, *matbeg, *matcnt, *matind;
+ double *obj, *rhs, *matval, *lb;
+ char *sense, *vartype;
+ char **colname, **rowname;
+ struct obstack obst;
+ lpp_t *lpp = grb->lpp;
+ int error;
numcols = lpp->var_next-1;
numrows = lpp->cst_next-1;
objsen, 0, obj, sense, rhs, matbeg, matcnt, matind,
matval, lb, NULL, vartype, colname, rowname);
check_gurobi_error(grb, error);
+ grb->modelenv = GRBgetenv(grb->model);
obstack_free(&obst, NULL);
- free_lpp_matrix(lpp);
+ lpp_free_matrix(lpp);
}
static void gurobi_solve(gurobi_t *grb)
double *values;
double iterations;
- /* set performance parameters */
- // CPXsetintparam(grb->env, CPX_PARAM_MIPSTART, CPX_ON);
- //CPXsetintparam(grb->env, CPX_PARAM_MIPORDTYPE, CPX_MIPORDER_COST);
- /* output every search tree node */
- // CPXsetintparam(grb->env, CPX_PARAM_MIPINTERVAL, 1);
-
- /* experimental switches */
- // CPXsetintparam(grb->env, CPX_PARAM_VARSEL, CPX_VARSEL_STRONG);
- // CPXsetdblparam(grb->env, CPX_PARAM_BTTOL, 1.0);
- // CPXsetintparam(grb->env, CPX_PARAM_BRDIR, CPX_BRDIR_UP);
-
/* Set the time limit appropriately */
if(lpp->time_limit_secs > 0.0) {
- error = GRBsetdblparam(grb->env, GRB_DBL_PAR_TIMELIMIT, lpp->time_limit_secs);
+ error = GRBsetdblparam(grb->modelenv, GRB_DBL_PAR_TIMELIMIT, lpp->time_limit_secs);
check_gurobi_error(grb, error);
}
- /*
- * If we have enough time, we instruct cplex to imply some
- * of its higher order magic to pursue the best solution
- */
- if(lpp->emphasis) {
- /* not implemented */
- }
-
+#if 0
/*
* If a bound of the objective function is supplied,
* set it accordingly, dependign on minimization or maximization.
*/
if(lpp->set_bound) {
- //panic("bound not implemented yet");
fprintf(stderr, "Warning: gurobi bound not implemented yet\n");
}
+#endif
/* solve */
error = GRBoptimize(grb->model);
default: lpp->sol_state = lpp_feasible; break;
}
- /* get variable solution values */
- values = alloca(numcols * sizeof(*values));
- error = GRBgetdblattrarray(grb->model, GRB_DBL_ATTR_X, 0, numcols, values);
- check_gurobi_error(grb, error);
- for(i=0; i<numcols; ++i) {
- lpp->vars[1+i]->value = values[i];
- lpp->vars[1+i]->value_kind = lpp_value_solution;
- }
+ if (lpp->sol_state >= lpp_feasible) {
+ /* get variable solution values */
+ values = alloca(numcols * sizeof(*values));
+ error = GRBgetdblattrarray(grb->model, GRB_DBL_ATTR_X, 0, numcols,
+ values);
+ check_gurobi_error(grb, error);
+ for(i=0; i<numcols; ++i) {
+ lpp->vars[1+i]->value = values[i];
+ lpp->vars[1+i]->value_kind = lpp_value_solution;
+ }
- /* Get the value of the objective function. */
- error = GRBgetdblattr(grb->model, GRB_DBL_ATTR_OBJVAL, &lpp->objval);
- check_gurobi_error(grb, error);
- error = GRBgetdblattr(grb->model , GRB_DBL_ATTR_OBJBOUND, &lpp->best_bound);
- check_gurobi_error(grb, error);
+ /* Get the value of the objective function. */
+ error = GRBgetdblattr(grb->model, GRB_DBL_ATTR_OBJVAL, &lpp->objval);
+ check_gurobi_error(grb, error);
+ error = GRBgetdblattr(grb->model , GRB_DBL_ATTR_OBJBOUND,
+ &lpp->best_bound);
+ if (error != 0) {
+ lpp->best_bound = FP_NAN;
+ }
+ }
/* get some statistics */
error = GRBgetdblattr(grb->model, GRB_DBL_ATTR_ITERCOUNT, &iterations);