Last active
August 29, 2015 14:05
-
-
Save felipecruz/e379f91df9e22166af18 to your computer and use it in GitHub Desktop.
gurobi cffi interface major WIP
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import cffi | |
GRB_EQUAL = 61 | |
ffi = cffi.FFI() | |
ffi.cdef(''' | |
typedef ... GRBenv; | |
typedef ... GRBmodel; | |
int GRBloadenv(GRBenv **envP, const char *logfilename); | |
void GRBfreeenv(GRBenv *env); | |
int GRBnewmodel (GRBenv *env, | |
GRBmodel **modelP, | |
const char *Pname, | |
int numvars, | |
double *obj, | |
double *lb, | |
double *ub, | |
char *vtype, | |
const char **varnames); | |
int GRBaddvars (GRBmodel *model, | |
int numvars, | |
int numnz, | |
int *vbeg, | |
int *vind, | |
double *vval, | |
double *obj, | |
double *lb, | |
double *ub, | |
char *vtype, | |
const char **varnames); | |
int GRBaddconstr (GRBmodel *model, | |
int numnz, | |
int *cind, | |
double *cval, | |
char sense, | |
double rhs, | |
const char *constrname); | |
int GRBupdatemodel(GRBmodel *model); | |
const char* GRBgeterrormsg(GRBenv *env); | |
int GRBoptimize(GRBmodel *model); | |
''') | |
gurobi = ffi.verify(''' | |
#include "gurobi_c.h" | |
''', | |
libraries=['gurobi56'], | |
include_dirs=['/Library/gurobi563/mac64/include'], | |
library_dirs=['/Library/gurobi563/mac64/lib']) | |
def update(model): | |
error = gurobi.GRBupdatemodel(model) | |
if error: | |
raise Exception("Error on GRBnewmodel()") | |
def add_constraint(env, model, indexes, values, obj, name, | |
constraint=GRB_EQUAL): | |
c_indexes = ffi.new('int[]', indexes) | |
c_values = ffi.new('double[]', values) | |
size = len(indexes) | |
error = gurobi.GRBaddconstr(model, | |
ffi.cast('int', size), | |
c_indexes, | |
c_values, | |
ffi.cast('char', constraint), | |
ffi.cast('double', obj), | |
ffi.new('char[]', name)) | |
if error: | |
msg = ffi.string(gurobi.GRBgeterrormsg(env)) | |
print("Error code: {} - {}".format(error, msg)) | |
raise Exception("Error on GRBaddconstr()") | |
def new_model(env, name, edges): | |
_c_strings = [ffi.new('char[]', edge.get_id()) for edge in edges] | |
varnames = ffi.new('char *[]', _c_strings) | |
objs = [ffi.cast("double", float(edge.cost)) for edge in edges] | |
num_vars = len(varnames) | |
model = ffi.new('GRBmodel**') | |
error = gurobi.GRBnewmodel(env[0], model, name, num_vars, objs, | |
ffi.NULL, ffi.NULL, ffi.NULL, varnames) | |
if error: | |
raise Exception("Error on GRBnewmodel()") | |
return model[0] | |
def model_optimize(model): | |
error = gurobi.GRBoptimize(model) | |
if error: | |
raise Exception("Error on GRBoptimize()") | |
def gurobi_env(log_file="facility.log"): | |
env = ffi.new('GRBenv**') | |
error = gurobi.GRBloadenv(env, log_file) | |
if error: | |
raise Exception("Error on GRBloadenv()") | |
return env | |
def gurobi_free(env): | |
gurobi.GRBfreeenv(env[0]) | |
if __name__ == "__main__": | |
env = gurobi_env() | |
class Edge: | |
def __init__(self, _id, cost): | |
self._id = _id | |
self.cost = cost | |
def get_id(self): | |
return self._id | |
var_id = lambda i: "var:{}".format(i) | |
variables = [Edge(var_id(i), (i+1)*10) for i in range(1)] | |
model = new_model(env, "MyModel", variables) | |
update(model) | |
add_constraint(env[0], model, [0], [10], 60, "source1") | |
add_constraint(env[0], model, [0], [10], 60, "sink1") | |
model_optimize(model) | |
gurobi_free(env) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment