mt_cplex_cbk.h

Go to the documentation of this file.
00001 /* MTgomory "multi tableau gomory cut" provides an implementation for gomory
00002  * cuts derived from multiple tableau rows in the spirit of the work of
00003  * Andersen et al (IPCO 2007), Cornuejols (es presented in George Nemhauser
00004  * Birthday Conference in Atlanta 2007) and Gomory (presented in the same
00005  * conference).
00006  *
00007  * Copyright (C) 2007 Daniel Espinoza.
00008  * 
00009  * This library is free software; you can redistribute it and/or modify it
00010  * under the terms of the GNU Lesser General Public License as published by the
00011  * Free Software Foundation; either version 2.1 of the License, or (at your
00012  * option) any later version.
00013  *
00014  * This library is distributed in the hope that it will be useful, but 
00015  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
00016  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
00017  * License for more details.
00018  *
00019  * You should have received a copy of the GNU Lesser General Public License
00020  * along with this library; if not, write to the Free Software Foundation,
00021  * Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA 
00022  * */
00023 /* ========================================================================= */
00024 #ifndef __MT_CPLEX_CBK_H__
00025 #define __MT_CPLEX_CBK_H__
00026 #include "cplex.h"
00027 #include "EGlib.h"
00028 #include "mt_types.h"
00029 #include "mt_cutpool.h"
00030 /** @file 
00031  * @ingroup MTgomory */
00032 /** @addtogroup MTgomory */
00033 /** @{ */
00034 /* ========================================================================= */
00035 /** @brief Minimum violation for a cut to be added. Note that we scale the cut
00036  * in such a way that the maximum absolute value of a non-zero coefficient is
00037  * one. */
00038 #define MT_CCBK_MIN_VIO 0x1p-10
00039 /* ========================================================================= */
00040 /** @brief Minimum fractionality required for a tableau to be considered, i.e.
00041  * if abs(x-round(x))< min_frac we discard the asociated tableau */
00042 #define MT_CCBK_MIN_FRAC 0x1p-12
00043 /* ========================================================================= */
00044 /** @brief Maximum allowed cut ratio. The cut ratio is defined as the ratio 
00045  * between the maximum absolute value and minimum absolute value for the 
00046  * non-zero coefficients. It is importatn because is a measure of the error 
00047  * inducing capabilities of the inequality */
00048 #define MT_CCBK_MAX_RATIO 0x1p15
00049 /* ========================================================================= */
00050 /** @brief Minimum tableau row ratio. This is defined as minabsval/maxabsval
00051  * for a tableau row. Tableau rows that have a ratio bellow the given threshold
00052  * will not be considered at the moment of cut genweration */
00053 #define MT_CCBK_MIN_TABLEAU_RATIO 0x1p-12
00054 /* ========================================================================= */
00055 /** @brief internal error string for cplex */
00056 extern char __mt_cplex_errbuf[4096];
00057 
00058 /* ========================================================================= */
00059 /** @brief if se to one, use real variable names while displaying cut/tableau
00060  * information */
00061 #define MT_CCBK_USE_NAMES 1
00062 /* ========================================================================= */
00063 /** @brief internal debugging information for CPLEX
00064  * @param __rval cplex return value (zero means success)
00065  * @param env as returned by CPXopenCPLEX function.
00066  * @param where to jump if an error is found. 
00067  * */
00068 #define MTcplexCHECKRVALG(__env,__rval,__where) do{\
00069   if(__rval)\
00070   {\
00071     CPXgeterrorstring(__env, __rval, __mt_cplex_errbuf);\
00072     fprintf(stderr,__mt_cplex_errbuf);\
00073     __EG_PRINTLOC__;\
00074     goto __where;\
00075   }\
00076 }while(0)
00077 /* ========================================================================= */
00078 /** @brief display a compress tableau into the given file 
00079  * @param file where to write the tableau.
00080  * @param lp all LP-related information (including length of the tableau)
00081  * @param matval values of the compresed tableau
00082  * @param matind indices of the non-zeros in the tableau
00083  * @param length of the compresed tableau
00084  * @note The function support compressed tableau with logical variables
00085  * @note Also, the function would prefix a ~ for all variables that are at its
00086  * upper bound.
00087  * */
00088 void MTcplex_display_compress_tableau(FILE* file,
00089                                       const MTlp_t*const lp,
00090                                       const double*const matval,
00091                                       const int*const matind,
00092                                       const int nz);
00093 /* ========================================================================= */
00094 /** @brief display a tableau into the given file
00095  * @param file where to write the tableau.
00096  * @param lp all LP-related information (including length of the tableau)
00097  * @param tableau actual values of the tableau.
00098  * */
00099 void MTcplex_display_tableau( FILE* file,
00100                               const MTlp_t*const lp, 
00101                               const double*const tableau);
00102 /* ========================================================================= */
00103 /** @brief initialize an #MTlp_t structure 
00104  * @param __lp pointer to an #MTlp_t structure.
00105  * */
00106 #define MTlp_init(__lp) memset((__lp),0,sizeof(MTlp_t))
00107 /* ========================================================================= */
00108 /** @brief free any internally allocated memory inside an #MTlp_t structure. 
00109  * @param MTlp pointer to an #MTlp_t structure.
00110  * */
00111 void MTlp_clear(MTlp_t*const MTlp);
00112 /* ========================================================================= */
00113 /** @brief Given an LP problem pointer, load it into an 
00114  * (initialized) #MTlp_t structure.
00115  * @param lp pointer to an #MTlp_t structure.
00116  * @param CPXlp pointer to a CPLEX LP problem 
00117  * @param env as returned by CPXopenCPLEX function.
00118  * @param cbdata A pointer passed from the optimization routine to the
00119  * user-written callback that identifies the problem being optimized. The only 
00120  * purpose of this pointer is to pass it to the callback information routines.
00121  * @param wherefrom An integer value indicating where in the optimization this
00122  * function was called. It has the value CPX_CALLBACK_MIP_CUT.
00123  * @return zero on success.
00124  * */ 
00125 int MTlp_load_problem(CPXCENVptr env, 
00126                       MTlp_t*const lp, 
00127                       CPXLPptr CPXlp, 
00128                       void*cbdata, 
00129                       int wherefrom);
00130 /* ========================================================================= */
00131 /** @brief Initialize an #MTrowmatrix_t structure too an empty matrix
00132  * @param __mt matrix to initialize */
00133 #define MTrowmatrix_init(__mt) memset((__mt),0,sizeof(MTrowmatrix_t))
00134 /* ========================================================================= */
00135 /** @brief resize a #MTrowmatrix_t structure
00136  * @param MTrm rowmatrix to resize
00137  * @param MTrsz new row-space (it will only grow).
00138  * @param MTnsz new non-zero space (it will only grow).
00139  * */
00140 void MTrowmatrix_rsz(MTrowmatrix_t*const MTrm,
00141               const int MTrsz,
00142               const int MTnsz);
00143 /* ========================================================================= */
00144 /** @brief free any internally allocated memory inside an #MTrowmatrix_t
00145  * structure.
00146  * @param MTrm rowmatrix to clear */
00147 void MTrowmatrix_clear(MTrowmatrix_t*const MTrm);
00148 /* ========================================================================= */
00149 /** @brief initialize a #MTsol_t structure */
00150 #define MTsol_init(__sol) memset(__sol,0,sizeof(MTsol_t))
00151 /* ========================================================================= */
00152 /** @brief resize a solution structure 
00153  * @param MTsol solution to resize
00154  * @param cnz new column space
00155  * @param rnz new row space
00156  * */
00157 void MTsol_rsz( MTsol_t*const MTsol,
00158                 const int cnz,
00159                 const int rnz);
00160 /* ========================================================================= */
00161 /** @brief clear any internal memory asociated with an #MTsol_t structure 
00162  * @param MTsol structure to clear */
00163 void MTsol_clear(MTsol_t*const MTsol);
00164 /* ========================================================================= */
00165 /** @name #MTccbk_info_t set/get functions */
00166 /*@{*/
00167 #define MTcbkiSetCutsAtRoot(__cbki,__val) ((__cbki)->root_only=(__val))
00168 #define MTcbkiSetCuts(__cbki,__val) ((__cbki)->use_cuts=(__val))
00169 #define MTcbkiSetMaxRows(__cbki,__val) ((__cbki)->max_rows=(__val))
00170 #define MTcbkiSetMaxNodeCuts(__cbki,__val) ((__cbki)->max_cuts=(size_t)(__val))
00171 #define MTcbkiSetMaxRoundCuts(__cbki,__val) ((__cbki)->max_cpr=(__val))
00172 #define MTcbkiSetCutStyle(__cbki,__val) ((__cbki)->cut_style=(__val))
00173 /*@}*/
00174 /* ========================================================================= */
00175 /** @brief initialize an #MTccbk_info_t structure */
00176 #define MTccbk_info_init(__cbinf) memset(__cbinf,0,sizeof(MTccbk_info_t))
00177 /* ========================================================================= */
00178 /** @brief display callback info */
00179 void MTccbk_info_display(const MTccbk_info_t*const info,FILE*out);
00180 /* ========================================================================= */
00181 /** @brief test if we should proceed with the cuting process, and update
00182  * information
00183  * @param info calllback info to use.
00184  * @param env as returned by CPXopenCPLEX function.
00185  * @param cbdata A pointer passed from the optimization routine to the
00186  * user-written callback that identifies the problem being optimized. The only 
00187  * purpose of this pointer is to pass it to the callback information routines.
00188  * @param wherefrom An integer value indicating where in the optimization this
00189  * function was called. It has the value CPX_CALLBACK_MIP_CUT.
00190  * @param action pointer to an integer where we return action, zero to
00191  * continue cutting, non-zero to stop. 
00192  * @return zero on succsess, non-zero otherwise. */ 
00193 int MTccbk_info_process(MTccbk_info_t*const info,
00194                         CPXCENVptr env,
00195                         void*cbdata,
00196                         int wherefrom,
00197                         int*const action);
00198 /* ========================================================================= */
00199 /** @name Profiling information for the cuts */
00200 /*@{*/
00201 /* @brief number of tableau rows discarded because they have a small ratio
00202  * between minabs and maxabs, thus possible inducing bad numericall issues */
00203 extern int MTccbk_fail_tableau_ratio;
00204 /** @brief Number of discarded cuts because tableaus has wrong number
00205  * of basic variables. */
00206 extern int MTccbk_fail_tableau_nbasic;
00207 /** @brief Number of discarded cuts because tableaus has wrong coefficient for
00208  * basic variable. */
00209 extern int MTccbk_fail_tableau_coeff;
00210 /** @brief Number of discarded cuts because fraction is too small. */
00211 extern int MTccbk_fail_tableau_frac;
00212 /** @brief Type of basic variable for tableau is not integer */
00213 extern int MTccbk_fail_tableau_btype;
00214 /** @brief Number of discarded cuts because high ratio */
00215 extern int MTccbk_fail_ratio;
00216 /** @brief minimum ratio of discarded inequality */
00217 extern double MTccbk_discarded_ratio;
00218 /** @brief Number of discarded cuts because low violation */
00219 extern int MTccbk_fail_violation;
00220 /** @brief maximum violation of discarded inequality */
00221 extern double MTccbk_discarded_violation;
00222 /** @brief display summary information for the call-back calls 
00223  * @param __fout where to write the sumary */
00224 #define MTccbk_display_sumary(__fout) do{\
00225   fprintf(__fout,"MTccbk sumary:\n");\
00226   fprintf(__fout,"\tDiscarded tableau rows: %4d (coeff %d, nbasic %d,"\
00227           " ratio %d, type %d, fraction %d)\n", MTccbk_fail_tableau_nbasic + \
00228           MTccbk_fail_tableau_coeff + MTccbk_fail_tableau_ratio + \
00229           MTccbk_fail_tableau_btype + MTccbk_fail_tableau_frac,\
00230           MTccbk_fail_tableau_coeff, MTccbk_fail_tableau_nbasic, \
00231           MTccbk_fail_tableau_ratio, MTccbk_fail_tableau_btype, \
00232           MTccbk_fail_tableau_frac);\
00233   fprintf(__fout,"\tDiscarded by ratio:     %4d (next %.5lg)\n",\
00234           MTccbk_fail_ratio, MTccbk_discarded_ratio);\
00235   fprintf(__fout,"\tDiscarded by violation: %4d (next %.5lg)\n",\
00236           MTccbk_fail_violation, MTccbk_discarded_violation);\
00237   }while(0)
00238 /*@}*/
00239 /* ========================================================================= */
00240 /** @name #MTgomory_ccbk_t set/get functions */
00241 /*@{*/
00242 #define MTccbkSetCutDominance(__cbdata,__val) MTcutHeapSetDominance((&((__cbdata)->cuth)),__val)
00243 #define MTccbkSetCutSel(__cbdata,__val) MTcutHeapSetCS((&((__cbdata)->cuth)),__val)
00244 #define MTccbkSetCutsAtRoot(__cbdata,__val)  MTcbkiSetCutsAtRoot((&((__cbdata)->info)),__val) 
00245 #define MTccbkSetCuts(__cbdata,__val)  MTcbkiSetCuts((&((__cbdata)->info)),__val) 
00246 #define MTccbkSetCutStyle(__cbdata,__val)  MTcbkiSetCutStyle((&((__cbdata)->info)),__val) 
00247 #define MTccbkSetMaxRows(__cbdata,__val)  MTcbkiSetMaxRows((&((__cbdata)->info)),__val)
00248 #define MTccbkSetMaxNodeCuts(__cbdata,__val)  MTcbkiSetMaxNodeCuts((&((__cbdata)->info)),__val)
00249 #define MTccbkSetMaxRoundCuts(__cbdata,__val) do{\
00250   MTgomory_ccbk_t*const __MTcbdata = (__cbdata);\
00251   MTcbkiSetMaxRoundCuts((&(__MTcbdata->info)),__val);\
00252   MTcutHeapClear(&(__MTcbdata->cuth));\
00253   MTcutHeapInit(&(__MTcbdata->cuth),((size_t)(__MTcbdata->info.max_cpr)));}while(0)
00254 /*@}*/
00255 /* ========================================================================= */
00256 /** @brief initialize an #MTgomory_ccbk_t structure.
00257  * @param __cbdata pointer to an #MTgomory_ccbk_t structure.
00258  * */
00259 #define MTgomory_ccbk_init(__cbdata) do{\
00260   MTgomory_ccbk_t*const __MTcbdata = (__cbdata);\
00261   memset((__MTcbdata),0,sizeof(MTgomory_ccbk_t));\
00262   MTccbk_info_init(&(__MTcbdata->info));\
00263   MTsol_init(&(__MTcbdata->sol));\
00264   MTcut_init(&(__MTcbdata->cut));\
00265   MTrowmatrix_init(&(__MTcbdata->tb));\
00266   MTcutHeapInit(&(__MTcbdata->cuth),((size_t)(__MTcbdata->info.max_cpr)));\
00267   MTlp_init(&(__MTcbdata->lp));}while(0)
00268 /* ========================================================================= */
00269 /** @brief if required (i.e. __nrowsz > nrowsz || __ncolsz > colsz || 
00270  * __ntbsz > tbsz) , resize an #MTgomory_ccbk_t structure
00271  * @param __cbdata pointer to an #MTgomory_ccbk_t structure.
00272  * @param __nrowsz new row-size for the structure.
00273  * @param __ncolsz new col-size for the structure.
00274  * @param __ntbsz new tableau-size for the structure.
00275  * @note When we resize the structure, all previous contents are lost. 
00276  * */
00277 #define MTgomory_ccbk_rsz(__cbdata,__nrowsz,__ncolsz,__ntbsz) do{\
00278   MTgomory_ccbk_t*const __ccbk = (__cbdata);\
00279   const int __ccbk_rsz = (__nrowsz);\
00280   const int __ccbk_csz = (__ncolsz);\
00281   const int __ccbk_tsz = (__ntbsz);\
00282   MTrowmatrix_rsz(&(__ccbk->tb),__ccbk_rsz,__ccbk_tsz);\
00283   MTsol_rsz(&(__ccbk->sol),__ccbk_csz,__ccbk_rsz);\
00284   MTcut_rsz(&(__ccbk->cut),__ccbk_csz);\
00285   if(__ccbk->colsz < __ccbk_csz){\
00286     __ccbk->colsz = __ccbk_csz;\
00287     EGfree(__ccbk->work);\
00288     EGfree(__ccbk->extcut);\
00289     __ccbk->work = EGsMalloc(double,(__ccbk_csz+1));\
00290     __ccbk->extcut = EGsMalloc(double,__ccbk_csz);}\
00291   if(__ccbk->rowsz < __ccbk_rsz){\
00292     __ccbk->rowsz = __ccbk_rsz;\
00293     EGfree(__ccbk->base);\
00294     EGfree(__ccbk->f);\
00295     __ccbk->base = EGsMalloc(double,__ccbk_rsz);\
00296     __ccbk->f = EGsMalloc(double,__ccbk_rsz);}\
00297   }while(0)
00298 /* ========================================================================= */
00299 /** @brief free any internally allocated memory inside an #MTgomory_ccbk_t
00300  * structure. 
00301  * @param __cbdata pointer to an #MTgomory_ccbk_t structure.
00302  * */
00303 #define MTgomory_ccbk_clear(__cbdata) do{\
00304   MTgomory_ccbk_t*const __ccbk = (__cbdata);\
00305   EGfree(__ccbk->work);\
00306   EGfree(__ccbk->extcut);\
00307   EGfree(__ccbk->base);\
00308   EGfree(__ccbk->f);\
00309   __ccbk->rowsz = __ccbk->colsz = 0;\
00310   MTsol_clear(&(__ccbk->sol));\
00311   MTcut_clear(&(__ccbk->cut));\
00312   MTrowmatrix_clear(&(__ccbk->tb));\
00313   MTcutHeapClear(&(__ccbk->cuth));\
00314   MTlp_clear(&(__ccbk->lp));}while(0)
00315 /* ========================================================================= */
00316 /** @brief Interface for the CPLEX-callback for the #MTgomoryCut function.
00317  * @param env as returned by CPXopenCPLEX function.
00318  * @param cbdata A pointer passed from the optimization routine to the
00319  * user-written callback that identifies the problem being optimized. The only 
00320  * purpose of this pointer is to pass it to the callback information routines.
00321  * @param wherefrom An integer value indicating where in the optimization this
00322  * function was called. It has the value CPX_CALLBACK_MIP_CUT.
00323  * @param cbhandle A pointer to user private data.
00324  * @param useraction_p A pointer to an integer indicating the action for ILOG
00325  * CPLEX to take at the completion
00326  * of the user callback. The table summarizes possible actions.
00327  * - 0 CPX_CALLBACK_DEFAULT Use cuts as added
00328  * - 1 CPX_CALLBACK_FAIL Exit optimization
00329  * - 2 CPX_CALLBACK_SET Use cuts as added
00330  * */
00331 int MTgomory_ccbk(CPXCENVptr env,
00332                   void*cbdata,
00333                   int wherefrom,
00334                   void*cbhandle,
00335                   int*useraction_p);
00336 /* ========================================================================= */
00337 /** @brief read optionfile and set parameter to CPLEX
00338  * @param env pointer to the CPLEX environment structure.
00339  * @param inputfile pointer to the optionfile.*/
00340 int MTread_cplex_options(CPXENVptr env, FILE * inputfile);
00341 /* ========================================================================= */
00342 /** @brief given an LP desvription, and CPLEX binvrow, compute the 
00343  * actual tableau (including logicals, which are in position i+ncols of
00344  * the tableau for the i-th logical/slack variable, but we force that
00345  * the coefficient of equality logicals is zero)
00346  * @param lp pointer to an #MTlp_t structure.
00347  * @param binvrow as returned by cplex (length = lp->nrows);
00348  * @param tableau where to write the tableau (length lp->nrows + 
00349  * lp->ncols).
00350  * @return zero on success, non-zero otherwise
00351  * */ 
00352 int MTcplex_binv_to_tableau(const MTlp_t*const lp, 
00353                             const double*const binvrow, 
00354                             double*const tableau);
00355 /* ========================================================================= */
00356 /** @brief test if a given cut is valid to the given cplex LP
00357  * @param cut cut to be tested
00358  * @param lp pointer to the asociated #MTlp_t structure.
00359  * @return zero on success, non-zero otherwise.
00360  * */
00361 int MTcplex_test_cut( const MTcut_t*const cut,
00362                       const MTlp_t*const lp);
00363 /* ========================================================================= */
00364 /** @brief compute ax = f for a tableau
00365  * @param lp pointer to an #MTlp_t structure.
00366  * @param tableau where to write the tableau (length lp->nrows + 
00367  * @param x structural variables values
00368  * @param slack logical variables values
00369  * @param f where to store ax = f
00370  * */
00371 void MTcompute_f(const MTlp_t*const lp, 
00372                 const double*const tableau,
00373                 const double*const x,
00374                 const double*const slack,
00375                 double*const f);
00376 /* ========================================================================= */
00377 /** @brief display an LP to the given file 
00378  * @param lp pointer to an #MTlp_t structure
00379  * @param sol asociated solution to the LP
00380  * @param stream file where to write the LP
00381  * */
00382 void MTdisplay_lp(const MTlp_t*const lp,
00383                   const MTsol_t*const sol, 
00384                   FILE*stream);
00385 /* ========================================================================= */
00386 /** @brief get the indices of fractional (structural) variables 
00387  * @param lp pointer to an #MTlp_t structure
00388  * @param x current LP x-value
00389  * @param fracvars array of length  (at least) #MTlp_t::nrows
00390  * @param nfrac pointer to an integer where the number of fractional variables
00391  * is returned.
00392  * @param minitgap minimum distance to closest integer for a variable to be
00393  * considered fractional
00394  * @return zero on success, non-zero otherwise
00395  * */
00396 int MTcompute_fractional_vars(const MTlp_t*const lp,
00397                               const double*const x,
00398                               int*const fracvars,
00399                               int*const nfrac,
00400                               const double minitgap);
00401 /* ========================================================================= */
00402 /** @brief get the indices of (almost) integer variables 
00403  * @param lp pointer to an #MTlp_t structure
00404  * @param x current LP x-value
00405  * @param intvars array of length  (at least) #MTlp_t::nrows
00406  * @param nint pointer to an integer where the number of fractional variables
00407  * is returned.
00408  * @param intgap integrality gap allowd for a variable to be considered integer
00409  * @return zero on success, non-zero otherwise
00410  * */
00411 int MTcompute_integer_vars(const MTlp_t*const lp,
00412                            const double*const x,
00413                            int*const intvars,
00414                            int*const nint,
00415                            const double intgap);
00416 /* ========================================================================= */
00417 /** @brief Get the best K tableau (asociated to fractional variables), note
00418  * that we check for wrongly computed tableau. 
00419  * Note that we compute Z = f + 0.5+Ax, where A is the tableau and f the
00420  * fractional value (displaced by 1/2), moreover, all basic variables have zero
00421  * coefficient in the resulting tableau, and all variables are complemented to
00422  * their bounds.
00423  * @param lp pointer to an #MTlp_t structure
00424  * @param sol asociated node solution
00425  * @patam tb pointer to an #MTrowmap_t structure
00426  * @param f fractional value for each tableau.
00427  * @param max_tableau maximum number of tableaus to consider.
00428  * used to select the set of best fractional tableau rows.
00429  * @param env Cplex environment pointer.
00430  * @param CPXlp cplex lp pointer.
00431  * @return zero on success, non-zero otherwise.
00432  * */
00433 int MTget_best_k_tableau_rows(const MTlp_t*const lp,
00434                               const MTsol_t*const sol,
00435                               const int max_tableau,
00436                               CPXCENVptr env,
00437                               CPXLPptr CPXlp,
00438                               MTrowmatrix_t*const tb,
00439                               double*const f);
00440 /* ========================================================================= */
00441 /** @brief Get the best K tableau (asociated to integer basic variables), note
00442  * that we check for wrongly computed tableau. 
00443  * Note that we compute Z = f + 0.5+Ax, where A is the tableau and f the
00444  * fractional value (displaced by 1/2), moreover, all basic variables have zero
00445  * coefficient in the resulting tableau, and all variables are complemented to
00446  * their bounds.
00447  * @param lp pointer to an #MTlp_t structure
00448  * @param sol asociated node solution
00449  * @patam tb pointer to an #MTrowmap_t structure
00450  * @param f fractional value for each tableau.
00451  * @param max_tableau maximum number of tableaus to consider.
00452  * used to select the set of best integer tableau rows.
00453  * @param env Cplex environment pointer.
00454  * @param CPXlp cplex lp pointer.
00455  * @return zero on success, non-zero otherwise.
00456  * */
00457 int MTget_best_k_integer_tableau_rows(const MTlp_t*const lp,
00458                                       const MTsol_t*const sol,
00459                                       const int max_tableau,
00460                                       CPXCENVptr env,
00461                                       CPXLPptr CPXlp,
00462                                       MTrowmatrix_t*const tb,
00463                                       double*const f);
00464 /* ========================================================================= */
00465 /** @brief transform an uncomplemented cut to a complemented form.
00466  * Note that we expect no coefficient for basic variables in the cut.
00467  * @param cut pointer to an #MTcut_t structure, we will complement the cut.
00468  * @param sol asociated node solution
00469  * @param lp pointer to the related #MTlp_t structure
00470  * @return zero on success, non-zero otherwise.
00471  * */
00472 int MTuncomplemented_to_complemented_cut( const MTlp_t*const lp,
00473                                           const MTsol_t*const sol,
00474                                           MTcut_t*const cut);
00475 /* ========================================================================= */
00476 /** @brief transform an extened non-complemented cut to a compresed and
00477  * complemented form. We assume the extended cut is of the form ax >= 1. 
00478  * Note that we expect no coefficient for basic variables in the cut, moreover,
00479  * the rhs of the inequality is assumed to be 1 (in raw format).
00480  * @note The parameter extended WILL CHANGE ITS CONTENTS
00481  * @param cut pointer to an #MTcut_t structure, we will store the compresed cut
00482  * here.
00483  * @param sol asociated node solution
00484  * @param extended extended cut (length #MTlp_t::nrows + #MTlp_t::ncols), note
00485  * that this informnation will be modified, and will contain the complemented
00486  * cut in extended form. 
00487  * @param lp pointer to the related #MTlp_t structure
00488  * @return zero on success, non-zero otherwise.
00489  * */
00490 int MTraw_to_complemented_cut(
00491     const MTlp_t*const lp,
00492     const MTsol_t*const sol,
00493     double*const extended,
00494     MTcut_t*const cut);
00495 /* ========================================================================= */
00496 /** @brief transform an extened non-complemented cut to a compresed for. We
00497  * assume the extended cut is of the form ax >= 1.m 
00498  * Note that we expect no coefficient for basic variables in the cut.
00499  * @note The parameter extended WILL NOT CHANGE ITS CONTENTS
00500  * @param cut pointer to an #MTcut_t structure, we will store the compresed cut
00501  * here.
00502  * @param extended extended cut (length #MTlp_t::nrows + #MTlp_t::ncols), note
00503  * that this informnation will be modified, and will contain the complemented
00504  * cut in extended form. 
00505  * @param nactive length of array active
00506  * @param active if not null, it should store the positions of possibly active
00507  * positions in extended; all positions outside it are assumed to be zero.
00508  * @param lp pointer to the related #MTlp_t structure
00509  * @param status if status is zero, the cut should be stored, otherwise, it
00510  * should be discarded.
00511  * @return zero on success, non-zero otherwise.
00512  * */
00513 int MTraw_to_uncomplemented_cut(
00514     const MTlp_t*const lp,
00515     const double*const extended,
00516     const int nactive,
00517     const int*const active,
00518     MTcut_t*const cut,
00519     int*const status);
00520 /* ========================================================================= */
00521 /** @brief obtain a solution to the current node LP 
00522  * @param lp pointer to an #MTlp_t structure
00523  * @param env Cplex environment pointer.
00524  * @param CPXlp cplex lp pointer.
00525  * @param sol where to store the solution
00526  * @param CPLEX callback cbdata.
00527  * @param wherefrom CPLEX callback wherefrom parameter.
00528  * @return zero on success, non-zero otherwise
00529  * */
00530 int MTget_sol(const MTlp_t*const lp,
00531               CPXCENVptr env,
00532               CPXLPptr CPXlp,
00533               void*cbdata,
00534               int wherefrom,
00535               MTsol_t*const sol);
00536 /* ========================================================================= */
00537 /** @biref if we have CPLEX 11 or later, we use sense as 'g' instead of 'G',
00538  * because, in theory, it enables cutpool management, we will see */
00539 #if CPX_VERSION >= 1100
00540 #define MT_CPLEX_SENSE 'g'
00541 #else
00542 #define MT_CPLEX_SENSE 'G'
00543 #endif
00544 /* ========================================================================= */
00545 /** @brief initialize an #MTns_ccbk_t structure */
00546 #define MTns_ccbk_init(__ns_ccbk) do{\
00547   MTns_ccbk_t*const __MTns_ccbk = (__ns_ccbk);\
00548   memset(__MTns_ccbk,0,sizeof(MTns_ccbk_t));}while(0)
00549 /* ========================================================================= */
00550 /** @brief resize node-solve arrays */
00551 #define MTns_ccbk_rsz(__ns_ccbk,__ncsz,__nrsz) do{\
00552   MTns_ccbk_t*const __MTns_ccbk = (__ns_ccbk);\
00553   const size_t __MTns_ncsz = (size_t)(__ncsz);\
00554   const size_t __MTns_nrsz = (size_t)(__nrsz);\
00555   if( __MTns_ccbk->rsz < __MTns_nrsz){\
00556     __MTns_ccbk->rsz = __MTns_nrsz;\
00557     __MTns_ccbk->rfix = EGrealloc(__MTns_ccbk->rfix,sizeof(char)*__MTns_nrsz);\
00558     __MTns_ccbk->rstat = EGrealloc(__MTns_ccbk->rstat,sizeof(int)*__MTns_nrsz);\
00559     __MTns_ccbk->sense = EGrealloc(__MTns_ccbk->sense,sizeof(char)*__MTns_nrsz);\
00560     __MTns_ccbk->pi = EGrealloc(__MTns_ccbk->pi,sizeof(double)*__MTns_nrsz);}\
00561   if( __MTns_ccbk->csz < __MTns_ncsz){\
00562     __MTns_ccbk->csz = __MTns_ncsz;\
00563     __MTns_ccbk->oobj = EGrealloc(__MTns_ccbk->oobj,sizeof(double)*__MTns_ncsz);\
00564     __MTns_ccbk->lb = EGrealloc(__MTns_ccbk->lb,sizeof(double)*__MTns_ncsz);\
00565     __MTns_ccbk->ub = EGrealloc(__MTns_ccbk->ub,sizeof(double)*__MTns_ncsz);\
00566     __MTns_ccbk->x0 = EGrealloc(__MTns_ccbk->x0,sizeof(double)*__MTns_ncsz);\
00567     __MTns_ccbk->x1 = EGrealloc(__MTns_ccbk->x1,sizeof(double)*__MTns_ncsz);\
00568     __MTns_ccbk->cfix = EGrealloc(__MTns_ccbk->cfix,sizeof(char)*__MTns_ncsz);\
00569     __MTns_ccbk->cstat = EGrealloc(__MTns_ccbk->cstat,sizeof(int)*__MTns_ncsz);\
00570     __MTns_ccbk->matind = EGrealloc(__MTns_ccbk->matind,sizeof(int)*__MTns_ncsz);\
00571     __MTns_ccbk->matval = EGrealloc(__MTns_ccbk->matval,sizeof(double)*__MTns_ncsz);\
00572     __MTns_ccbk->dj = EGrealloc(__MTns_ccbk->dj,sizeof(double)*__MTns_ncsz);\
00573     }\
00574   }while(0)
00575 /* ========================================================================= */
00576 /** @brief clear any internally allocated memory within an #MTns_ccbk_t
00577  * structure. */
00578 #define MTns_ccbk_clear(__ns_ccbk) do{\
00579   MTns_ccbk_t*const __MTns_ccbk = (__ns_ccbk);\
00580   EGfree(__MTns_ccbk->rfix);\
00581   EGfree(__MTns_ccbk->pi);\
00582   EGfree(__MTns_ccbk->cfix);\
00583   EGfree(__MTns_ccbk->dj);\
00584   EGfree(__MTns_ccbk->rstat);\
00585   EGfree(__MTns_ccbk->sense);\
00586   EGfree(__MTns_ccbk->oobj);\
00587   EGfree(__MTns_ccbk->lb);\
00588   EGfree(__MTns_ccbk->ub);\
00589   EGfree(__MTns_ccbk->x1);\
00590   EGfree(__MTns_ccbk->x0);\
00591   EGfree(__MTns_ccbk->matind);\
00592   EGfree(__MTns_ccbk->matval);\
00593   EGfree(__MTns_ccbk->cstat);}while(0)
00594 /* ========================================================================= */
00595 /** @brief Display stats in the given #MTns_ccbk_t structure */
00596 #define MTns_ccbk_display(__ns_ccbk) do{\
00597   const MTns_ccbk_t*const __MTns = (__ns_ccbk);\
00598   const double __MTd = ((double)(__MTns->nzrd))/((double)__MTns->ncalls);\
00599   const double __MTd2 = ((double)(__MTns->loops))/((double)__MTns->ncalls);\
00600   fprintf(stderr,"\tAverage solution difference  %.7le in %zd calls\n",__MTns->xdiff/((double)__MTns->ncalls),__MTns->ncalls);\
00601   fprintf(stderr,"\tAverage Primal degenerancy   %.4lf in %zd calls\n",__MTd,__MTns->ncalls);\
00602   fprintf(stderr,"\tAverage Reoptimization steps %.4lf in %zd calls\n",__MTd2,__MTns->ncalls);}while(0)
00603 /* ========================================================================= */
00604 /** @brief simple node solve callback, we use it to count primal degenerancy,
00605  * i.e. the number of variables with zero reduced cost, this should indicate
00606  * posibility of doing nested objective funcions to avoid primal degenerancy */
00607 int MTnode_solve( CPXCENVptr env, 
00608                   void*cbdata,
00609                   int wherefrom, 
00610                   void*cbhandle, 
00611                   int*useraction_p);
00612 /* ========================================================================= */
00613 /** @brief given a tableau in extended notation, verify that it is indeed a
00614  * numerically stable and correct tableau. 
00615  * @param tableau table to check
00616  * @param lp Internal LP description
00617  * @param status on return zero fi everything is OK, non-zero otherwise.
00618  * @param ratio if status==0, store the ratio for the tableau.
00619  * @param etnz if status == 0, store the number of non-zeros in the tableau
00620  * @return 0 on success, non-zero otherwise
00621  * */
00622 int MTcheckTabrow(
00623     const MTlp_t*const lp,
00624     const double*tableau,
00625     int*const status,
00626     double*const ratio,
00627     int*const etnz);
00628 /* ========================================================================= */
00629 /** @brief given a tableau row in extended format, store it as a compresed form, it include setting row to row - integer_part[row] and updating the rhs.
00630  * @param lp internal LP description,
00631  * @param sol current optimal solution.
00632  * @param rowval on input extended row description, on output, non-zeros
00633  * coefficients
00634  * @param rowind array of length ncols where we will store the indices of
00635  * non-zero coefficients in the row
00636  * @param nz on output, non-zeros found
00637  * @return zero on success, non-zero otherwise */
00638 int MTcompressTabRow(
00639     const MTlp_t*const lp,
00640     const MTsol_t*const sol,
00641     double*rowval,
00642     int*rowind,
00643     double*const rhs,
00644     int*const nz);
00645 /* ========================================================================= */
00646 /** @} */
00647 /* end of mt_cplex_cbk.h */
00648 #endif

Generated on Mon Oct 26 09:16:29 2009 for MTgomory by  doxygen 1.4.6