1/* BEGIN LICENSE BLOCK
2 * Version: CMPL 1.1
3 *
4 * The contents of this file are subject to the Cisco-style Mozilla Public
5 * License Version 1.1 (the "License"); you may not use this file except
6 * in compliance with the License.  You may obtain a copy of the License
7 * at www.eclipse-clp.org/license.
8 *
9 * Software distributed under the License is distributed on an "AS IS"
10 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See
11 * the License for the specific language governing rights and limitations
12 * under the License.
13 *
14 * The Original Code is  The ECLiPSe/Gurobi Interface
15 * The Initial Developer of the Original Code is Joachim Schimpf
16 * Portions created by the Initial Developer are
17 * Copyright (C) 2012 Joachim Schimpf
18 *
19 * Contributor(s): Joachim Schimpf, Coninfer Ltd
20 *
21 * END LICENSE BLOCK */
22
23/*
24 * ECLiPSe/Gurobi interface (for inclusion in eplex.c)
25 */
26
27#include "gurobi_c.h"
28
29#define CPXENVptr			GRBenv*
30#define CPXLPptr			GRBmodel*
31
32typedef char* param_id_t;
33typedef int sostype_t;
34
35#include "eplex.h"	/* needs declarations above! */
36
37
38
39/*
40 * Capabilities
41 */
42#undef HAS_QUADRATIC
43#undef HAS_MIQP
44#define HAS_LIMITED_MIP_RESULTS
45#define SOLVER_HAS_LOCAL_PARAMETERS
46#define SOLVER_HAS_STR_PARAMS
47
48/*
49 * Constants
50 */
51#define SOLVER_SHORT_NAME	GRB
52#define SOLVER_ATOMIC_NAME	"gurobi"
53#define SOLVER_VERSION_INT	(100*GRB_VERSION_MAJOR+GRB_VERSION_MINOR)
54
55#define CPXPUBLIC
56
57#define CPX_INFBOUND		GRB_INFINITY
58
59#define SOLVER_MAT_BASE		0
60#define SOLVER_MAT_OFFSET	1
61
62#define SOLVER_SENSE_LE		'<'
63#define SOLVER_SENSE_GE		'>'
64#define SOLVER_SENSE_EQ		'='
65
66#define SOLVER_SOS_TYPE1	1
67#define SOLVER_SOS_TYPE2	2
68
69#define CPX_COL_AT_LOWER	GRB_NONBASIC_LOWER
70#define CPX_COL_AT_UPPER	GRB_NONBASIC_UPPER
71#define CPX_COL_BASIC		GBB_BASIC
72#define CPX_COL_FREE_SUPER	GRB_SUPERBASIC
73
74#define STRBUFFERSIZE		GRB_MAX_STRLEN
75
76/*
77 * Mappings for CPLEX-style functions
78 */
79#define CPXgetrhs(E,A1,A2,A3,A4)	GRBgetdblattrarray(A1,GRB_DBL_ATTR_RHS,A3,(A4)-(A3)+1,A2)
80#define CPXgetsense(E,A1,A2,A3,A4)	GRBgetcharattrarray(A1,GRB_CHAR_ATTR_SENSE,A3,(A4)-(A3)+1,A2)
81#define CPXgetlb(E,A1,A2,A3,A4)		GRBgetdblattrarray(A1,GRB_DBL_ATTR_LB,A3,(A4)-(A3)+1,A2)
82#define CPXgetub(E,A1,A2,A3,A4)		GRBgetdblattrarray(A1,GRB_DBL_ATTR_UB,A3,(A4)-(A3)+1,A2)
83#define CPXgetctype(E,A1,A2,A3,A4)	GRBgetcharattrarray(A1,GRB_CHAR_ATTR_VTYPE,A3,(A4)-(A3)+1,A2)
84#define CPXchgctype(E,A1,A2,A3,A4)	GRBsetcharattrlist(A1,GRB_CHAR_ATTR_VTYPE,A2,A3,A4)
85#define CPXchgbds(E,A1,A2,A3,A4,A5)	grb_chgbds(A1,A2,A3,A4,A5)
86#define CPXcopybase(E,A1,A2,A3)		grb_loadbasis(A1,A2,A3)
87#define CPXgetbase(E,A1,A2,A3)		grb_getbasis(A1,A2,A3)
88#define CPXgetmipobjval(E,A1,A2)	GRBgetdblattr(A1,GRB_DBL_ATTR_OBJVAL,A2)
89#define CPXgetobj(E,A1,A2,A3,A4)	GRBgetdblattrarray(A1,GRB_DBL_ATTR_OBJ,A3,(A4)-(A3)+1,A2)
90#define CPXchgobj(E,A1,A2,A3,A4)	GRBsetdblattrlist(A1,GRB_DBL_ATTR_OBJ,A2,A3,A4)
91/* branching directions ignored! */
92#define CPXcopyorder(E,A1,A2,A3,A4,A5)	GRBsetintattrlist(A1,GRB_INT_ATTR_BRANCHPRIORITY,A2,A3,A4)
93#define CPXchgqpcoef(E,A1,A2,A3,A4)	(-1)
94#define CPXchgrhs(E,A1,A2,A3,A4)	GRBsetdblattrlist(A1,GRB_DBL_ATTR_RHS,A2,A3,A4)
95#define CPXcloseCPLEX(E)		GRBfreeenv(*(E))
96/* CAUTION: gurobi could set types directly here */
97#define CPXaddcols(E,LP,NC,NNZ,OC,MB,MI,MV,LB,UB,CN) \
98	GRBaddvars(LP,NC,NNZ,MB,MI,MV,OC,LB,UB,NULL,CN)
99/* CAUTION: can only add rows, not columns, i.e. NC==0! */
100#define CPXaddrows(E,LP,NC,NR,NNZ,RHS,SEN,MB,MI,MV,CN,RN) \
101	GRBaddconstrs(LP,NR,NNZ,MB,MI,MV,SEN,RHS,CN)
102/* CAUTION: arrays must be large enough */
103#define CPXgetrows(E,A1,A2,A3,A4,A5,A6,A7,A8,A9) \
104	GRBgetconstrs(A1,A2,A3,A4,A5,A8,(A9)-(A8)+1)
105#define CPXchgobjsen(E,A1,A2) 		GRBsetintattr(A1,GRB_INT_ATTR_MODELSENSE,A2)
106#define CPXchgprobtype(A1, A2, A3)	0 /* 0 for success return code */
107#define CPXaddsos(E,LP,NS,NE,ST,SB,SI,SW,SN) GRBaddsos(LP,NS,NE,ST,SB,SI,SW)
108#define XPRSdelrows(A1,A2,A3)		GRBdelconstrs(A1,A2,A3)
109#define XPRSdelcols(A1,A2,A3)		GRBdelvars(A1,A2,A3)
110#define CPXchgname(E,A1,A2,A3,A4)	grb_setname(A1,A2,A3,A4)
111
112#define CPXisminimize(E,A1) 		(grb_getintattr(A1, GRB_INT_ATTR_MODELSENSE) == GRB_MINIMIZE)
113#define CPXgetnumnz(E,A1)		grb_getintattr(A1, GRB_INT_ATTR_NUMNZS)
114#define CPXgetnumint(E,A1)		grb_getintattr(A1, GRB_INT_ATTR_NUMINTVARS)
115#define CPXgetnumbin(E,A1)		grb_getintattr(A1, GRB_INT_ATTR_NUMBINVARS)
116#define CPXgetnumqpnz(E,A1)		grb_getintattr(A1, GRB_INT_ATTR_NUMQNZS)
117
118#define CPXupdatemodel(LP)		GRBupdatemodel(LP)
119
120/*
121 * Other operations
122 */
123#define SetPreSolve(state)
124
125#define Get_Int_Param(E,L,A1,A2) 	GRBgetintparam((L)?GRBgetenv((L)->lp):(E),A1,A2)
126#define Get_Dbl_Param(E,L,A1,A2)	GRBgetdblparam((L)?GRBgetenv((L)->lp):(E),A1,A2)
127#define Get_Str_Param(E,L,A1,A2)	GRBgetstrparam((L)?GRBgetenv((L)->lp):(E),A1,A2)
128#define Set_Int_Param(E,L,A1,A2) 	GRBsetintparam((L)?GRBgetenv((L)->lp):(E),A1,A2)
129#define Set_Dbl_Param(E,L,A1,A2)	GRBsetdblparam((L)?GRBgetenv((L)->lp):(E),A1,A2)
130#define Set_Str_Param(E,L,A1,A2)	GRBsetstrparam((L)?GRBgetenv((L)->lp):(E),A1,A2)
131
132#define Get_LP_Objval(A1,A2)		GRBgetdblattr((A1)->lp,GRB_DBL_ATTR_OBJVAL,A2)
133#define Get_Best_Objbound(A1, A2)	GRBgetdblattr(A1,GRB_DBL_ATTR_OBJBOUND,A2)
134#define Get_Feasibility_Tolerance(E,L,T) GRBgetdblparam(E,GRB_DBL_PAR_FEASIBILITYTOL,T)
135
136#define Report_Error(Msg) \
137	(void) ec_outfs(solver_streams[ErrType], "Gurobi error: "); \
138	(void) ec_outfs(solver_streams[ErrType], Msg); \
139	(void) ec_newline(solver_streams[ErrType]);
140
141#define Report_Solver_Error(E)		Report_Error(GRBgeterrormsg(E))
142