C Include Files and User Exits


Sample C include files

These are the sample C include files that define the control variable names used throughout this document.


Character Control Variable Mnemonics #include oslc
Integer Control Variable Mnemonics #include osli
Index Control Variable Mnemonics #include osln
Real Control Variable Mnemonics #include oslr

Character Control Variable Mnemonics #include oslc

/*___________________________________________________________________________*/
/* 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) */

Integer Control Variable Mnemonics #include osli

/*___________________________________________________________________________*/
/* 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 */

Index Control Variable Mnemonics #include osln

/*___________________________________________________________________________*/
/* 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) */

Real Control Variable Mnemonics #include oslr

/*___________________________________________________________________________*/
/* 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] 



Sample C include files
Sample Mixed-Integer User Exit Subroutines
Sample Row Ordering User Exit Subroutine, exordu
 

Sample Informational User Exit Subroutines

These are the sample informational user exit subroutines that are used in part or in whole throughout this document. In addition to these subroutines, there may be additional sample informational user exit subroutines distributed with the Optimization Library code.
  Sample User Exit Subroutine exitru
  Sample User Exit Subroutine exmsgu

Sample User Exit Subroutine exitru

/* *********************************************************************** */
/*                            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 */

Sample User Exit Subroutine exmsgu

/* *********************************************************************** */
/*                            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 */

Sample User Exit Subroutine exmsgu

/* *********************************************************************** */
/*   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".



Sample C include files
Sample Informatonal User Exit Subroutines
Sample Row Ordering User Exit Subroutine, exordu
 

Sample Mixed-Integer User Exit Subroutines

These are the sample mixed-integer user exit subroutines that are used in part or in whole throughout this document. In addition to these subroutines, there may also be additionial sample mixed-integer user exit subroutines distributed with the Optimization Library code.
Sample User Exit Subroutine exbrnu
Sample User Exit Subroutine exbrnu2
Sample User Exit Subroutine exchnu
Sample User Exit Subroutine excutu
Sample User Exit Subroutine exevnu
Sample User Exit Subroutine exheuu
Sample User Exit Subroutine exnodu
Sample User Exit Subroutine exslvu

Sample User Exit Subroutine exbrnu

/* *********************************************************************** */
/*                            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 */

Sample User Exit Subroutine exbrnu2

/* ***********************************************************************
 *                            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 */

Sample User Exit Subroutine exchnu

/* *********************************************************************** */
/*                            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 */

Sample User Exit Subroutine excutu

/* *********************************************************************** */
/*                            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"
#include 

int 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 */

Sample User Exit Subroutine exevnu

/* *********************************************************************** */
/*                            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 */

Sample User Exit Subroutine exheuu

/* *********************************************************************** */
/*                            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 */

Sample User Exit Subroutine exnodu

/* *********************************************************************** 
 *                            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 */

Sample User Exit Subroutine exslvu

/* *********************************************************************** */
/*                          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 */

Sample User Exit Subroutine exordu

/* ********************************************************************* */
/*                           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 */

 
Sample C include files
Sample Informational User Exit Subroutines
Sample Mixed-Integer User Exit Subroutines
Sample Row Ordering User Exit Subroutine, exordu
[ Top of Page | Previous Page | Next Page | Table of Contents ]