/*___________________________________________________________________________*/ /* IBM Optimization Solutions and Library Optimization Library */ /* oslc.h - OSL C header file for character control variables */ /* (c) IBM Corp, 1990,1997 All rights reserved. */ /* */ /* US Government Users Restricted Rights - Use, duplication, or disclosure */ /* restricted by GAS ADP Schedule Contract with IBM Corp. */ /*___________________________________________________________________________*/ #define OSLCLN 17 /* no. of character control variables */ static char oslc[OSLCLN*80]; /* array for char. control variables */ #define CNAME oslc[0*80] /* problem name in the MPS file */ #define COBJECTIVE oslc[1*80] /* objective function row name in the MPS file */ #define CRHS oslc[2*80] /* the RHS name in the MPS file */ #define CRANGE oslc[3*80] /* the range name in the MPS file */ #define CBOUND oslc[4*80] /* the bound name in the MPS file */ #define CBASIS oslc[5*80] /* the basis name in the MPS file */ #define CCHANGEOBJ oslc[6*80] /* the name of cost (objective) change row in the MPS file to be used by ekkspar */ #define CCHANGERHS oslc[7*80] /* the name of RHS change in the MPS file to be used by ekkspar */ #define CCHANGERANGE oslc[8*80] /* the name of range change in the MPS file to be used by ekkspar */ #define CCHANGEBOUNDS oslc[9*80] /* the name of bounds change in the MPS file to be used by ekkspar */ #define CSSOLUTION oslc[10*80] /* the name of the spreadsheet range(s) containing the adjustable cells */ #define CSCONSTRTS oslc[11*80] /* the name of the spreadsheet range(s) containing the constraint cells */ #define CSOBJECTIVE oslc[12*80] /* the name of the spreadsheet range containing the objective cell */ #define CSEKKSOS1 oslc[13*80] /* the name of the spreadsheet range(s) containing SOS sets of type 1 */ #define CSEKKSOS2 oslc[14*80] /* the name of the spreadsheet range(s) containing SOS sets of type 2 */ #define CSEKKSOS3 oslc[15*80] /* the name of the spreadsheet range(s) containing SOS sets of type 3 */ #define CSEKKSOS4 oslc[16*80] /* the name of the spreadsheet range(s) containing SOS sets of type 4 (gen. int. variables) */
/*___________________________________________________________________________*/ /* IBM Optimization Solutions and Library Optimization Library */ /* osli.h - OSL C header file for integer control variables */ /* (c) IBM Corp, 1990,1997 All rights reserved. */ /* */ /* US Government Users Restricted Rights - Use, duplication, or disclosure */ /* restricted by GAS ADP Schedule Contract with IBM Corp. */ /*___________________________________________________________________________*/ #define OSLILN 71 /* number of integer control variables */ static long osli[OSLILN]; /* array for integer control variables */ #define ILOGFREQ osli[0] /* the log frequency */ #define IPRINTUNIT osli[1] /* unit number where output is directed */ #define IMAXFACTOR osli[2] /* max no. of iter. between refact. */ #define IITERNUM osli[3] /* number of iterations OSL has performed */ #define IMAXITER osli[4] /* max no. of iterations OSL will perform */ #define ILOGLEVEL osli[5] /* Amount of detail for the simplex log */ #define IONEOBJ osli[6] /* One objective function (type N row) flag for MPS files */ #define IQPARNUMITER osli[7] /* the number of the current ekkqpar parametric adjustment. */ #define IMAXROWS osli[8] /* max no. of rows allowed in the matrix */ #define IMAXCOLS osli[9] /* max no. of columns allowed in matrix */ #define INUMCHAR osli[10] /* number of characters in the names of the MPS fields */ #define ISTOPMASK osli[11] /* bit mask for stopping conditions. */ #define IMAXITERB osli[12] /* maximum number of iterations of the interior-point barrier algorithm */ #define IADJACTYPE osli[13] /* formation of the adjacency matrix */ #define IFORMNTYPE osli[14] /* formation of the normal matrix */ #define IDENSECOL osli[15] /* dense column threshold */ #define IDEVEXMODE osli[16] /* type of Devex pricing to be used */ #define INULLCHECK osli[17] /* null space checking switch */ #define IDROPROWCT osli[18] /* constraint dropping threshold */ #define IITERUFREQ osli[19] /* the frequency which ekkitru is called */ #define IPOSSBASIS osli[20] /* the potential basis flag */ #define IMAXPROJNS osli[21] /* the maximum null space projections */ #define INUMELS osli[22] /* no. of elem. in the last created block */ #define INUMBLOCKS osli[23] /* the number of matrix blocks */ #define IMSGPOS osli[24] /* position of the message number on the output line */ #define IPAGELINES osli[25] /* the number of lines on the page */ #define INUMROWS osli[26] /* the number of rows in the matrix */ #define INUMCOLS osli[27] /* no. of structural variables in matrix */ #define INUMPINF osli[28] /* current no. of primal infeasibilities */ #define INUMDINF osli[29] /* current no. of dual infeasibilities */ #define IMODELMASK osli[30] /* bit mask that determines which parts of the matrix are written or read by ekkptmd or ekkgtmd */ #define IPRTINFOMASK osli[31] /* solution printing mask for ekkprts */ #define ISOLMASK osli[32] /* print matrix mask for ekkprts */ #define IPRTMTRXMASK osli[32] /* OSL Release 1 name for Isolmask */ #define IEXTRABLK osli[33] /* no. of elements in each spare block */ #define IQPARMAXITER osli[34] /* max no. of parametric adjustments that will be performed by ekkqpar */ #define ILINELEN osli[35] /* the length of the output line */ #define INUMNODES osli[36] /* the maximum node number created so far */ #define IINTMASK osli[37] /* amount of information printed in the ekkmslv log (bit mask) */ #define IFASTITS osli[38] /* the fast iteration switch */ #define IMAXNODES osli[39] /* maximum number of nodes to evaluate */ #define IMAXSOLS osli[40] /* maximum number of feasible integer solutions to find */ #define INUMSOLS osli[41] /* no. of integer solutions found so far */ #define INUMINTS osli[42] /* number of individual integer variables */ #define INUMSETS osli[43] /* the number of sets */ #define INUMUNSAT osli[44] /* number of integer variables at fractional values */ #define IVECTOR osli[45] /* IBM Vector Facility flag */ #define IPROBSTAT osli[46] /* the problem status */ #define IMAJORITS osli[47] /* max no. of decomposition iterations */ #define IPRINTSENS osli[48] /* sensitivity info. printing bit mask */ #define IMAXINTS osli[49] /* maximum number of integer variables */ #define IMAXSETS osli[50] /* the maximum number of sets */ #define ISTRATEGY osli[51] /* select various steps of the MIP alg. */ #define IMAXINTINFO osli[52] /* max amount of integer information */ #define ITHRESHOLD osli[53] /* no. of int. vars. that must be fixed for supernode processing to continue */ #define IHEURPASS osli[54] /* number of heuristic passes to be made by ekkmpre */ #define ISUPERTOL osli[55] /* no. of branches allowed inside a super node before supernode processing ends */ #define IROWORD osli[56] /* the row ordering method indicator */ #define IORDUNIT osli[57] /* row ordering read/write logical unit */ #define IMIPLENGTH osli[58] /* amount of extra info that is saved and restored by the subroutine ekknodu */ #define IITERBNUM osli[59] /* no. of iter. ekkbslv has performed */ #define IPRICETYPE osli[60] /* the type of pricing for ekknslv */ #define INUMCPU osli[61] /* no. of slave processes */ #define IPROBSTAT2 osli[62] /* a secondary problem status variable */ #define ISMDLTYPEMASK osli[63] /* the type of model read in by ekksmdl (bit mask) */ #define ITOTALCPU osli[64] /* total no. of processes */ #define IWHICHCPU osli[65] /* no. of this processor */ #define ISTRIPES osli[66] /* no. of stripes in Cholesky */ #define INUMELQ osli[68] /* no. of cols in quadratic matrix (col copy) or no. of elements in quadratic matrix (index copy) */ #define IORDTHRSH osli[69] /* threshold for matrix ordering */ #define ILPDCFLAG osli[70] /* set to a positive number to idicate the maximum number of blocks for ekklpdc */
/*___________________________________________________________________________*/ /* IBM Optimization Solutions and Library Optimization Library */ /* osln.h - OSL C header file for index control variables */ /* (c) IBM Corp, 1990,1997 All rights reserved. */ /* */ /* US Government Users Restricted Rights - Use, duplication, or disclosure */ /* restricted by GAS ADP Schedule Contract with IBM Corp. */ /*___________________________________________________________________________*/ #define OSLNLN 69 /* number of index control variables */ static long osln[OSLNLN]; /* array for index control variables */ #define NROWLOWER osln[0] /* index into dspace for the first element of row lower bounds */ #define NROWACTS osln[1] /* index into dspace for the first element of row activities */ #define NROWUPPER osln[2] /* index into dspace for the first element of row upper bounds */ #define NROWSLACKS osln[3] /* index into dspace for the first element of row slacks */ #define NROWDUALS osln[3] /* alternate name for NROWSLACKS */ #define NROWSTAT osln[4] /* index into mspace for the first element of the row status vector */ #define NCOLLOWER osln[5] /* index into dspace for the first element of column lower bounds */ #define NCOLSOL osln[6] /* index into dspace for the 1st element of the solution (column activities) */ #define NCOLUPPER osln[7] /* index into dspace for the 1st element of column upper bounds */ #define NCOLRCOSTS osln[8] /* index into dspace for the 1st element of reduced costs */ #define NCOLSTAT osln[9] /* index into mspace for the 1st element of the column status vector */ #define NOBJECTIVE osln[10] /* index into dspace for the 1st element of column costs (obj. func. coeff.) */ #define NROWNAMES osln[11] /* index into dspace for the 1st element of row names */ #define NCOLNAMES osln[12] /* index into dspace for the 1st element of column names */ #define NROWSCALES osln[13] /* index into dspace for the 1st element of row scale factors */ #define NCOLSCALES osln[14] /* index into dspace for the 1st element of column scale factors */ #define NPRESOLVE osln[15] /* index into mspace for the 1st element of the presolve region */ #define NROWCC osln[16] /* index into mspace for the 1st element of rows for matrix (column copy) */ #define NCOLRC osln[17] /* index into mspace for the 1st element of columns for matrix (row copy) */ #define NELEMCC osln[18] /* index into dspace for the 1st element of elements for matrix (column copy) */ #define NELEMRC osln[19] /* index into dspace for the 1st element of columns for matrix (row copy) */ #define NROWRC osln[20] /* index into mspace for the 1st element of row starts (row copy) */ #define NCOLCC osln[21] /* index into mspace for the 1st element of column starts (column copy) */ #define NFIRSTFREE osln[22] /* index into dspace of the 1st element of free space */ #define NLASTFREE osln[23] /* index into dspace of the last element of free space */ #define NBLOCKCOL osln[24] /* index into mspace for the 1st element of column entries for latest block */ #define NBLOCKROW osln[25] /* index into mspace for the 1st element of row entries for latest block */ #define NBLOCKELEM osln[26] /* index into dspace for the 1st element of elements for latest block */ #define NINTINFO osln[27] /* index into mspace for the 1st element of integer information */ #define NROWAUX osln[28] /* index into dspace for the 1st element of row auxiliary solve information */ #define NCOLAUX osln[29] /* index into dspace for the 1st element of row auxiliary solve information */ #define NSOBJUPC osln[30] /* index into dspace created by ekksobj for the first element of the array of cost upper limits */ #define NSOBJDNC osln[31] /* index into dspace created by ekksobj for the first element of the array of cost lower limits */ #define NSOBJUPV osln[32] /* index into dspace created by ekksobj for the first element of ranges of the objective function values corresp. to the upper limits on cost coefficients indexed by Nsobjupc */ #define NSOBJDNV osln[33] /* index into dspace created by ekksobj for the first element of ranges of the objective function values corresp. to the lower limits on cost coefficients indexed by Nsobjdnc */ #define NSOBJUPE osln[34] /* index into mspace created by ekksobj for the first element of the array of entering rows or columns corresp. to the increased cost coeffs. indexed by Nsobjupc */ #define NSOBJDNE osln[35] /* index into mspace created by ekksobj for the 1st element of the array of entering rows or columns corresponding to the decreased cost coefficients indexed by Nsobjdnc */ #define NSOBJUPL osln[36] /* index into mspace created by ekksobj for the 1st element of the array of leaving rows or columns corresponding to the increased cost coefficients indexed by Nsobjupc */ #define NSOBJDNL osln[37] /* index into mspace created by ekksobj for the 1st element of the array of leaving rows or columns corresp. to the decreased cost coefficients indexed by Nsobjdnc */ #define NSBNDCUPB osln[38] /* index into dspace created by ekksbnd for the first element of the upper limits on column bounds */ #define NSBNDCDNB osln[39] /* index into dspace created by ekksbnd for the first element of the lower limits on column bounds */ #define NSBNDCUPV osln[40] /* index into dspace created by ekksbnd for the 1st element of the ranges of the objective function values corresp. to the upper limits on column bounds indexed by Nsbndcupb */ #define NSBNDCDNV osln[41] /* index into dspace created by ekksbnd for the 1st element of ranges of the objective function values corresp. to the lower limits on column bounds indexed by Nsbndcdnb */ #define NSBNDCUPE osln[42] /* index into mspace created by ekksbnd for the 1st element of the array of entering rows or columns corresp. to the upper limits on column bounds indexed by Nsbndcupb */ #define NSBNDCDNE osln[43] /* index into mspace created by ekksbnd for the 1st element of the array of entering rows or columns corresp. to the lower limits on column bounds indexed by Nsbndcdnb */ #define NSBNDCUPL osln[44] /* index into mspace created by ekksbnd for the 1st element of the array of leaving rows or columns corresp. to the upper limits on column bounds indexed by Nsbndcupb */ #define NSBNDCDNL osln[45] /* index into mspace created by ekksbnd for the 1st element of the array of leaving rows or columns corresp. to the lower limits on column bounds indexed by Nsbndcdnb */ #define NSBNDRUPB osln[46] /* index into dspace created by ekksbnd for the 1st element of the upper limits on row bounds */ #define NSBNDRDNB osln[47] /* index into dspace created by ekksbnd for the first element of the lower limits on row bounds */ #define NSBNDRUPV osln[48] /* index into dspace created by ekksbnd for the 1st element of the ranges of the objective function values corresp. to the upper limits on row bounds indexed by Nsbndrupb */ #define NSBNDRDNV osln[49] /* index into dspace created by ekksbnd for the 1st element of ranges of the objective function values corresp. to the lower limits on row bounds indexed by Nsbndrdnb */ #define NSBNDRUPE osln[50] /* index into mspace created by ekksbnd for the first element of the array of entering rows or columns corresp. to the upper limits on row bounds indexed by Nsbndrupb */ #define NSBNDRDNE osln[51] /* index into mspace created by ekksbnd for the 1st element of the array of entering rows or columns corresp. to the lower limits on row bounds indexed by Nsbndrdnb */ #define NSBNDRUPL osln[52] /* index into mspace created by ekksbnd for the 1st element of the array of leaving rows or columns corresp. to the upper limits on row bounds indexed by Nsbndrupb */ #define NSBNDRDNL osln[53] /* index into mspace created by ekksbnd for the 1st element of the array of leaving rows or columns corresp. to the lower limits on row bounds indexed by Nsbndrdnb */ #define NSELLISTCOL osln[54] /* index into mspace for the column selection list */ #define NSELLISTROW osln[55] /* index into mspace for the row selection list */ #define NSPARCOST osln[56] /* index into dspace for the parametric cost (objective) change vector created for ekkspar */ #define NSPARRLO osln[57] /* index into dspace for the row lower bounds parametric change vector created for ekkspar */ #define NSPARRUP osln[58] /* index into dspace for the row upper bounds parametric change vector created for ekkspar */ #define NSPARCLO osln[59] /* index into dspace for the column lower bounds parametric change vector created for ekkspar */ #define NSPARCUP osln[60] /* index into dspace for the column upper bounds parametric change vector created for ekkspar */ #define NARCID osln[61] /* index into mspace for the 1st element of the indices of the arcs in the basis */ #define NLEVEL osln[62] /* index into mspace for the 1st element of the array of node levels */ #define NPARENT osln[63] /* index into mspace for the 1st element of the array of parent nodes */ #define NPREORDER osln[64] /* index into mspace for the 1st element of the preorder traversal array */ #define NREVPREORDER osln[65] /* index into mspace for the 1st element of the reverse preorder traversal array */ #define NQROW osln[66] /* index into mspace for the 1st element of rows for quad matrix (col copy) or index into mspace for the 1st element of row entries for quad matrix (index copy) */ #define NQCOL osln[67] /* index into mspace for the 1st element of column starts for quad matrix (col copy) or index into mspace for the 1st element of column entries for quad matrix (index copy) */ #define NQELEM osln[68] /* index into mspace for the 1st element of elements for quad matrix (col or index copy) */
/*___________________________________________________________________________*/ /* IBM Optimization Solutions and Library Optimization Library */ /* oslr.h - OSL C header file for real control variables */ /* (c) IBM Corp, 1990,1997 All rights reserved. */ /* */ /* US Government Users Restricted Rights - Use, duplication, or disclosure */ /* restricted by GAS ADP Schedule Contract with IBM Corp. */ /*___________________________________________________________________________*/ #define OSLRLN 47 /* number of real control variables */ double oslr[OSLRLN]; /* array for real control variables */ #define RTOLPINF oslr[0] /* allowed amount of primal infeasibi. */ #define RTOLDINF oslr[1] /* allowed amount of dual infeasibility */ #define RMAXMIN oslr[2] /* the weight of the linear objective */ #define RMUFACTOR oslr[3] /* the reduction factor for mu in the primal barrier algorithm */ #define RMULIMIT oslr[4] /* the lower limit for mu in the primal barrier algorithm */ #define RRGFACTOR oslr[5] /* the reduced gradient target reduction factor */ #define RRGLIMIT oslr[6] /* the reduced gradient limit for the primal barrier algorithm */ #define RFIXVAR1 oslr[7] /* tolerance for fixing variables in the barrier method when infeasible */ #define RFIXVAR2 oslr[8] /* the tolerance for fixing variables in the barrier method when feasible */ #define RCHOLABSTOL oslr[9] /* the absolute pivot tolerance for Cholesky factorization */ #define RCHOLTINYTOL oslr[10] /* the cut-off tolerance for Cholesky factorization */ #define RCHOLRELTOL oslr[10] /* OSL Release 1 name for RCHOLTINYTOL */ #define RMULINFAC oslr[11] /* the multiple of mu to add to the linear objective */ #define RPROJTOL oslr[12] /* the projection error tolerance */ #define RPWEIGHT oslr[13] /* the multiplier of the feasible objective that is used when the current soln. is primal infeasible */ #define RCHANGEWEIGHT oslr[14] /* the rate of change for Rpweight or Rdweight */ #define RBBCUTOFF oslr[15] /* the cutoff for the branch and bound */ #define RDWEIGHT oslr[16] /* the proportion of the feasible objective that is used when the current solution is dual infeasible */ #define ROBJVALUE oslr[17] /* the value of the objective function */ #define RSUMPINF oslr[18] /* sum of the primal infeasibilities */ #define RSUMDINF oslr[19] /* the sum of the dual infeasibilities */ #define RTOLMPS oslr[20] /* the zero tolerance for MPS data */ #define RDEGSCALE oslr[21] /* the scale factor for all degradation */ #define RBESTSOL oslr[22] /* best feas. int. soln. found so far */ #define RIWEIGHT oslr[23] /* weight for each int. infeasibility */ #define RIMPROVE oslr[24] /* the amount by which a new solution must be better */ #define RTARGET oslr[25] /* the value of the target solution */ #define RTOLINT oslr[26] /* the integer tolerance */ #define RBESTPOSS oslr[27] /* the best possible solution */ #define RBESTEST oslr[28] /* the best estimated solution */ #define RSTEPMULT oslr[29] /* the step-length multiplier for the primal barrier algorithm */ #define RMUINIT oslr[30] /* the initial value of mu for the primal barrier algorithm */ #define RDENSETHR oslr[31] /* the density threshold for Cholesky processing */ #define ROBJWEIGHT oslr[32] /* the weight given to true objective in primal composite phase 1 */ #define RLAMBDAVAL oslr[33] /* the value of the ekkqpar parametric parameter lambda */ #define RDCCUTOFF oslr[34] /* value of ekkqslv decomp. cutoff */ #define RDOBJVAL oslr[35] /* value of dual objective for ekkbslv */ #define RSLAMBDA oslr[36] /* value of ekkspar parameter lambda */ #define RSLAMBDALIM oslr[37] /* the limiting value for the ekkspar parameter lambda */ #define RSLAMBDADELTA oslr[38] /* the incrementing value for the ekkspar parameter lambda */ #define RTHRESHOLD oslr[39] /* the supernode processing threshold */ #define RPDGAPTOL oslr[40] /* the barrier method primal-dual gap tolerance */ #define RPDSTEPMULT oslr[41] /* the primal-dual barrier method step-length multiplier */ #define RPERTDIAG oslr[42] /* the diagonal perturbation for Cholesky factorization */ #define RNETSAMP oslr[43] /* the sample size for the ekknslv pricing algorithm */ #define RPRINTCPU oslr[44] /* switch to print CPU time used by OSL subroutines */ #define RREGGAMMA oslr[45] #define RREGDELTA oslr[46]
/* *********************************************************************** */ /* exitru */ /* By setting the user return code to 3, this user exit routine */ /* causes ekksslv to stop after the accumulated CPU time exceeds */ /* 1000 microseconds. The CPU clock is started after the first */ /* primal iteration and it is checked after each primal iteration. */ /* NOTE: ekkcput subroutine is available only in VS FORTRAN. */ /* *********************************************************************** */ #include#include "ekkc.h" #include "osli.h" int ekkitru(dspace, mspace, imode, istat) double *dspace; int *mspace, *imode, *istat; { static int rtcod; static double start, elapsed, current; /* Function Body */ if (*imode != 1) { goto L100; } ekkiget(&rtcod, dspace, osli, OSLILN); /* CPUTIME subroutine is available only with VS FORTRAN. */ /* User should check rtcod here to make sure the timing is correct. */ if (IITERNUM == 1) { ekkcput(&start, &rtcod); } else { ekkcput(¤t, &rtcod); elapsed = current - start; if (elapsed > 1e3) { ekkprts(&rtcod, dspace); ekkbaso(&rtcod, dspace, 35, 1); *istat = 3; } } L100: return 0; } /* ekkitru */
/* *********************************************************************** */ /* exitru */ /* By setting the user return code to 3, this user exit routine */ /* causes ekksslv to stop after the accumulated CPU time exceeds */ /* 1000 microseconds. The CPU clock is started after the first */ /* primal iteration and it is checked after each primal iteration. */ /* NOTE: ekkcput subroutine is available only in VS FORTRAN. */ /* *********************************************************************** */ #include#include "ekkc.h" #include "osli.h" int ekkitru(dspace, mspace, imode, istat) double *dspace; int *mspace, *imode, *istat; { static int rtcod; static double start, elapsed, current; /* Function Body */ if (*imode != 1) { goto L100; } ekkiget(&rtcod, dspace, osli, OSLILN); /* CPUTIME subroutine is available only with VS FORTRAN. */ /* User should check rtcod here to make sure the timing is correct. */ if (IITERNUM == 1) { ekkcput(&start, &rtcod); } else { ekkcput(¤t, &rtcod); elapsed = current - start; if (elapsed > 1e3) { ekkprts(&rtcod, dspace); ekkbaso(&rtcod, dspace, 35, 1); *istat = 3; } } L100: return 0; } /* ekkitru */
/* *********************************************************************** */ /* This user exit routine will maintain a queue of messages. */ /* *********************************************************************** */ /* Queue of message numbers: msgqnum[] */ /* Array to hold real, integer, and character values that are */ /* printed in the message: msgqrl[], msgqin[], msgqch[]. */ /* Vectors to hold number of elements in each column of */ /* msgqrl[], msgqin[], msgqch[]: msgqnrl[], msgqnin[], msgqnch[]. */ /* Structure msgque containing message queue data. */ struct { double msgqrl[100] /* was [25][4] */; int msgqnum[4], msgqin[100] /* was [25][4] */, msgqnrl[4], msgqnin[4], msgqnch[4], msgqptr; char msgqch[12800] /* was [25][4] */; } MSGQUE; #define msgque_1 MSGQUE int ekkmsgu(dspace, mspace, strtnum, nreal, rvec, nint, ivec, nchar, cvec, cvec_len) double *dspace; int *mspace, *strtnum, *nreal; double *rvec; int *nint, *ivec, *nchar; char *cvec; int cvec_len; { /* Local variables */ static int j; /* Save message number. */ /* Parameter adjustments */ cvec -= 128; /* Function Body */ msgque_1.msgqnum[msgque_1.msgqptr - 1] = *strtnum; /* Save real values. */ msgque_1.msgqnrl[msgque_1.msgqptr - 1] = *nreal; for (j = 1; j <= *nreal; ++j) { msgque_1.msgqrl[j + msgque_1.msgqptr * 25 - 26] = rvec[j-1]; } /* Save integer values. */ msgque_1.msgqnin[msgque_1.msgqptr - 1] = *nint; for (j = 1; j <= *nint; ++j) { msgque_1.msgqin[j + msgque_1.msgqptr * 25 - 26] = ivec[j-1]; } /* Save character values. */ msgque_1.msgqnch[msgque_1.msgqptr - 1] = *nchar; for (j = 1; j <= *nchar; ++j) { strncpy(msgque_1.msgqch + (j + msgque_1.msgqptr * 25 - 26 << 7), cvec + (j << 7), 128); } /* Update queue pointer. */ msgque_1.msgqptr = msgque_1.msgqptr % 4 + 1; return 0; } /* ekkmsgu */
You can run this program using "Sample Linear Programming Model Data 1".
/* *********************************************************************** */ /* exbrnu */ /* This user exit routine modifies the default choice of the */ /* branching variable. */ /* ireasn is the situation when ekkbrnu is called, where: */ /* ireasn=1: subroutine is being called before any set is processed; */ /* marray and darray are not used. */ /* =2: subroutine is being called before processing each set; */ /* only set number, type of set, priority, and number in set */ /* are valid in marray and darray. */ /* =3: subroutine is being called after processing each */ /* variable in the set; all of marray and darray are valid */ /* and you may change pseudocosts (takes effect on the next */ /* branch). */ /* =4: subroutine is being called after processing each set; */ /* all of marray and darray are valid and the user may */ /* change variable number and priority (takes effect on */ /* next branch). */ /* =5: subroutine is being called after processing all sets; */ /* all of marray and darray are valid and the set number in */ /* OSL's chosen set, which you may now change. */ /* marray[0]: set number being processed. */ /* marray[1]: type of set being processed. */ /* marray[2]: priority (1 is highest). */ /* marray[3]: number of variables in the set */ /* marray[4]: variable column number of the current variable. */ /* marray[5]: direction of the branching. */ /* darray[0]: current value of variable in continuous solution. */ /* darray[1]: down pseudocost. */ /* darray[2]: up pseudocost for single variables. */ /* For sets it is the reference row entry. */ /* darray[3]: estimated degradation for the down branch. */ /* darray[4]: estimated degradation for the up branch. */ /* NOTE THIS SAMPLE USER EXIT IS NOT VALID FOR MIP PROBLEMS WITH SOS */ /* *********************************************************************** */ #include#include "ekkc.h" #include "osli.h" #include int ekkbrnu(dspace, mspace, ireasn, marray, darray, jrtcod) double *dspace; long *mspace, *ireasn, *marray; double *darray; long *jrtcod; { static long m2, rtcod; static long iseq, iset, if9; static double dval, dbest, dbest2; double diff; /* Function Body */ m2 = marray[1]; if (m2 == 1 || m2 == 2 || m2 == 3) { printf("\n THIS EKKBRNU NOT FOR SOS"); printf("\n STOPPING YOUR APPLICATION NOW"); } switch ((int)*ireasn) { case 1: goto L1000; case 2: goto L2000; case 3: goto L3000; case 4: goto L4000; case 5: goto L5000; } /* Initialization */ /* Using 0.499999 so that variables at 0.0 will be skipped */ L1000: dbest = .499999; dbest2 = 0.; iseq = 0; iset = 0; if9 = 0; ekkiget(&rtcod, dspace, osli, OSLILN); printf("\n There are %d sets.\n",INUMSETS); goto L6000; /* Before Set */ L2000: printf("\n Set number %d %d %d %d\n",marray[0], marray[1],marray[2],marray[3]); /* Set return code to force ekkbrnu calls. */ *jrtcod = 0; goto L6000; /* In Set */ /* Choose variable closest to 1.0 or to 0.5 if none above .9. */ L3000: if (darray[0] >= .9) { if (darray[0] > 1.000005) { printf("\n THIS EKKBRNU NOT FOR GENERAL INTEGER VARIABLES"); printf("\n STOPPING YOUR APPLICATION NOW"); } if (darray[0] > dbest2 && darray[0] <= .99999) { iseq = marray[4]; dbest2 = darray[0]; dval = darray[0]; /* Branch up. */ marray[5] = 1; iset = marray[0]; if9 = 1; } } else if ((diff = darray[0] - .5, fabs(diff)) < dbest && if9 == 0) { iseq = marray[4]; dbest = (diff = darray[0] - .5, fabs(diff)); dval = darray[0]; /* Branch up. */ marray[5] = 1; iset = marray[0]; } goto L6000; /* At end of set -- point to the chosen one. */ L4000: printf("\n OSL chooses %d %d %f", marray[4], marray[5], darray[0]); printf("\n I chose %d 1 %f", iseq, dval); if (iset == marray[0]) { marray[4] = -iseq; } goto L6000; L5000: marray[0] = -iset; L6000: return 0; } /* ekkbrnu */
/* *********************************************************************** * EXBRNU2 * This user exit routine modifies the default choice of the branching * variable. It is intended for use with samples: exmslv3 and exnodu. * dspace is the user work area. * mspace is the user work area. * ireasn is the reason for calling. * marray is the short node list -- integer values. * darray is the short node list -- double values (equivalenced). * jrtcod is the return code. * marray[0] is the set number. (5) (negative allowed) * marray[1] is the set type. * marray[2] is the priority. (2) * marray[3] is the number of variables in the set. * marray[4] is the column number of current variable. (4) * (negative allow) * marray[5] is which way. (4) * darray[0] is the current value of variable. * darray[1] is the down pseudo-cost. (3) * darray[2] is the up cost (3) or ref row entry (4). * darray[3] is the estimated degradation for going down. (4) (5) * darray[4] is the estimated degradation for going up. (4) (5) * Note: * The number(s) in parentheses (n) to the right of the definitions of the * elements of marray and darray indicate(s) the value of the parameter * "reason" for which these data items are available and/or may be set. ***************************************************************************/ /* Include files with OSL function prototypes & control variable mnemonics */ #include "ekkc.h" #include "osli.h" #include "osln.h" /* This external struct provides communication with ekknodu (exnodu) */ extern struct { double dbranch; } usrcom1; int ekkbrnu(double * dspace, long * mspace, long * ireasn, long * marray, double * darray, long * jrtcod) { /* Type local variables */ static double dhi, dlo; static double dsum, drefsum; double dpergrid; double dval, drefval; long irtcod, isol; long ivar, iset; long ncenter, ngrid, nnzero; /* Function Body */ switch (*ireasn) { case 1: goto L1000; case 2: goto L6000; case 3: goto L6000; case 4: goto L6000; case 5: goto L5000; } /* Initial entry - do all work here */ L1000: ekkiget(&irtcod, dspace, osli, OSLILN); ekknget(&irtcod, dspace, osln, OSLNLN); printf("There are %d sets and %d integer variables.\n", INUMSETS, INUMINTS); /* Number in grid */ ngrid = INUMINTS / INUMSETS; isol = NCOLSOL - 1; /* First set is X by itself */ nnzero = 0; for (ivar = 1; ivar <= ngrid; ++ivar) { dval = dspace[isol++]; if (dval > 1e-5 || dval < -1e-5) ++nnzero; } /* Skip, if first set unsatisfied - can do ordinary branch */ if (nnzero > 1) goto L6000; /* Through other sets getting *linked* reference entry */ /* (In real use, we would use true reference entries for grid) */ ncenter = (ngrid - 1) / 2; dpergrid = 2. / (double) ncenter; ++ncenter; dsum = drefsum = 0.; dlo = 1e20; dhi = -1e20; for (iset = 2; iset <= INUMSETS; ++iset) { for (ivar = 1; ivar <= ngrid; ++ivar) { dval = dspace[isol++]; /* accumulate */ if (dval > 1e-5 || dval < -1e-5) { drefval = (double) (ivar - ncenter) * dpergrid; drefsum += dval * drefval; dsum += dval; dlo = (dlodrefval) ? dhi : drefval; } } } goto L6000; /* At end */ L5000: if (marray[0] == 1) return 0; /* X satisfied, check Y */ if (dhi - dlo <= 1e-5) return 0; /* choose set 2 */ marray[0] = -2; /* choose where to branch */ dbranch = drefsum / dsum; L6000: return 0; } /* ekkbrnu */
/* *********************************************************************** */ /* exchnu */ /* This user exit subroutine chooses the next node for the branch */ /* and bound algorithm. */ /* ireasn=1 : Subroutine is being called before going through the list */ /* of active nodes. */ /* =2 : Subroutine is being called as each active node is being */ /* processed. */ /* =3 : Subroutine is being called after going through the list */ /* of active nodes. */ /* marray[0]: If ireasn=1, marray[0] is the number of active nodes; */ /* the rest of marray and darray are not meaningful. */ /* If ireasn=2, marray[0] is the number of the current node. */ /* If ireasn=3, marray[0] is the number of the chosen node; */ /* the rest of marray and darray are not meaningful. */ /* marray[1]: Number of unsatisfied variables. */ /* darray[1]: Solution value of parent node. */ /* *********************************************************************** */ #include#include "ekkc.h" #include "oslr.h" /* Common Block Declarations */ extern struct { double dvalobj; } usercom; #define usercom_1 usercom /* usercom struct is shared with exevnu.c */ int ekkchnu(dspace, mspace, ireasn, marray, darray, jrtcod) double *dspace; long *mspace, *ireasn, *marray; double *darray; long *jrtcod; { static long rtcod; static long ibest, number; static double dbest, rxtarget; /* Function Body */ switch ((int)*ireasn) { case 1: goto L1000; case 2: goto L2000; case 3: goto L3000; } /* Initialization */ L1000: dbest = 1e30; ibest = 0; number = 999999; /* Find target value. */ ekkrget(&rtcod, dspace, oslr, OSLRLN); rxtarget = RTARGET; /* Set return code to force ekkchnu calls. */ *jrtcod = 0; goto L4000; /* Ordinary call. */ L2000: if (darray[1] < rxtarget) { /* Better than the target, so choose one with fewest */ /* infeasibilities. */ if (number > marray[1]) { /* Fewer infeasibilities -- choose this one. */ dbest = darray[1]; ibest = marray[0]; number = marray[1]; } else if (number == marray[1] && dbest > darray[1]) { /* Same number, but better value. */ dbest = darray[1]; ibest = marray[0]; } } goto L4000; /* Done */ /* If any node better than target, point to one with fewest */ /* infeasibilities. */ L3000: if (ibest != 0) { marray[0] = ibest; } /* Store value of objective for ekkevnu. */ usercom_1.dvalobj = dbest; L4000: return 0; } /* ekkchnu */
/* *********************************************************************** */ /* excutu */ /* Sample user exit routine ekkcutu. ekkcutu allows you to generate */ /* "cuts", or additional constraint rows, to a problem matrix. It is */ /* called during ekkmpre preprocessing, or during supernode */ /* processing in ekkmslv. */ /* On Input mstatbin tells the user which 0-1 variables have been */ /* fixed so far, -1 says fixed to 0, +1 to 1, 0 still free. */ /* It is of length nbin. mtobin is an array of Inumcols */ /* length which has 0 for a continous, - the type for other */ /* "Integer" variables and points into mstatbin for all 0-1 */ /* variables. */ /* The user returns a series of cuts by filling in mcadd,mradd, */ /* deadd and nadd. */ /* mcadd - 1 is the first column of matrix, Inumcols is last. */ /* minus 1 denotes a lower bound on a row and minus 2 */ /* denotes an upper bound. */ /* If on entry nadd were 1002 and nrow were 205 then to add a */ /* single cut of X + 2* Y <= 2 might be: */ /* iadd mcadd mradd deadd */ /* 1003 5 206 1.0 */ /* 1003 407 206 2.0 */ /* 1003 -2 206 2.0 */ /* and nadd would be changed to 1005 on exit, and nrow to 206. */ /* dspace - Main Data Array */ /* mstatbin- Column status: 0 - free, 1 - fixed to 1, -1 - fixed to 0 */ /* mtobin - 0 or 0-1 sequence for each real variable */ /* mcadd - Column indices of cuts */ /* mradd - Row indices of cuts */ /* deadd - Elements of cuts */ /* nbin - Number of 0-1 variables in mstat01 */ /* nadd - Current number of entries in mcadd, mradd and deadd */ /* naddmax - Maximum number of entries allowed */ /* nrow - Current number of rows in matrix (including cuts) */ /* nrowmax - Maximum number of rows allowed */ /* *********************************************************************** */ #include "ekkc.h" #includeint ekkcutu(dspace, mstatbin, mtobin, mcadd, mradd, deadd, nbin, nadd, naddmax, nrow, nrowmax) double *dspace; int *mstatbin, *mtobin, *mcadd, *mradd; double *deadd; int *nbin, *nadd, *naddmax, *nrow, *nrowmax; { /* Initialized data */ static double delement[5] = { 5.,-7.,1.,10.,-1. }; static double drhs = 8.; static int mcolumn1[5] = { 4,6,8,30,2 }; static int mcolumn2[3] = { 1,4,7 }; static int i; /* In actual use one or more cuts would be computed. */ /* For explanations we assume that variables are X1,X2.... */ /* Assume first cut is magically in a Data statement */ /* First cut will be 5 X4 - 7 X6 + X8 +10 X30 - X2 <= 8 */ /* Function Body */ /* Add in first cut if enough room */ if (*nrow < *nrowmax && *nadd <= *nrowmax - 6) { ++(*nrow); /* elements */ for (i = 1; i <= 4; ++i) { ++(*nadd); mradd[*nadd-1] = *nrow; mcadd[*nadd-1] = mcolumn1[i - 1]; deadd[*nadd-1] = delement[i - 1]; } /* upper bound on row activity */ ++(*nadd); mradd[*nadd-1] = *nrow; mcadd[*nadd-1] = -2; deadd[*nadd-1] = drhs; } /* Second cut will be X1 + X4 + X7 = 1 */ if (*nrow < *nrowmax && *nadd <= *nrowmax - 5) { ++(*nrow); /* elements */ for (i = 1; i <= 3; ++i) { ++(*nadd); mradd[*nadd-1] = *nrow; mcadd[*nadd-1] = mcolumn2[i - 1]; deadd[*nadd-1] = 1.; } /* upper bound on row activity */ ++(*nadd); mradd[*nadd-1] = *nrow; mcadd[*nadd-1] = -2; deadd[*nadd-1] = 1.; /* and lower bound */ ++(*nadd); mradd[*nadd-1] = *nrow; mcadd[*nadd-1] = -1; deadd[*nadd-1] = 1.; } return 0; } /* ekkcutu */
/* *********************************************************************** */ /* exevnu */ /* This user exit routine determines whether the primal or the */ /* dual simplex method will be used to evaluate the current node. */ /* The routine is written under the assumption that for the class */ /* problems being solved, the primal algorithm is faster than the */ /* dual algorithm. However, with the dual algorithm, the branch can */ /* be cut off when the objective increases above the cutoff. So this */ /* routine selects the primal algorithm unless the objective is near */ /* the cutoff. It is assumed that ekkchnu saved the value of the */ /* objective function in dvalobj. */ /* Note that the return code must be set if the problem in infeasible. */ /* *********************************************************************** */ #include#include "ekkc.h" #include "oslr.h" #include "osli.h" /* Common Block Declarations */ struct { double dvalobj; } usercom; #define usercom_1 usercom /* usercom struct is shared with exchnu.c */ int ekkevnu(dspace, mspace, jrtcod) double *dspace; long *mspace, *jrtcod; { static long rtcod; /* Function Body */ ekkrget(&rtcod, dspace, oslr, OSLRLN); if (usercom_1.dvalobj + (float)2e3 > RBBCUTOFF) { /* Near cutoff, so use dual algorithm. */ ekksslv(&rtcod, dspace, 2, 1); } else { /* Not near cutoff, so use primal algorithm. */ ekksslv(&rtcod, dspace, 1, 1); } ekkiget(&rtcod, dspace, osli, OSLILN); /* Set user return code if needed. */ if (IPROBSTAT != 0) { *jrtcod = 1; } else { *jrtcod = 0; } return 0; } /* ekkevnu */
/* *********************************************************************** */ /* exheuu */ /* Sample user exit routine ekkheuu. ekkheuu gives you control over */ /* the fixing of variables to their upper or lower bounds. */ /* On Input mstatbin tells the user which 0-1 variables have been */ /* fixed so far, -1 says fixed to 0, +1 to 1, 0 still free. */ /* It is of length nbin. mtobin is an array of Inumcols */ /* length which has 0 for a continous, - the type for other */ /* "Integer" variables and points into mstatbin for all 0-1 */ /* variables. */ /* The user returns a valid branch. OSL will continue by */ /* setting 0-1 variables to their bounds using the first */ /* nfix1 entries in mfix. The postponed branch (which is only */ /* used if JTYPE is 2) is given by the next nfix2 entries of mfix. */ /* In this example the user knows that going up to 1 is always */ /* feasible, so the variable closest to one will be chosen */ /* Calling sequence - ekkheuu */ /* dspacE - Main Data Array */ /* mstatbin - Column status: 0 -free, 1 -fixed to 1, -1 -fixed to 0 */ /* mtobin - 0 or 0-1 sequence for each real variable */ /* mfix - Stack of 0-1s - negative fixed to, positive to 1 */ /* (maximum length 2*nbin) */ /* nbin - Number of 0-1 variables in mstatbin */ /* nfix1 - Number of variables fixed on this way */ /* nfix2 - Number of variables fixed on postponed way */ /* jtype - 1 for heuristic guess, 2 for heuristic branch */ /* ********************************************************************* */ #include#include "ekkc.h" #include "osli.h" #include "osln.h" int ekkheuu(dspace, mstatbin, mtobin, mfix, nbin, nfix1, nfix2, jtype) double *dspace; int *mstatbin, *mtobin, *mfix, *nbin, *nfix1, *nfix2, *jtype; { static int icol, iret, ichosen; static double dval, dlarge; /* Function Body */ if (*jtype != 2) { return 0; } /* Get all values (GETs need only be done once) */ ekkiget(&iret, dspace, osli, OSLILN); ekknget(&iret, dspace, osln, OSLNLN); /* Find largest 0-1 value (not at 1) */ dlarge = 0.; ichosen = 0; for (icol = 1; icol <= INUMCOLS; ++icol) { if (mtobin[icol-1] > 0) { dval = dspace[NCOLSOL + icol - 2]; if (dval < .9999 && dval > dlarge) { dlarge = dval; ichosen = icol; } } } if (ichosen == 0) { printf("\n This should never happen\n"); exit(); } /* Find 0-1 sequence */ ichosen = mtobin[ichosen-1]; /* Carry on with this one to one */ *nfix1 = 1; mfix[0] = ichosen; /* And postpone other way */ *nfix2 = 1; mfix[1] = -ichosen; return 0; } /* ekkheuu */
/* *********************************************************************** * EXNODU * This user exit routine allows for non standard branching. * Data will be saved and restored to allow very flexible branch * and bound. It is intended for use with EXMSLV3 and exbrnu2. * dspace is the user work area. * mspace is the user work area. * ireasn is the reason for calling. * marray is the short node list -- integer values. * darray is the short node list -- real*8 values (equivalenced). * marray[0] - Branch type SOS=1-3, Integer=4,Null=99 * marray[1] - 0 for down branch , 1 for up * marray[2] - Variable number / Set number * darray[0] - Integer value/Set reference value * muser - User array * nuser - Length of muser array * ***********************************************************************/ /* Include files with OSL function prototypes & control variable mnemonics */ #include "ekkc.h" #include "osli.h" #include "osln.h" /* usrcom1 provides communication with ekkbrnu (exbrnu2) */ struct { double dbranch; } usrcom1; /* persistent temporary storage */ double dtemp[10]; long mtemp[20]; int ekknodu(double *dspace, long *mspace, long * ireasn, long *marray, double *darray, long *muser, long * nuser) { /* Type local variables */ long i, iup, iset, ivar, irtcod; long ncenter, ngrid; double dpergrid, dhi, dlo; /* NOTE: in this example we have assumed that Imiplength is 20 */ if (*nuser != 20) { printf("Error detected in user exit ekknodu"); printf("Bad sample coding - Imiplength must be = 20"); printf("Stopping your sample application now"); stop(16); } switch (*ireasn) { case 1: goto L1000; case 2: goto L2000; } /* Return if ordinary branch */ L1000: if (marray[2] == 1) return 0; /* Save any information which will be needed when node is evaluated. * This information can be of any kind. The user could be * continually refining the grid, in which case information * on mesh size and X, Y values of basic variables would be stored, * then in ekkevnu the matrix could be completely rewritten! */ dtemp[0] = dbranch; i1 = *nuser; for (i = 0; i < i1; ++i) muser[i] = mtemp[i]; /* Switch off ***ANY*** action by OSL to fix variables */ marray[0] = 99; goto L3000; /* Return if ordinary branch */ L2000: if (marray[0] != 99) return 0; /* Now set all variables to zero */ dbranch = dtemp[0]; i1 = *nuser; for (i = 0; i < i1; ++i) mtemp[i] = muser[i]; if (marray[1] == 1) { /* Up branch - fix all low reference values to zero */ dlo = -1e20; dhi = dbranch; } else { /* Down branch - fix all high reference values to zero */ dlo = dbranch; dhi = 1e20; } ekkiget(&irtcod, dspace, osli, OSLILN); ekknget(&irtcod, dspace, osln, OSLNLN); /* Number in grid */ ngrid = INUMINTS / INUMSETS; iup = NCOLUPPER - 2 + ngrid; /* Through other sets getting *linked* reference entry */ /* (In real use, we would use true reference entries for grid) */ ncenter = (ngrid - 1) / 2; dpergrid = 2. / (double) (ncenter); ++ncenter; for (iset = 2; iset <= INUMSETS; ++iset) { for (ivar = 1; ivar <= ngrid; ++ivar) { ++iup; dbranch = (double) (ivar - ncenter) * dpergrid; /* zero bound, if in range */ if (dbranch >= dlo && dbranch <= dhi) dspace[iup] = 0.; } } L3000: return 0; } /* ekknodu */
/* *********************************************************************** */ /* EXSLVU */ /* This sample user exit program shows how to invoke EKKQSLV to solve */ /* a branch and bound node of a quadratic MIP problem. It may also be */ /* used for linear MIP problems. There are three situations in which */ /* EKKSLVU is called. The first situation corresponds to the root node */ /* of the branch and bound tree. The second situation corresponds to */ /* a leaf node (normal node) of the branch and bound tree. The third */ /* situation corresponds to the optimal node. This user exit may be */ /* used to select the algorithms (primal or dual) to use to solve the */ /* node under these three situations. It's also used to indicate */ /* whether a cold or warm start should be used. */ /* *********************************************************************** */ /* dobjval- Value of objective */ /* jrtcod - Return code */ /* jtype - 1 - initial solve */ /* 2 - normal node */ /* 3 - final solve */ /* *********************************************************************** */ #include "ekkc.h" #include "osli.h" #include "osln.h" #include "oslr.h" int ekkslvu(double * dspace, long * mspace, double * dobjval, long * jrtcod, long * jtype) { /* Type local variables */ long ialg; long iinit; long irtcod; /* Function Body */ if (*jtype == 1) { /* Initial solve */ ialg = 1; iinit = 1; } else if (*jtype == 2) { /* Regular node */ ialg = 2; iinit = 0; } else if (*jtype == 3) { /* Final solve */ ialg = 1; iinit = 1; } /* Solve the LP or QP node */ ekknget(&irtcod, &dspace[1], osln, OSLNLN); if (NQELEM == 0) { /* No Quadtratic data, so the problem is an LP */ ekksslv(jrtcod, dspace, &ialg, &iinit); } else { /* Quadratic data exists, so solve the problem as a QP */ ekkqslv(jrtcod, dspace, &ialg, &iinit); } /* Return the outcome of the solve to EKKMSLV */ ekkiget(&irtcod, dspace, osli, OSLILN); if (IPROBSTAT != 0) { *jrtcod = 1; } else { *jrtcod = 0; } /* Return a new candidate incumbant value to EKKMSLV */ ekkrget(&irtcod, dspace, oslr, OSLRLN); *dobjval = ROBJVALUE; return 0; } /* ekkslvu */
/* ********************************************************************* */ /* exordu */ /* This user exit enables the user to custom-order the LP matrix. In */ /* this example, Joseph Liu's Multiple Minimum Degree algorithm (to */ /* be supplied by the user, GENMMD) is used. */ /* adjncy: The entries (row indices) for the adjacency matrix */ /* perm : The array where the permutation will be put */ /* invp : The array where the inverse permutation will be put */ /* mwork : An integer array for user work space */ /* nwords: The length of mwork in single words. */ /* nrow : The row size of the LP matrix A */ /* ********************************************************************* */ #include#include "ekkc.h" int ekkordu(xadj, adjncy, perm, invp, mwork, nwords, nrow) int *xadj, *adjncy, *perm, *invp, *mwork, *nwords, *nrow; { static int maxi4, metol; static int nofsub; extern int genmmd(); /* Function Body */ /* Test for sufficient space. */ if (*nwords < *nrow << 2) { printf("\n Not enough space for GENMMD"); exit(); } /* Set some GENMMD-specific parameters */ metol = 1; maxi4 = 1073741824; GENMMD(nrow, xadj, adjncy, invp, perm, &metol, mwork, &mwork[*nrow], &mwork[(*nrow << 1)], &mwork[*nrow * 3], &maxi4, &nofsub); return 0; } /* ekkordu */