stat.h 14.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*                                                                           */
/*                  This file is part of the program and library             */
/*         SCIP --- Solving Constraint Integer Programs                      */
/*                                                                           */
/*    Copyright (C) 2002-2020 Konrad-Zuse-Zentrum                            */
/*                            fuer Informationstechnik Berlin                */
/*                                                                           */
/*  SCIP is distributed under the terms of the ZIB Academic License.         */
/*                                                                           */
/*  You should have received a copy of the ZIB Academic License              */
/*  along with SCIP; see the file COPYING. If not visit scipopt.org.         */
/*                                                                           */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

/**@file   stat.h
 * @ingroup INTERNALAPI
 * @brief  internal methods for problem statistics
 * @author Tobias Achterberg
 */

/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/

#ifndef __SCIP_STAT_H__
#define __SCIP_STAT_H__


#include "scip/def.h"
#include "blockmemshell/memory.h"
#include "scip/type_prob.h"
#include "scip/type_retcode.h"
#include "scip/type_set.h"
#include "scip/type_stat.h"
#include "scip/type_mem.h"
#include "scip/pub_message.h"
#include "scip/concurrent.h"

#include "scip/struct_stat.h"

#ifdef __cplusplus
extern "C" {
#endif

/** creates problem statistics data */
SCIP_RETCODE SCIPstatCreate(
   SCIP_STAT**           stat,               /**< pointer to problem statistics data */
   BMS_BLKMEM*           blkmem,             /**< block memory */
   SCIP_SET*             set,                /**< global SCIP settings */
   SCIP_PROB*            transprob,          /**< transformed problem, or NULL */
   SCIP_PROB*            origprob,           /**< original problem, or NULL */
   SCIP_MESSAGEHDLR*     messagehdlr         /**< message handler */
   );

/** frees problem statistics data */
SCIP_RETCODE SCIPstatFree(
   SCIP_STAT**           stat,               /**< pointer to problem statistics data */
   BMS_BLKMEM*           blkmem              /**< block memory */
   );

/** diables the collection of any statistic for a variable */
void SCIPstatDisableVarHistory(
   SCIP_STAT*            stat                /**< problem statistics data */
   );

/** enables the collection of statistics for a variable */
void SCIPstatEnableVarHistory(
   SCIP_STAT*            stat                /**< problem statistics data */
   );

/** marks statistics to be able to reset them when solving process is freed */
void SCIPstatMark(
   SCIP_STAT*            stat                /**< problem statistics data */
   );

/** reset statistics to the data before solving started */
void SCIPstatReset(
   SCIP_STAT*            stat,               /**< problem statistics data */
   SCIP_SET*             set,                /**< global SCIP settings */
   SCIP_PROB*            transprob,          /**< transformed problem, or NULL */
   SCIP_PROB*            origprob            /**< original problem, or NULL */
   );

/** reset implication counter */
void SCIPstatResetImplications(
   SCIP_STAT*            stat                /**< problem statistics data */
   );

/** reset presolving and current run specific statistics */
void SCIPstatResetPresolving(
   SCIP_STAT*            stat,               /**< problem statistics data */
   SCIP_SET*             set,                /**< global SCIP settings */
   SCIP_PROB*            transprob,          /**< transformed problem, or NULL */
   SCIP_PROB*            origprob            /**< original problem, or NULL */
   );

/** reset primal-dual, primal-reference, and dual-reference integral */
void SCIPstatResetPrimalDualIntegrals(
   SCIP_STAT*            stat,               /**< problem statistics data */
   SCIP_SET*             set,                /**< global SCIP settings */
   SCIP_Bool             partialreset        /**< should time and integral value be kept? (in combination with no statistical
                                              *  reset, integrals are added for each problem to be solved) */
   );

/** update the primal-dual, primal-reference, and reference-dual integral statistics.
 *  method accepts + and - SCIPsetInfinity() as values for upper and lower bound, respectively
 */
void SCIPstatUpdatePrimalDualIntegrals(
   SCIP_STAT*            stat,               /**< problem statistics data */
   SCIP_SET*             set,                /**< global SCIP settings */
   SCIP_PROB*            transprob,          /**< transformed problem */
   SCIP_PROB*            origprob,           /**< original problem */
   SCIP_Real             primalbound,        /**< current primal bound in transformed problem, or infinity */
   SCIP_Real             dualbound           /**< current lower bound in transformed space, or -infinity */
   );

/** optionally update and return the reference-dual integral statistic */
SCIP_Real SCIPstatGetDualReferenceIntegral(
   SCIP_STAT*            stat,               /**< problem statistics data */
   SCIP_SET*             set,                /**< global SCIP settings */
   SCIP_PROB*            transprob,          /**< transformed problem */
   SCIP_PROB*            origprob,           /**< original problem */
   SCIP_Bool             update              /**< should the value be updated first? */
   );

/** optionally update and return the primal-reference integral statistic */
SCIP_Real SCIPstatGetPrimalReferenceIntegral(
   SCIP_STAT*            stat,               /**< problem statistics data */
   SCIP_SET*             set,                /**< global SCIP settings */
   SCIP_PROB*            transprob,          /**< transformed problem */
   SCIP_PROB*            origprob,           /**< original problem */
   SCIP_Bool             update              /**< should the value be updated first? */
   );

/** optionally update and return the primal-dual integral statistic */
SCIP_Real SCIPstatGetPrimalDualIntegral(
   SCIP_STAT*            stat,               /**< problem statistics data */
   SCIP_SET*             set,                /**< global SCIP settings */
   SCIP_PROB*            transprob,          /**< transformed problem */
   SCIP_PROB*            origprob,           /**< original problem */
   SCIP_Bool             update              /**< should the value be updated first? */
   );

/** reset current branch and bound run specific statistics */
void SCIPstatResetCurrentRun(
   SCIP_STAT*            stat,               /**< problem statistics data */
   SCIP_SET*             set,                /**< global SCIP settings */
   SCIP_PROB*            transprob,          /**< transformed problem, or NULL */
   SCIP_PROB*            origprob,           /**< original problem, or NULL */
   SCIP_Bool             solved              /**< is problem already solved? */
   );

/** resets display statistics, such that a new header line is displayed before the next display line */
void SCIPstatResetDisplay(
   SCIP_STAT*            stat                /**< problem statistics data */
   );

/** increases LP count, such that all lazy updates depending on the LP are enforced again */
void SCIPstatEnforceLPUpdates(
   SCIP_STAT*            stat                /**< problem statistics data */
   );

/** depending on the current memory usage, switches mode flag to standard or memory saving mode */
void SCIPstatUpdateMemsaveMode(
   SCIP_STAT*            stat,               /**< problem statistics data */
   SCIP_SET*             set,                /**< global SCIP settings */
   SCIP_MESSAGEHDLR*     messagehdlr,        /**< message handler */
   SCIP_MEM*             mem                 /**< block memory pools */
   );

/** returns the estimated number of bytes used by extern software, e.g., the LP solver */
SCIP_Longint SCIPstatGetMemExternEstim(
   SCIP_STAT*            stat                /**< dynamic SCIP statistics */
   );

/** enables or disables all statistic clocks of \p stat concerning LP execution time, strong branching time, etc.
 *
 *  @note: The (pre-)solving time clocks which are relevant for the output during (pre-)solving
 *         are not affected by this method
 *
 *  @see: For completely disabling all timing of SCIP, consider setting the parameter timing/enabled to FALSE
 */
void SCIPstatEnableOrDisableStatClocks(
   SCIP_STAT*            stat,               /**< SCIP statistics */
   SCIP_Bool             enable              /**< should the LP clocks be enabled? */
   );

/** recompute root LP best-estimate from scratch */
void SCIPstatComputeRootLPBestEstimate(
   SCIP_STAT*            stat,               /**< SCIP statistics */
   SCIP_SET*             set,                /**< global SCIP settings */
   SCIP_Real             rootlpobjval,       /**< root LP objective value */
   SCIP_VAR**            vars,               /**< problem variables */
   int                   nvars               /**< number of variables */
   );

/** update root LP best-estimate with changed variable pseudo-costs */
SCIP_RETCODE SCIPstatUpdateVarRootLPBestEstimate(
   SCIP_STAT*            stat,               /**< SCIP statistics */
   SCIP_SET*             set,                /**< global SCIP settings */
   SCIP_VAR*             var,                /**< variable with changed pseudo costs */
   SCIP_Real             oldrootpscostscore  /**< old minimum pseudo cost score of variable */
   );

#ifdef TPI_NONE
/* no TPI included so just update the stats */

#define SCIPstatUpdate(stat, set, field, val) do { \
  (stat)->field = (val); \
  } while(0)

#define SCIPstatIncrement(stat, set, field) do { \
   ++(stat)->field; \
   } while(0)

#define SCIPstatAdd(stat, set, field, val) do { \
   (stat)->field += (val); \
   } while(0)

#else
/* TPI not none, so increment deterministic time for relevant stats */

#define SCIPupdateDeterministicTimeCount(stat, set, val) do { \
        (stat)->detertimecnt += (val); \
        if( (stat)->detertimecnt > 10000.0 ) { \
           SCIP_CALL_ABORT( SCIPincrementConcurrentTime( (set)->scip, (stat)->detertimecnt ) ); \
           (stat)->detertimecnt = 0.0;                                  \
        }\
    } while(0) \

#define SCIPstatUpdate(stat, set, field, val) do { \
   switch( offsetof(SCIP_STAT, field) ) \
   { \
      default: \
         break; \
      case offsetof(SCIP_STAT, nprimalresolvelpiterations): \
         SCIPupdateDeterministicTimeCount(stat, set, 0.00328285264101 * ((val) - (stat)->field) * (stat)->nnz ); \
         break; \
      case offsetof(SCIP_STAT, ndualresolvelpiterations): \
         SCIPupdateDeterministicTimeCount(stat, set, 0.00531625104146 * ((val) - (stat)->field) * (stat)->nnz ); \
         break; \
      case offsetof(SCIP_STAT, nprobboundchgs): \
         SCIPupdateDeterministicTimeCount(stat, set, 0.000738719124051 * ((val) - (stat)->field) * (stat)->nnz ); \
         break; \
      case offsetof(SCIP_STAT, nisstoppedcalls): \
         SCIPupdateDeterministicTimeCount(stat, set, 0.0011123144764 * ((val) - (stat)->field) * (stat)->nnz ); \
   } \
   (stat)->field = (val); \
   } while(0)


#define SCIPstatIncrement(stat, set, field) do { \
   switch( offsetof(SCIP_STAT, field) ) \
   { \
      default: \
         break; \
      case offsetof(SCIP_STAT, nprimalresolvelpiterations): \
         SCIPupdateDeterministicTimeCount(stat, set, 0.00328285264101 * (stat)->nnz ); \
         break; \
      case offsetof(SCIP_STAT, ndualresolvelpiterations): \
         SCIPupdateDeterministicTimeCount(stat, set, 0.00531625104146 * (stat)->nnz ); \
         break; \
      case offsetof(SCIP_STAT, nprobboundchgs): \
         SCIPupdateDeterministicTimeCount(stat, set, 0.000738719124051 * (stat)->nnz ); \
         break; \
      case offsetof(SCIP_STAT, nisstoppedcalls): \
         SCIPupdateDeterministicTimeCount(stat, set, 0.0011123144764 * (stat)->nnz ); \
   } \
   ++(stat)->field; \
   } while(0)

#define SCIPstatAdd(stat, set, field, val) do { \
   switch( offsetof(SCIP_STAT, field) ) \
   { \
      default: \
         break; \
      case offsetof(SCIP_STAT, nprimalresolvelpiterations): \
         SCIPupdateDeterministicTimeCount(stat, set, 0.00328285264101 * (val) * (stat)->nnz); \
         break; \
      case offsetof(SCIP_STAT, ndualresolvelpiterations): \
         SCIPupdateDeterministicTimeCount(stat, set, 0.00531625104146 * (val) * (stat)->nnz); \
         break; \
      case offsetof(SCIP_STAT, nprobboundchgs): \
         SCIPupdateDeterministicTimeCount(stat, set, 0.000738719124051 * (val) * (stat)->nnz ); \
         break; \
      case offsetof(SCIP_STAT, nisstoppedcalls): \
         SCIPupdateDeterministicTimeCount(stat, set, 0.0011123144764 * (val) * (stat)->nnz ); \
   } \
   (stat)->field += (val); \
   } while(0)
#endif


/* if we have a C99 compiler */
#ifdef SCIP_HAVE_VARIADIC_MACROS

/** prints a debugging message if SCIP_DEBUG flag is set */
#ifdef SCIP_DEBUG
#define SCIPstatDebugMsg(set, ...)      SCIPstatPrintDebugMessage(stat, __FILE__, __LINE__, __VA_ARGS__)
#define SCIPstatDebugMsgPrint(set, ...) SCIPstatPrintDebugMessagePrint(stat, __VA_ARGS__)
#else
#define SCIPstatDebugMsg(set, ...)      while ( FALSE ) SCIPstatPrintDebugMessage(stat, __FILE__, __LINE__, __VA_ARGS__)
#define SCIPstatDebugMsgPrint(set, ...) while ( FALSE ) SCIPstatPrintDebugMessagePrint(stat, __VA_ARGS__)
#endif

#else
/* if we do not have a C99 compiler, use a workaround that prints a message, but not the file and linenumber */

/** prints a debugging message if SCIP_DEBUG flag is set */
#ifdef SCIP_DEBUG
#define SCIPstatDebugMsg                printf("debug: "), SCIPstatDebugMessagePrint
#define SCIPstatDebugMsgPrint           SCIPstatDebugMessagePrint
#else
#define SCIPstatDebugMsg                while ( FALSE ) SCIPstatDebugMessagePrint
#define SCIPstatDebugMsgPrint           while ( FALSE ) SCIPstatDebugMessagePrint
#endif

#endif


/** prints a debug message */
SCIP_EXPORT
void SCIPstatPrintDebugMessage(
   SCIP_STAT*            stat,               /**< SCIP statistics */
   const char*           sourcefile,         /**< name of the source file that called the function */
   int                   sourceline,         /**< line in the source file where the function was called */
   const char*           formatstr,          /**< format string like in printf() function */
   ...                                       /**< format arguments line in printf() function */
   );

/** prints a debug message without precode */
SCIP_EXPORT
void SCIPstatDebugMessagePrint(
   SCIP_STAT*            stat,               /**< SCIP statistics */
   const char*           formatstr,          /**< format string like in printf() function */
   ...                                       /**< format arguments line in printf() function */
   );

#ifdef __cplusplus
}
#endif

#endif