1212795Sdim/* BEGIN LICENSE BLOCK
2212795Sdim * Version: CMPL 1.1
3212795Sdim *
4212795Sdim * The contents of this file are subject to the Cisco-style Mozilla Public
5212795Sdim * License Version 1.1 (the "License"); you may not use this file except
6212795Sdim * in compliance with the License.  You may obtain a copy of the License
7212795Sdim * at www.eclipse-clp.org/license.
8212795Sdim *
9212795Sdim * Software distributed under the License is distributed on an "AS IS"
10212795Sdim * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See
11212795Sdim * the License for the specific language governing rights and limitations
12212795Sdim * under the License.
13212795Sdim *
14212795Sdim * The Original Code is  The ECLiPSe Constraint Logic Programming System.
15212795Sdim * The Initial Developer of the Original Code is  Cisco Systems, Inc.
16212795Sdim * Portions created by the Initial Developer are
17212795Sdim * Copyright (C) 1995-2012 Cisco Systems, Inc.  All Rights Reserved.
18212795Sdim *
19212795Sdim * Contributor(s): Joachim Schimpf, Kish Shen and Andrew Eremin, IC-Parc
20212795Sdim *
21212795Sdim * END LICENSE BLOCK */
22226633Sdim
23212795Sdim/*
24212795Sdim * ECLiPSe/XPRESSMP interface (for inclusion in eplex.c)
25212795Sdim */
26212795Sdim
27212795Sdim#include "xprs.h"
28212795Sdim
29212795Sdim#define CPXLPptr		XPRSprob /* prob. pointer 13+ only! */
30212795Sdim#define CPXENVptr		XPRSprob /* 'default' problem */
31212795Sdim
32212795Sdim#define SOLVE_MIP_COPY
33212795Sdim
34212795Sdimtypedef int param_id_t;
35212795Sdimtypedef char sostype_t;
36212795Sdim
37212795Sdim#include "eplex.h"		/* needs declarations above! */
38212795Sdim
39212795Sdim
40212795Sdim# define SOLVER_SHORT_NAME XPRS
41212795Sdim# define SOLVER_ATOMIC_NAME "xpress"
42212795Sdim# define SOLVER_VERSION_INT XPRESS
43212795Sdim# define XP_PROBNAME_MAX 200  /* maximum length of problem name */
44212795Sdim# define HAS_QUADRATIC
45212795Sdim# define HAS_MIQP
46212795Sdim# define SOLVER_HAS_STR_PARAMS /* has string parameters */
47212795Sdim# define STRBUFFERSIZE  256  /* string parameter buffer size (256 used in example)*/
48212795Sdim/* copying a problem with zeroed quad. coeff. can lead to core dumps */
49212795Sdim# define HAS_MIQP_FIXEDCOPYBUG
50212795Sdim# define HAS_INTLB_BUG /* LB lost when converting col to int type */
51212795Sdim# if XPRESS <= 14
52212795Sdim#  define HAS_MIQP_CALLBACKBUG /* callback to get MIQP solution core dumps */
53249423Sdim#  define HAS_SAMEBOUNDSBUG /* sol. value = 0 if both bounds set to same */
54221345Sdim# endif
55218893Sdim# define SOLVER_HAS_LOCAL_PARAMETERS
56218893Sdim# if XPRESS >= 14      /* need to constrain integer range...*/
57221345Sdim#  define HAS_NARROW_INT_RANGE
58218893Sdim#  ifndef XPRS_MAXINT  /* in case we are using an old xprs.h file */
59218893Sdim#   define XPRS_MAXINT         2147483647
60218893Sdim#  endif
61218893Sdim# endif
62212795Sdim# if XPRESS >= 15
63218893Sdim#  define HAS_POSTSOLVE
64218893Sdim/* XPRSpostsolve is not documented and not declared in xprs.h */
65212795Sdimint XPRS_CC XPRSpostsolve(XPRSprob prob);
66212795Sdim# endif
67212795Sdim# if XPRESS < 20
68212795Sdim#define HAS_NO_ADDSOS
69212795Sdim# endif
70212795Sdim
71212795Sdim# ifndef XPRESSMINOR
72212795Sdim#  define XPRESSMINOR 0
73212795Sdim# endif
74212795Sdim
75212795Sdim# ifdef __STDC__
76212795Sdim#  define __ANSIC_	/* used in xpresso.h */
77212795Sdim# endif
78212795Sdim
79212795Sdim# define XP_GLSTAT_OFFSET 0x10
80212795Sdim
81212795Sdim# define SOLVER_MAT_BASE   0
82212795Sdim# define SOLVER_MAT_OFFSET 1
83212795Sdim
84212795Sdim#define SOLVER_SENSE_LE	'L'
85212795Sdim#define SOLVER_SENSE_GE	'G'
86212795Sdim#define SOLVER_SENSE_EQ	'E'
87212795Sdim
88212795Sdim#define SOLVER_SOS_TYPE1	'1'
89212795Sdim#define SOLVER_SOS_TYPE2	'2'
90212795Sdim
91212795Sdim# 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