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 Constraint Logic Programming System.
15 * The Initial Developer of the Original Code is  Cisco Systems, Inc.
16 * Portions created by the Initial Developer are
17 * Copyright (C) 1995-2012 Cisco Systems, Inc.  All Rights Reserved.
18 *
19 * Contributor(s): Joachim Schimpf, Kish Shen and Andrew Eremin, IC-Parc
20 *
21 * END LICENSE BLOCK */
22
23/*
24 * ECLiPSe/XPRESSMP interface (for inclusion in eplex.c)
25 */
26
27#include "xprs.h"
28
29#define CPXLPptr		XPRSprob /* prob. pointer 13+ only! */
30#define CPXENVptr		XPRSprob /* 'default' problem */
31
32#define SOLVE_MIP_COPY
33
34typedef int param_id_t;
35typedef char sostype_t;
36
37#include "eplex.h"		/* needs declarations above! */
38
39
40# define SOLVER_SHORT_NAME XPRS
41# define SOLVER_ATOMIC_NAME "xpress"
42# define SOLVER_VERSION_INT XPRESS
43# define XP_PROBNAME_MAX 200  /* maximum length of problem name */
44# define HAS_QUADRATIC
45# define HAS_MIQP
46# define SOLVER_HAS_STR_PARAMS /* has string parameters */
47# define STRBUFFERSIZE  256  /* string parameter buffer size (256 used in example)*/
48/* copying a problem with zeroed quad. coeff. can lead to core dumps */
49# define HAS_MIQP_FIXEDCOPYBUG
50# define HAS_INTLB_BUG /* LB lost when converting col to int type */
51# if XPRESS <= 14
52#  define HAS_MIQP_CALLBACKBUG /* callback to get MIQP solution core dumps */
53#  define HAS_SAMEBOUNDSBUG /* sol. value = 0 if both bounds set to same */
54# endif
55# define SOLVER_HAS_LOCAL_PARAMETERS
56# if XPRESS >= 14      /* need to constrain integer range...*/
57#  define HAS_NARROW_INT_RANGE
58#  ifndef XPRS_MAXINT  /* in case we are using an old xprs.h file */
59#   define XPRS_MAXINT         2147483647
60#  endif
61# endif
62# if XPRESS >= 15
63#  define HAS_POSTSOLVE
64/* XPRSpostsolve is not documented and not declared in xprs.h */
65int XPRS_CC XPRSpostsolve(XPRSprob prob);
66# endif
67# if XPRESS < 20
68#define HAS_NO_ADDSOS
69# endif
70
71# ifndef XPRESSMINOR
72#  define XPRESSMINOR 0
73# endif
74
75# ifdef __STDC__
76#  define __ANSIC_	/* used in xpresso.h */
77# endif
78
79# define XP_GLSTAT_OFFSET 0x10
80
81# define SOLVER_MAT_BASE   0
82# define SOLVER_MAT_OFFSET 1
83
84#define SOLVER_SENSE_LE	'L'
85#define SOLVER_SENSE_GE	'G'
86#define SOLVER_SENSE_EQ	'E'
87
88#define SOLVER_SOS_TYPE1	'1'
89#define SOLVER_SOS_TYPE2	'2'
90
91# define CPX_INFBOUND			XPRS_PLUSINFINITY
92# define CPX_COL_AT_LOWER               0
93# define CPX_COL_BASIC                  1
94# define CPX_COL_AT_UPPER               2
95# define CPX_COL_FREE_SUPER             3
96# define CPX_COL_NONBASIC_ZERO_BOUNDED	CPX_COL_AT_LOWER
97# define CPX_COL_NONBASIC_ZERO_UNBOUNDED CPX_COL_FREE_SUPER
98# define CPXgetrhs(E,A1,A2,A3,A4)	XPRSgetrhs(A1,A2,A3,A4)
99# define CPXgetsense(E,A1,A2,A3,A4)	XPRSgetrowtype(A1,A2,A3,A4)
100# define CPXgetlb(E,A1,A2,A3,A4)	XPRSgetlb(A1,A2,A3,A4)
101# define CPXgetub(E,A1,A2,A3,A4)	XPRSgetub(A1,A2,A3,A4)
102# define CPXgetctype(E,A1,A2,A3,A4)	XPRSgetcoltype(A1,A2,A3,A4)
103# define CPXchgctype(E,A1,A2,A3,A4)	XPRSchgcoltype(A1,A2,A3,A4)
104# define CPXchgbds(E,A1,A2,A3,A4,A5)	XPRSchgbounds(A1,A2,A3,A4,A5)
105# define CPXcopybase(E,A1,A2,A3)	XPRSloadbasis(A1,A3,A2) /* args swapped! */
106# define CPXgetbase(E,A1,A2,A3)		XPRSgetbasis(A1,A3,A2) /* args swapped! */
107# define Get_LP_Objval(A1,A2)		XPRSgetdblattrib((A1)->lpcopy,XPRS_LPOBJVAL,A2)
108# define Get_Best_Objbound(A1, A2)      XPRSgetdblattrib(A1,XPRS_BESTBOUND,A2)
109# define CPXgetmipobjval(E,A1,A2)	XPRSgetdblattrib(A1,XPRS_MIPOBJVAL,A2)
110# define CPXgetobj(E,A1,A2,A3,A4)	XPRSgetobj(A1,A2,A3,A4)
111# define CPXchgobj(E,A1,A2,A3,A4)	XPRSchgobj(A1,A2,A3,A4)
112# define CPXcopyorder(E,A1,A2,A3,A4,A5)	XPRSloaddirs(A1,A2,A3,A4,A5,NULL,NULL)
113# define CPXchgqpcoef(E,A1,A2,A3,A4)	XPRSchgqobj(A1,A2,A3,A4)
114# define CPXchgrhs(E,A1,A2,A3,A4)       XPRSchgrhs(A1,A2,A3,A4)
115# define CPXcloseCPLEX(E)		XPRSfree()
116# define CPXaddcols(E,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10) \
117          XPRSaddcols(A1,A2,A3,A4,A5,A6,A7,A8,A9) /* diff args! */
118# define CPXaddrows(E,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11) \
119          XPRSaddrows(A1,A3,A4,A6,A5,NULL,A7,A8,A9) /* diff args! */
120# define CPXaddsos(E,LP,NS,NE,ST,SB,SI,SW,SN) XPRSaddsets(LP,NS,NE,ST,SB,SI,SW)
121# define CPXgetrows(E,A1,A2,A3,A4,A5,A6,A7,A8,A9) \
122          XPRSgetrows(A1,A3,A4,A5,A6,A2,A8,A9) /* diff args! */
123# define CPXchgobjsen(E,A1,A2) 		0
124# define CPXchgprobtype(A1, A2, A3)     0 /* 0 for success return code */
125# define CPXupdatemodel(LP)
126
127# define CPXgetnumnz(E,A1)		xprs_getintattr(A1, XPRS_ELEMS)
128# define CPXgetnumint(E,A1)		xprs_getintattr(A1, XPRS_MIPENTS)
129# define CPXgetnumbin(E,A1)		0
130# define CPXgetnumqpnz(E,A1)		xprs_getintattr(A1, XPRS_QELEMS)
131
132# define SUPPORT_IIS
133# define Find_Conflict(Err, L, NRows, NCols) { \
134	Err = XPRSiis(L, ""); \
135        if (!Err) Err = XPRSgetiis(L, &(NCols), &(NRows), NULL, NULL); \
136}
137
138# define Get_Conflict(L, Status, RowIdxs, RowStat, Nrows_p, ColIdxs, ColStat, Ncols_p)  \
139	Status = XPRSgetiis(L, Ncols_p, Nrows_p,  ColIdxs, RowIdxs)
140
141# define Get_Feasibility_Tolerance(E,L,T) XPRSgetdblcontrol((L)->lp, XPRS_FEASTOL, T)
142
143# define Get_Int_Param(E,L,A1,A2) \
144   ((L) == NULL ? XPRSgetintcontrol(E,A1,A2) : XPRSgetintcontrol((L)->lp,A1,A2))
145# define Get_Dbl_Param(E,L,A1,A2) \
146   ((L) == NULL ? XPRSgetdblcontrol(E,A1,A2) : XPRSgetdblcontrol((L)->lp,A1,A2))
147# define Get_Str_Param(E,L,A1,A2) \
148   ((L) == NULL ? XPRSgetstrcontrol(E,A1,A2) : XPRSgetstrcontrol((L)->lp,A1,A2))
149# define Set_Int_Param(E,L,A1,A2) \
150   ((L) == NULL ? XPRSsetintcontrol(E,A1,A2) : XPRSsetintcontrol((L)->lp,A1,A2))
151# define Set_Dbl_Param(E,L,A1,A2) \
152   ((L) == NULL ? XPRSsetdblcontrol(E,A1,A2) : XPRSsetdblcontrol((L)->lp,A1,A2))
153# define Set_Str_Param(E,L,A1,A2) \
154   ((L) == NULL ? XPRSsetstrcontrol(E,A1,A2) : XPRSsetstrcontrol((L)->lp,A1,A2))
155# define Get_MIPCutOff(d, v) XPRSgetdblcontrol((d)->lpcopy, XPRS_MIPABSCUTOFF, v)
156# define Get_Dual_Infeas(lp, v) XPRSgetintattrib(lp, XPRS_DUALINFEAS, v)
157# define Get_Primal_Infeas(lp, v) XPRSgetintattrib(lp, XPRS_PRIMALINFEAS, v)
158
159# define SetPreSolve(state)
160
161#ifdef XPRESS_OEM_ICPARC_2002
162# include "xprsoem.h"
163#endif
164
165
166# define Get_Xp_Stat(lpd) \
167	if (IsMIPProb(lpd->prob_type)) { \
168	    (void) XPRSgetintattrib(lpd->lpcopy, XPRS_MIPSTATUS, &lpd->sol_state); \
169	    if (lpd->sol_state == XPRS_MIP_LP_NOT_OPTIMAL || \
170               lpd->sol_state == XPRS_MIP_LP_OPTIMAL) \
171		(void) XPRSgetintattrib(lpd->lpcopy, XPRS_LPSTATUS, &lpd->sol_state); \
172	    else \
173		lpd->sol_state += XP_GLSTAT_OFFSET; \
174	} else if (lpd->prob_type == PROBLEM_FIXEDL || lpd->prob_type == PROBLEM_FIXEDQ) { \
175        /* fixglobal only performed if MIP was optimal */ \
176            (void) XPRSgetintattrib(lpd->lpcopy, XPRS_MIPSTATUS, &lpd->sol_state); \
177            if (lpd->sol_state == XPRS_MIP_OPTIMAL) \
178               (void) XPRSgetintattrib(lpd->lpcopy, XPRS_LPSTATUS, &lpd->sol_state); \
179            else \
180            { \
181	       if (lpd->sol_state == XPRS_MIP_LP_NOT_OPTIMAL || \
182                  lpd->sol_state == XPRS_MIP_LP_OPTIMAL) \
183		  (void) XPRSgetintattrib(lpd->lpcopy, XPRS_LPSTATUS, &lpd->sol_state); \
184	       else \
185		  lpd->sol_state += XP_GLSTAT_OFFSET; \
186            } \
187        } else if (lpd->prob_type == PROBLEM_RELAXEDL || lpd->prob_type == PROBLEM_RELAXEDQ) \
188        { \
189	    (void) XPRSgetintattrib(lpd->lpcopy, XPRS_LPSTATUS, &lpd->sol_state); \
190        } \
191	else \
192        { \
193	    (void) XPRSgetintattrib(lpd->lp, XPRS_LPSTATUS, &lpd->sol_state); \
194	}
195
196
197
198# define SuccessState(d)	( \
199	(d)->sol_state == XP_GLSTAT_OFFSET + XPRS_MIP_OPTIMAL || \
200	(d)->sol_state == XPRS_LP_OPTIMAL )
201/* the LP_CUTOFF* LPSTATUS happens only with MIP search, and as we access
202   LPSTATUS for MIP search only if the MIP search is stopped at the root,
203   we know that these states means that a cutoff occurred at the root node,
204   and that the MIP optimal solution cannot be better than the cutoff, and
205   this is considered to be a failure state
206*/
207# define FailState(d) ( \
208	(d)->sol_state == XP_GLSTAT_OFFSET + XPRS_MIP_INFEAS || \
209	(d)->sol_state == XPRS_LP_INFEAS || \
210	(d)->sol_state == XPRS_LP_CUTOFF || \
211	(d)->sol_state == XPRS_LP_CUTOFF_IN_DUAL)
212/* catches the MIP cases only */
213# define MIPSemiFailState(d) ( \
214	(d)->sol_state == XP_GLSTAT_OFFSET + XPRS_MIP_NO_SOL_FOUND)
215/* catches the MIP cases only */
216# define MIPSemiSuccessState(d) ( \
217	(d)->sol_state == XP_GLSTAT_OFFSET + XPRS_MIP_SOLUTION)
218/* An aborted LP can be either semi-fail or semi-success */
219# define LPAbortedState(d) ( \
220        (d)->sol_state == XPRS_LP_UNFINISHED )
221# define MaybeFailState(d) (0)
222# define UnboundedState(d) ( \
223	(d)->sol_state == XPRS_LP_UNBOUNDED )
224
225# define DualMethod(lpd,m,am) 0
226
227# define UsingBarrierNoCrossOver(d) (meth->meth == METHOD_BAR && meth->auxmeth == METHOD_NONE)
228# define Get_Bar_Primal_Obj(d, obj) XPRSgetdblattrib((d), XPRS_BARPRIMALOBJ, obj)
229# define Get_Bar_Dual_Obj(d, obj) XPRSgetdblattrib((d), XPRS_BARDUALOBJ, obj)
230# define Bar_Is_Primal_Feasible(lpd) \
231	(XPRSgetdblattrib(lpd->lp, XPRS_BARPRIMALINF, &infeas), infeas < 1e-6)
232# define Bar_Is_Dual_Feasible(lpd) \
233	(XPRSgetdblattrib(lpd->lp, XPRS_BARDUALINF, &infeas), infeas < 1e-6)
234
235
236