1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 2 /* */ 3 /* This file is part of the program and library */ 4 /* SCIP --- Solving Constraint Integer Programs */ 5 /* */ 6 /* Copyright (c) 2002-2023 Zuse Institute Berlin (ZIB) */ 7 /* */ 8 /* Licensed under the Apache License, Version 2.0 (the "License"); */ 9 /* you may not use this file except in compliance with the License. */ 10 /* You may obtain a copy of the License at */ 11 /* */ 12 /* http://www.apache.org/licenses/LICENSE-2.0 */ 13 /* */ 14 /* Unless required by applicable law or agreed to in writing, software */ 15 /* distributed under the License is distributed on an "AS IS" BASIS, */ 16 /* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ 17 /* See the License for the specific language governing permissions and */ 18 /* limitations under the License. */ 19 /* */ 20 /* You should have received a copy of the Apache-2.0 license */ 21 /* along with SCIP; see the file LICENSE. If not visit scipopt.org. */ 22 /* */ 23 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 24 25 /**@file scip_solvingstats.c 26 * @ingroup OTHER_CFILES 27 * @brief public methods for querying solving statistics 28 * @author Tobias Achterberg 29 * @author Timo Berthold 30 * @author Gerald Gamrath 31 * @author Leona Gottwald 32 * @author Stefan Heinz 33 * @author Gregor Hendel 34 * @author Thorsten Koch 35 * @author Alexander Martin 36 * @author Marc Pfetsch 37 * @author Michael Winkler 38 * @author Kati Wolter 39 * 40 * @todo check all SCIP_STAGE_* switches, and include the new stages TRANSFORMED and INITSOLVE 41 */ 42 43 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/ 44 45 #include "blockmemshell/memory.h" 46 #include "scip/branch.h" 47 #include "scip/clock.h" 48 #include "scip/concsolver.h" 49 #include "scip/concurrent.h" 50 #include "scip/conflict.h" 51 #include "scip/conflictstore.h" 52 #include "scip/debug.h" 53 #include "scip/disp.h" 54 #include "scip/history.h" 55 #include "scip/implics.h" 56 #include "scip/pricestore.h" 57 #include "scip/primal.h" 58 #include "scip/prob.h" 59 #include "scip/pub_benderscut.h" 60 #include "scip/pub_benders.h" 61 #include "scip/pub_branch.h" 62 #include "scip/pub_compr.h" 63 #include "scip/pub_cons.h" 64 #include "scip/pub_cutpool.h" 65 #include "scip/pub_cutsel.h" 66 #include "scip/pub_expr.h" 67 #include "scip/pub_heur.h" 68 #include "scip/pub_history.h" 69 #include "scip/pub_message.h" 70 #include "scip/pub_misc.h" 71 #include "scip/pub_misc_sort.h" 72 #include "scip/pub_nlpi.h" 73 #include "scip/pub_presol.h" 74 #include "scip/pub_pricer.h" 75 #include "scip/pub_prop.h" 76 #include "scip/pub_reader.h" 77 #include "scip/pub_relax.h" 78 #include "scip/pub_reopt.h" 79 #include "scip/pub_sepa.h" 80 #include "scip/pub_sol.h" 81 #include "scip/pub_table.h" 82 #include "scip/pub_var.h" 83 #include "scip/reader.h" 84 #include "scip/reopt.h" 85 #include "scip/scip_benders.h" 86 #include "scip/scip_general.h" 87 #include "scip/scip_mem.h" 88 #include "scip/scip_message.h" 89 #include "scip/scip_nlp.h" 90 #include "scip/scip_numerics.h" 91 #include "scip/scip_sol.h" 92 #include "scip/scip_solvingstats.h" 93 #include "scip/scip_table.h" 94 #include "scip/scip_timing.h" 95 #include "scip/scip_var.h" 96 #include "scip/sepastore.h" 97 #include "scip/set.h" 98 #include "scip/sol.h" 99 #include "scip/stat.h" 100 #include "scip/struct_mem.h" 101 #include "scip/struct_primal.h" 102 #include "scip/struct_prob.h" 103 #include "scip/struct_scip.h" 104 #include "scip/struct_set.h" 105 #include "scip/struct_stat.h" 106 #include "scip/syncstore.h" 107 #include "scip/table.h" 108 #include "scip/tree.h" 109 #include "scip/var.h" 110 #include <string.h> 111 112 /** gets number of branch and bound runs performed, including the current run 113 * 114 * @return the number of branch and bound runs performed, including the current run 115 * 116 * @pre This method can be called if SCIP is in one of the following stages: 117 * - \ref SCIP_STAGE_PROBLEM 118 * - \ref SCIP_STAGE_TRANSFORMING 119 * - \ref SCIP_STAGE_TRANSFORMED 120 * - \ref SCIP_STAGE_INITPRESOLVE 121 * - \ref SCIP_STAGE_PRESOLVING 122 * - \ref SCIP_STAGE_EXITPRESOLVE 123 * - \ref SCIP_STAGE_PRESOLVED 124 * - \ref SCIP_STAGE_INITSOLVE 125 * - \ref SCIP_STAGE_SOLVING 126 * - \ref SCIP_STAGE_SOLVED 127 * - \ref SCIP_STAGE_EXITSOLVE 128 * - \ref SCIP_STAGE_FREETRANS 129 */ 130 int SCIPgetNRuns( 131 SCIP* scip /**< SCIP data structure */ 132 ) 133 { 134 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNRuns", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 135 136 return scip->stat->nruns; 137 } 138 139 /** gets number of reoptimization runs performed, including the current run 140 * 141 * @return the number of reoptimization runs performed, including the current run 142 * 143 * @pre This method can be called if SCIP is in one of the following stages: 144 * - \ref SCIP_STAGE_PROBLEM 145 * - \ref SCIP_STAGE_TRANSFORMING 146 * - \ref SCIP_STAGE_TRANSFORMED 147 * - \ref SCIP_STAGE_INITPRESOLVE 148 * - \ref SCIP_STAGE_PRESOLVING 149 * - \ref SCIP_STAGE_EXITPRESOLVE 150 * - \ref SCIP_STAGE_PRESOLVED 151 * - \ref SCIP_STAGE_INITSOLVE 152 * - \ref SCIP_STAGE_SOLVING 153 * - \ref SCIP_STAGE_SOLVED 154 * - \ref SCIP_STAGE_EXITSOLVE 155 * - \ref SCIP_STAGE_FREETRANS 156 */ 157 int SCIPgetNReoptRuns( 158 SCIP* scip /**< SCIP data structure */ 159 ) 160 { 161 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNReoptRuns", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 162 163 return scip->stat->nreoptruns; 164 } 165 166 /** add given number to the number of processed nodes in current run and in all runs, including the focus node 167 * 168 * @return the number of processed nodes in current run, including the focus node 169 * 170 * @pre This method can be called if SCIP is in one of the following stages: 171 * - \ref SCIP_STAGE_PROBLEM 172 * - \ref SCIP_STAGE_TRANSFORMING 173 * - \ref SCIP_STAGE_TRANSFORMED 174 * - \ref SCIP_STAGE_INITPRESOLVE 175 * - \ref SCIP_STAGE_PRESOLVING 176 * - \ref SCIP_STAGE_EXITPRESOLVE 177 * - \ref SCIP_STAGE_PRESOLVED 178 * - \ref SCIP_STAGE_INITSOLVE 179 * - \ref SCIP_STAGE_SOLVING 180 * - \ref SCIP_STAGE_SOLVED 181 * - \ref SCIP_STAGE_EXITSOLVE 182 * - \ref SCIP_STAGE_FREETRANS 183 */ 184 void SCIPaddNNodes( 185 SCIP* scip, /**< SCIP data structure */ 186 SCIP_Longint nnodes /**< number of processed nodes to add to the statistics */ 187 ) 188 { 189 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPaddNNodes", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 190 191 scip->stat->nnodes += nnodes; 192 scip->stat->ntotalnodes += nnodes; 193 } 194 195 /** gets number of processed nodes in current run, including the focus node 196 * 197 * @return the number of processed nodes in current run, including the focus node 198 * 199 * @pre This method can be called if SCIP is in one of the following stages: 200 * - \ref SCIP_STAGE_PROBLEM 201 * - \ref SCIP_STAGE_TRANSFORMING 202 * - \ref SCIP_STAGE_TRANSFORMED 203 * - \ref SCIP_STAGE_INITPRESOLVE 204 * - \ref SCIP_STAGE_PRESOLVING 205 * - \ref SCIP_STAGE_EXITPRESOLVE 206 * - \ref SCIP_STAGE_PRESOLVED 207 * - \ref SCIP_STAGE_INITSOLVE 208 * - \ref SCIP_STAGE_SOLVING 209 * - \ref SCIP_STAGE_SOLVED 210 * - \ref SCIP_STAGE_EXITSOLVE 211 * - \ref SCIP_STAGE_FREETRANS 212 */ 213 SCIP_Longint SCIPgetNNodes( 214 SCIP* scip /**< SCIP data structure */ 215 ) 216 { 217 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNNodes", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 218 219 return scip->stat->nnodes; 220 } 221 222 /** gets total number of processed nodes in all runs, including the focus node 223 * 224 * @return the total number of processed nodes in all runs, including the focus node 225 * 226 * @pre This method can be called if SCIP is in one of the following stages: 227 * - \ref SCIP_STAGE_PROBLEM 228 * - \ref SCIP_STAGE_TRANSFORMING 229 * - \ref SCIP_STAGE_TRANSFORMED 230 * - \ref SCIP_STAGE_INITPRESOLVE 231 * - \ref SCIP_STAGE_PRESOLVING 232 * - \ref SCIP_STAGE_EXITPRESOLVE 233 * - \ref SCIP_STAGE_PRESOLVED 234 * - \ref SCIP_STAGE_INITSOLVE 235 * - \ref SCIP_STAGE_SOLVING 236 * - \ref SCIP_STAGE_SOLVED 237 * - \ref SCIP_STAGE_EXITSOLVE 238 * - \ref SCIP_STAGE_FREETRANS 239 */ 240 SCIP_Longint SCIPgetNTotalNodes( 241 SCIP* scip /**< SCIP data structure */ 242 ) 243 { 244 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNTotalNodes", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 245 246 return scip->stat->ntotalnodes; 247 } 248 249 /** gets number of leaf nodes processed with feasible relaxation solution 250 * 251 * @return number of leaf nodes processed with feasible relaxation solution 252 * 253 * @pre This method can be called if SCIP is in one of the following stages: 254 * - \ref SCIP_STAGE_PROBLEM 255 * - \ref SCIP_STAGE_TRANSFORMING 256 * - \ref SCIP_STAGE_TRANSFORMED 257 * - \ref SCIP_STAGE_INITPRESOLVE 258 * - \ref SCIP_STAGE_PRESOLVING 259 * - \ref SCIP_STAGE_EXITPRESOLVE 260 * - \ref SCIP_STAGE_PRESOLVED 261 * - \ref SCIP_STAGE_INITSOLVE 262 * - \ref SCIP_STAGE_SOLVING 263 * - \ref SCIP_STAGE_SOLVED 264 * - \ref SCIP_STAGE_EXITSOLVE 265 * - \ref SCIP_STAGE_FREETRANS 266 */ 267 SCIP_Longint SCIPgetNFeasibleLeaves( 268 SCIP* scip /**< SCIP data structure */ 269 ) 270 { 271 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNFeasibleLeaves", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 272 273 return scip->stat->nfeasleaves; 274 } 275 276 /** gets number of infeasible leaf nodes processed 277 * 278 * @return number of infeasible leaf nodes processed 279 * 280 * @pre This method can be called if SCIP is in one of the following stages: 281 * - \ref SCIP_STAGE_PROBLEM 282 * - \ref SCIP_STAGE_TRANSFORMING 283 * - \ref SCIP_STAGE_TRANSFORMED 284 * - \ref SCIP_STAGE_INITPRESOLVE 285 * - \ref SCIP_STAGE_PRESOLVING 286 * - \ref SCIP_STAGE_EXITPRESOLVE 287 * - \ref SCIP_STAGE_PRESOLVED 288 * - \ref SCIP_STAGE_INITSOLVE 289 * - \ref SCIP_STAGE_SOLVING 290 * - \ref SCIP_STAGE_SOLVED 291 * - \ref SCIP_STAGE_EXITSOLVE 292 * - \ref SCIP_STAGE_FREETRANS 293 */ 294 SCIP_Longint SCIPgetNInfeasibleLeaves( 295 SCIP* scip /**< SCIP data structure */ 296 ) 297 { 298 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNInfeasibleLeaves", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 299 300 return scip->stat->ninfeasleaves; 301 } 302 303 /** gets number of processed leaf nodes that hit LP objective limit 304 * 305 * @return number of processed leaf nodes that hit LP objective limit 306 * 307 * @pre This method can be called if SCIP is in one of the following stages: 308 * - \ref SCIP_STAGE_PROBLEM 309 * - \ref SCIP_STAGE_TRANSFORMING 310 * - \ref SCIP_STAGE_TRANSFORMED 311 * - \ref SCIP_STAGE_INITPRESOLVE 312 * - \ref SCIP_STAGE_PRESOLVING 313 * - \ref SCIP_STAGE_EXITPRESOLVE 314 * - \ref SCIP_STAGE_PRESOLVED 315 * - \ref SCIP_STAGE_INITSOLVE 316 * - \ref SCIP_STAGE_SOLVING 317 * - \ref SCIP_STAGE_SOLVED 318 * - \ref SCIP_STAGE_EXITSOLVE 319 * - \ref SCIP_STAGE_FREETRANS 320 */ 321 SCIP_Longint SCIPgetNObjlimLeaves( 322 SCIP* scip /**< Scip data structure */ 323 ) 324 { 325 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNObjlimLeaves", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 326 327 return scip->stat->nobjleaves; 328 } 329 330 /** gets number of global bound changes 331 * 332 * @return number of global bound changes 333 * 334 * @pre This method can be called if SCIP is in one of the following stages: 335 * - \ref SCIP_STAGE_PROBLEM 336 * - \ref SCIP_STAGE_TRANSFORMING 337 * - \ref SCIP_STAGE_TRANSFORMED 338 * - \ref SCIP_STAGE_INITPRESOLVE 339 * - \ref SCIP_STAGE_PRESOLVING 340 * - \ref SCIP_STAGE_EXITPRESOLVE 341 * - \ref SCIP_STAGE_PRESOLVED 342 * - \ref SCIP_STAGE_INITSOLVE 343 * - \ref SCIP_STAGE_SOLVING 344 * - \ref SCIP_STAGE_SOLVED 345 * - \ref SCIP_STAGE_EXITSOLVE 346 * - \ref SCIP_STAGE_FREETRANS 347 */ 348 int SCIPgetNRootboundChgs( 349 SCIP* scip /**< Scip data structure */ 350 ) 351 { 352 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNRootboundChgs", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 353 354 return scip->stat->nrootboundchgs; 355 } 356 357 /** gets number of global bound changes applied in the current run 358 * 359 * @return number of global bound changes 360 * 361 * @pre This method can be called if SCIP is in one of the following stages: 362 * - \ref SCIP_STAGE_PROBLEM 363 * - \ref SCIP_STAGE_TRANSFORMING 364 * - \ref SCIP_STAGE_TRANSFORMED 365 * - \ref SCIP_STAGE_INITPRESOLVE 366 * - \ref SCIP_STAGE_PRESOLVING 367 * - \ref SCIP_STAGE_EXITPRESOLVE 368 * - \ref SCIP_STAGE_PRESOLVED 369 * - \ref SCIP_STAGE_INITSOLVE 370 * - \ref SCIP_STAGE_SOLVING 371 * - \ref SCIP_STAGE_SOLVED 372 * - \ref SCIP_STAGE_EXITSOLVE 373 * - \ref SCIP_STAGE_FREETRANS 374 */ 375 int SCIPgetNRootboundChgsRun( 376 SCIP* scip /**< Scip data structure */ 377 ) 378 { 379 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNRootboundChgsRun", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 380 381 return scip->stat->nrootboundchgsrun; 382 } 383 384 /** gets number of times a selected node was from a cut off subtree 385 * 386 * @return number of times a selected node was from a cut off subtree 387 * 388 * @pre This method can be called if SCIP is in one of the following stages: 389 * - \ref SCIP_STAGE_PROBLEM 390 * - \ref SCIP_STAGE_TRANSFORMING 391 * - \ref SCIP_STAGE_TRANSFORMED 392 * - \ref SCIP_STAGE_INITPRESOLVE 393 * - \ref SCIP_STAGE_PRESOLVING 394 * - \ref SCIP_STAGE_EXITPRESOLVE 395 * - \ref SCIP_STAGE_PRESOLVED 396 * - \ref SCIP_STAGE_INITSOLVE 397 * - \ref SCIP_STAGE_SOLVING 398 * - \ref SCIP_STAGE_SOLVED 399 * - \ref SCIP_STAGE_EXITSOLVE 400 * - \ref SCIP_STAGE_FREETRANS 401 */ 402 SCIP_Longint SCIPgetNDelayedCutoffs( 403 SCIP* scip /**< SCIP data structure */ 404 ) 405 { 406 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNDelayedCutoffs", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 407 408 return scip->stat->ndelayedcutoffs; 409 } 410 411 /** gets total number of LPs solved so far 412 * 413 * @return the total number of LPs solved so far 414 * 415 * @pre This method can be called if SCIP is in one of the following stages: 416 * - \ref SCIP_STAGE_PROBLEM 417 * - \ref SCIP_STAGE_TRANSFORMING 418 * - \ref SCIP_STAGE_TRANSFORMED 419 * - \ref SCIP_STAGE_INITPRESOLVE 420 * - \ref SCIP_STAGE_PRESOLVING 421 * - \ref SCIP_STAGE_EXITPRESOLVE 422 * - \ref SCIP_STAGE_PRESOLVED 423 * - \ref SCIP_STAGE_INITSOLVE 424 * - \ref SCIP_STAGE_SOLVING 425 * - \ref SCIP_STAGE_SOLVED 426 * - \ref SCIP_STAGE_EXITSOLVE 427 * - \ref SCIP_STAGE_FREETRANS 428 */ 429 SCIP_Longint SCIPgetNLPs( 430 SCIP* scip /**< SCIP data structure */ 431 ) 432 { 433 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNLPs", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 434 435 return scip->stat->nlps; 436 } 437 438 /** gets total number of iterations used so far in primal and dual simplex and barrier algorithm 439 * 440 * @return the total number of iterations used so far in primal and dual simplex and barrier algorithm 441 * 442 * @pre This method can be called if SCIP is in one of the following stages: 443 * - \ref SCIP_STAGE_PRESOLVING 444 * - \ref SCIP_STAGE_PRESOLVED 445 * - \ref SCIP_STAGE_SOLVING 446 * - \ref SCIP_STAGE_SOLVED 447 */ 448 SCIP_Longint SCIPgetNLPIterations( 449 SCIP* scip /**< SCIP data structure */ 450 ) 451 { 452 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNLPIterations", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 453 454 return scip->stat->nlpiterations; 455 } 456 457 /** gets number of active non-zeros in the current transformed problem 458 * 459 * @return the number of active non-zeros in the current transformed problem 460 * 461 * @pre This method can be called if SCIP is in one of the following stages: 462 * - \ref SCIP_STAGE_PROBLEM 463 * - \ref SCIP_STAGE_TRANSFORMING 464 * - \ref SCIP_STAGE_TRANSFORMED 465 * - \ref SCIP_STAGE_INITPRESOLVE 466 * - \ref SCIP_STAGE_PRESOLVING 467 * - \ref SCIP_STAGE_EXITPRESOLVE 468 * - \ref SCIP_STAGE_PRESOLVED 469 * - \ref SCIP_STAGE_INITSOLVE 470 * - \ref SCIP_STAGE_SOLVING 471 * - \ref SCIP_STAGE_SOLVED 472 * - \ref SCIP_STAGE_EXITSOLVE 473 */ 474 SCIP_Longint SCIPgetNNZs( 475 SCIP* scip /**< SCIP data structure */ 476 ) 477 { 478 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNNZs", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) ); 479 480 return scip->stat->nnz; 481 } 482 483 /** gets total number of iterations used so far in primal and dual simplex and barrier algorithm for the root node 484 * 485 * @return the total number of iterations used so far in primal and dual simplex and barrier algorithm for the root node 486 * 487 * @pre This method can be called if SCIP is in one of the following stages: 488 * - \ref SCIP_STAGE_PRESOLVED 489 * - \ref SCIP_STAGE_SOLVING 490 * - \ref SCIP_STAGE_SOLVED 491 */ 492 SCIP_Longint SCIPgetNRootLPIterations( 493 SCIP* scip /**< SCIP data structure */ 494 ) 495 { 496 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNRootLPIterations", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 497 498 return scip->stat->nrootlpiterations; 499 } 500 501 /** gets total number of iterations used in primal and dual simplex and barrier algorithm for the first LP at the root 502 * node 503 * 504 * @return the total number of iterations used in primal and dual simplex and barrier algorithm for the first root LP 505 * 506 * @pre This method can be called if SCIP is in one of the following stages: 507 * - \ref SCIP_STAGE_PRESOLVED 508 * - \ref SCIP_STAGE_SOLVING 509 * - \ref SCIP_STAGE_SOLVED 510 */ 511 SCIP_Longint SCIPgetNRootFirstLPIterations( 512 SCIP* scip /**< SCIP data structure */ 513 ) 514 { 515 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNRootFirstLPIterations", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 516 517 return scip->stat->nrootfirstlpiterations; 518 } 519 520 /** gets total number of primal LPs solved so far 521 * 522 * @return the total number of primal LPs solved so far 523 * 524 * @pre This method can be called if SCIP is in one of the following stages: 525 * - \ref SCIP_STAGE_PRESOLVED 526 * - \ref SCIP_STAGE_SOLVING 527 * - \ref SCIP_STAGE_SOLVED 528 */ 529 SCIP_Longint SCIPgetNPrimalLPs( 530 SCIP* scip /**< SCIP data structure */ 531 ) 532 { 533 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNPrimalLPs", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 534 535 return scip->stat->nprimallps; 536 } 537 538 /** gets total number of iterations used so far in primal simplex 539 * 540 * @return total number of iterations used so far in primal simplex 541 * 542 * @pre This method can be called if SCIP is in one of the following stages: 543 * - \ref SCIP_STAGE_PRESOLVED 544 * - \ref SCIP_STAGE_SOLVING 545 * - \ref SCIP_STAGE_SOLVED 546 */ 547 SCIP_Longint SCIPgetNPrimalLPIterations( 548 SCIP* scip /**< SCIP data structure */ 549 ) 550 { 551 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNPrimalLPIterations", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 552 553 return scip->stat->nprimallpiterations; 554 } 555 556 /** gets total number of dual LPs solved so far 557 * 558 * @return the total number of dual LPs solved so far 559 * 560 * @pre This method can be called if SCIP is in one of the following stages: 561 * - \ref SCIP_STAGE_PRESOLVED 562 * - \ref SCIP_STAGE_SOLVING 563 * - \ref SCIP_STAGE_SOLVED 564 */ 565 SCIP_Longint SCIPgetNDualLPs( 566 SCIP* scip /**< SCIP data structure */ 567 ) 568 { 569 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNDualLPs", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 570 571 return scip->stat->nduallps; 572 } 573 574 /** gets total number of iterations used so far in dual simplex 575 * 576 * @return the total number of iterations used so far in dual simplex 577 * 578 * @pre This method can be called if SCIP is in one of the following stages: 579 * - \ref SCIP_STAGE_PRESOLVED 580 * - \ref SCIP_STAGE_SOLVING 581 * - \ref SCIP_STAGE_SOLVED 582 */ 583 SCIP_Longint SCIPgetNDualLPIterations( 584 SCIP* scip /**< SCIP data structure */ 585 ) 586 { 587 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNDualLPIterations", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 588 589 return scip->stat->nduallpiterations; 590 } 591 592 /** gets total number of barrier LPs solved so far 593 * 594 * @return the total number of barrier LPs solved so far 595 * 596 * @pre This method can be called if SCIP is in one of the following stages: 597 * - \ref SCIP_STAGE_PRESOLVED 598 * - \ref SCIP_STAGE_SOLVING 599 * - \ref SCIP_STAGE_SOLVED 600 */ 601 SCIP_Longint SCIPgetNBarrierLPs( 602 SCIP* scip /**< SCIP data structure */ 603 ) 604 { 605 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNBarrierLPs", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 606 607 return scip->stat->nbarrierlps; 608 } 609 610 /** gets total number of iterations used so far in barrier algorithm 611 * 612 * @return the total number of iterations used so far in barrier algorithm 613 * 614 * @pre This method can be called if SCIP is in one of the following stages: 615 * - \ref SCIP_STAGE_PRESOLVED 616 * - \ref SCIP_STAGE_SOLVING 617 * - \ref SCIP_STAGE_SOLVED 618 */ 619 SCIP_Longint SCIPgetNBarrierLPIterations( 620 SCIP* scip /**< SCIP data structure */ 621 ) 622 { 623 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNBarrierLPIterations", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 624 625 return scip->stat->nbarrierlpiterations; 626 } 627 628 /** gets total number of LPs solved so far that were resolved from an advanced start basis 629 * 630 * @return the total number of LPs solved so far that were resolved from an advanced start basis 631 * 632 * @pre This method can be called if SCIP is in one of the following stages: 633 * - \ref SCIP_STAGE_PRESOLVED 634 * - \ref SCIP_STAGE_SOLVING 635 * - \ref SCIP_STAGE_SOLVED 636 */ 637 SCIP_Longint SCIPgetNResolveLPs( 638 SCIP* scip /**< SCIP data structure */ 639 ) 640 { 641 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNResolveLPs", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 642 643 return scip->stat->nprimalresolvelps + scip->stat->ndualresolvelps; 644 } 645 646 /** gets total number of simplex iterations used so far in primal and dual simplex calls where an advanced start basis 647 * was available 648 * 649 * @return the total number of simplex iterations used so far in primal and dual simplex calls where an advanced start 650 * basis was available 651 * 652 * @pre This method can be called if SCIP is in one of the following stages: 653 * - \ref SCIP_STAGE_PRESOLVED 654 * - \ref SCIP_STAGE_SOLVING 655 * - \ref SCIP_STAGE_SOLVED 656 */ 657 SCIP_Longint SCIPgetNResolveLPIterations( 658 SCIP* scip /**< SCIP data structure */ 659 ) 660 { 661 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNResolveLPIterations", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 662 663 return scip->stat->nprimalresolvelpiterations + scip->stat->ndualresolvelpiterations; 664 } 665 666 /** gets total number of primal LPs solved so far that were resolved from an advanced start basis 667 * 668 * @return the total number of primal LPs solved so far that were resolved from an advanced start basis 669 * 670 * @pre This method can be called if SCIP is in one of the following stages: 671 * - \ref SCIP_STAGE_PRESOLVED 672 * - \ref SCIP_STAGE_SOLVING 673 * - \ref SCIP_STAGE_SOLVED 674 */ 675 SCIP_Longint SCIPgetNPrimalResolveLPs( 676 SCIP* scip /**< SCIP data structure */ 677 ) 678 { 679 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNPrimalResolveLPs", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 680 681 return scip->stat->nprimalresolvelps; 682 } 683 684 /** gets total number of simplex iterations used so far in primal simplex calls where an advanced start basis 685 * was available 686 * 687 * @return the total number of simplex iterations used so far in primal simplex calls where an advanced start 688 * basis was available 689 * 690 * @pre This method can be called if SCIP is in one of the following stages: 691 * - \ref SCIP_STAGE_PRESOLVED 692 * - \ref SCIP_STAGE_SOLVING 693 * - \ref SCIP_STAGE_SOLVED 694 */ 695 SCIP_Longint SCIPgetNPrimalResolveLPIterations( 696 SCIP* scip /**< SCIP data structure */ 697 ) 698 { 699 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNPrimalResolveLPIterations", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 700 701 return scip->stat->nprimalresolvelpiterations; 702 } 703 704 /** gets total number of dual LPs solved so far that were resolved from an advanced start basis 705 * 706 * @return the total number of dual LPs solved so far that were resolved from an advanced start basis 707 * 708 * @pre This method can be called if SCIP is in one of the following stages: 709 * - \ref SCIP_STAGE_PRESOLVED 710 * - \ref SCIP_STAGE_SOLVING 711 * - \ref SCIP_STAGE_SOLVED 712 */ 713 SCIP_Longint SCIPgetNDualResolveLPs( 714 SCIP* scip /**< SCIP data structure */ 715 ) 716 { 717 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNDualResolveLPs", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 718 719 return scip->stat->ndualresolvelps; 720 } 721 722 /** gets total number of simplex iterations used so far in dual simplex calls where an advanced start basis 723 * was available 724 * 725 * @return the total number of simplex iterations used so far in dual simplex calls where an advanced start 726 * basis was available 727 * 728 * @pre This method can be called if SCIP is in one of the following stages: 729 * - \ref SCIP_STAGE_PRESOLVED 730 * - \ref SCIP_STAGE_SOLVING 731 * - \ref SCIP_STAGE_SOLVED 732 */ 733 SCIP_Longint SCIPgetNDualResolveLPIterations( 734 SCIP* scip /**< SCIP data structure */ 735 ) 736 { 737 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNDualResolveLPIterations", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 738 739 return scip->stat->ndualresolvelpiterations; 740 } 741 742 /** gets total number of LPs solved so far for node relaxations 743 * 744 * @return the total number of LPs solved so far for node relaxations 745 * 746 * @pre This method can be called if SCIP is in one of the following stages: 747 * - \ref SCIP_STAGE_PRESOLVED 748 * - \ref SCIP_STAGE_SOLVING 749 * - \ref SCIP_STAGE_SOLVED 750 */ 751 SCIP_Longint SCIPgetNNodeLPs( 752 SCIP* scip /**< SCIP data structure */ 753 ) 754 { 755 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNNodeLPs", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 756 757 return scip->stat->nnodelps; 758 } 759 760 /** gets total number of LPs solved in 0 iterations for node relaxations 761 * 762 * @return the total number of LPs solved with 0 iteratins for node relaxations 763 * 764 * @pre This method can be called if SCIP is in one of the following stages: 765 * - \ref SCIP_STAGE_PRESOLVED 766 * - \ref SCIP_STAGE_SOLVING 767 * - \ref SCIP_STAGE_SOLVED 768 */ 769 SCIP_Longint SCIPgetNNodeZeroIterationLPs( 770 SCIP* scip /**< SCIP data structure */ 771 ) 772 { 773 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNNodeZeroIterationLPs", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 774 775 return scip->stat->nnodezeroitlps; 776 } 777 778 /** gets total number of simplex iterations used so far for node relaxations 779 * 780 * @return the total number of simplex iterations used so far for node relaxations 781 * 782 * @pre This method can be called if SCIP is in one of the following stages: 783 * - \ref SCIP_STAGE_PRESOLVED 784 * - \ref SCIP_STAGE_SOLVING 785 * - \ref SCIP_STAGE_SOLVED 786 */ 787 SCIP_Longint SCIPgetNNodeLPIterations( 788 SCIP* scip /**< SCIP data structure */ 789 ) 790 { 791 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNNodeLPIterations", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 792 793 return scip->stat->nnodelpiterations; 794 } 795 796 /** gets total number of LPs solved so far for initial LP in node relaxations 797 * 798 * @return the total number of LPs solved so far for initial LP in node relaxations 799 * 800 * @pre This method can be called if SCIP is in one of the following stages: 801 * - \ref SCIP_STAGE_PRESOLVED 802 * - \ref SCIP_STAGE_SOLVING 803 * - \ref SCIP_STAGE_SOLVED 804 */ 805 SCIP_Longint SCIPgetNNodeInitLPs( 806 SCIP* scip /**< SCIP data structure */ 807 ) 808 { 809 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNNodeInitLPs", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 810 811 return scip->stat->ninitlps; 812 } 813 814 /** gets total number of simplex iterations used so far for initial LP in node relaxations 815 * 816 * @return the total number of simplex iterations used so far for initial LP in node relaxations 817 * 818 * @pre This method can be called if SCIP is in one of the following stages: 819 * - \ref SCIP_STAGE_PRESOLVED 820 * - \ref SCIP_STAGE_SOLVING 821 * - \ref SCIP_STAGE_SOLVED 822 */ 823 SCIP_Longint SCIPgetNNodeInitLPIterations( 824 SCIP* scip /**< SCIP data structure */ 825 ) 826 { 827 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNNodeInitLPIterations", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 828 829 return scip->stat->ninitlpiterations; 830 } 831 832 /** gets total number of LPs solved so far during diving and probing 833 * 834 * @return total number of LPs solved so far during diving and probing 835 * 836 * @pre This method can be called if SCIP is in one of the following stages: 837 * - \ref SCIP_STAGE_PRESOLVED 838 * - \ref SCIP_STAGE_SOLVING 839 * - \ref SCIP_STAGE_SOLVED 840 */ 841 SCIP_Longint SCIPgetNDivingLPs( 842 SCIP* scip /**< SCIP data structure */ 843 ) 844 { 845 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNDivingLPs", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 846 847 return scip->stat->ndivinglps; 848 } 849 850 /** gets total number of simplex iterations used so far during diving and probing 851 * 852 * @return the total number of simplex iterations used so far during diving and probing 853 * 854 * @pre This method can be called if SCIP is in one of the following stages: 855 * - \ref SCIP_STAGE_PRESOLVED 856 * - \ref SCIP_STAGE_SOLVING 857 * - \ref SCIP_STAGE_SOLVED 858 */ 859 SCIP_Longint SCIPgetNDivingLPIterations( 860 SCIP* scip /**< SCIP data structure */ 861 ) 862 { 863 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNDivingLPIterations", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 864 865 return scip->stat->ndivinglpiterations; 866 } 867 868 /** gets total number of times, strong branching was called (each call represents solving two LPs) 869 * 870 * @return the total number of times, strong branching was called (each call represents solving two LPs) 871 * 872 * @pre This method can be called if SCIP is in one of the following stages: 873 * - \ref SCIP_STAGE_PRESOLVED 874 * - \ref SCIP_STAGE_SOLVING 875 * - \ref SCIP_STAGE_SOLVED 876 */ 877 SCIP_Longint SCIPgetNStrongbranchs( 878 SCIP* scip /**< SCIP data structure */ 879 ) 880 { 881 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNStrongbranchs", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 882 883 return scip->stat->nstrongbranchs; 884 } 885 886 /** gets total number of simplex iterations used so far in strong branching 887 * 888 * @return the total number of simplex iterations used so far in strong branching 889 * 890 * @pre This method can be called if SCIP is in one of the following stages: 891 * - \ref SCIP_STAGE_PRESOLVED 892 * - \ref SCIP_STAGE_SOLVING 893 * - \ref SCIP_STAGE_SOLVED 894 */ 895 SCIP_Longint SCIPgetNStrongbranchLPIterations( 896 SCIP* scip /**< SCIP data structure */ 897 ) 898 { 899 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNStrongbranchLPIterations", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 900 901 return scip->stat->nsblpiterations; 902 } 903 904 /** gets total number of times, strong branching was called at the root node (each call represents solving two LPs) 905 * 906 * @return the total number of times, strong branching was called at the root node (each call represents solving two LPs) 907 * 908 * @pre This method can be called if SCIP is in one of the following stages: 909 * - \ref SCIP_STAGE_PRESOLVED 910 * - \ref SCIP_STAGE_SOLVING 911 * - \ref SCIP_STAGE_SOLVED 912 */ 913 SCIP_Longint SCIPgetNRootStrongbranchs( 914 SCIP* scip /**< SCIP data structure */ 915 ) 916 { 917 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNRootStrongbranchs", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 918 919 return scip->stat->nrootstrongbranchs; 920 } 921 922 /** gets total number of simplex iterations used so far in strong branching at the root node 923 * 924 * @return the total number of simplex iterations used so far in strong branching at the root node 925 * 926 * @pre This method can be called if SCIP is in one of the following stages: 927 * - \ref SCIP_STAGE_PRESOLVED 928 * - \ref SCIP_STAGE_SOLVING 929 * - \ref SCIP_STAGE_SOLVED 930 */ 931 SCIP_Longint SCIPgetNRootStrongbranchLPIterations( 932 SCIP* scip /**< SCIP data structure */ 933 ) 934 { 935 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNRootStrongbranchLPIterations", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 936 937 return scip->stat->nrootsblpiterations; 938 } 939 940 /** gets number of pricing rounds performed so far at the current node 941 * 942 * @return the number of pricing rounds performed so far at the current node 943 * 944 * @pre This method can be called if SCIP is in one of the following stages: 945 * - \ref SCIP_STAGE_SOLVING 946 */ 947 int SCIPgetNPriceRounds( 948 SCIP* scip /**< SCIP data structure */ 949 ) 950 { 951 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNPriceRounds", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 952 953 return scip->stat->npricerounds; 954 } 955 956 /** get current number of variables in the pricing store 957 * 958 * @return the current number of variables in the pricing store 959 * 960 * @pre This method can be called if SCIP is in one of the following stages: 961 * - \ref SCIP_STAGE_PRESOLVED 962 * - \ref SCIP_STAGE_SOLVING 963 * - \ref SCIP_STAGE_SOLVED 964 */ 965 int SCIPgetNPricevars( 966 SCIP* scip /**< SCIP data structure */ 967 ) 968 { 969 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNPricevars", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 970 971 return scip->pricestore == NULL ? 0 : SCIPpricestoreGetNVars(scip->pricestore); 972 } 973 974 /** get total number of pricing variables found so far 975 * 976 * @return the total number of pricing variables found so far 977 * 978 * @pre This method can be called if SCIP is in one of the following stages: 979 * - \ref SCIP_STAGE_PRESOLVED 980 * - \ref SCIP_STAGE_SOLVING 981 * - \ref SCIP_STAGE_SOLVED 982 */ 983 int SCIPgetNPricevarsFound( 984 SCIP* scip /**< SCIP data structure */ 985 ) 986 { 987 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNPricevarsFound", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 988 989 return scip->pricestore == NULL ? 0 : SCIPpricestoreGetNVarsFound(scip->pricestore); 990 } 991 992 /** get total number of pricing variables applied to the LPs 993 * 994 * @return the total number of pricing variables applied to the LPs 995 * 996 * @pre This method can be called if SCIP is in one of the following stages: 997 * - \ref SCIP_STAGE_PRESOLVED 998 * - \ref SCIP_STAGE_SOLVING 999 * - \ref SCIP_STAGE_SOLVED 1000 */ 1001 int SCIPgetNPricevarsApplied( 1002 SCIP* scip /**< SCIP data structure */ 1003 ) 1004 { 1005 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNPricevarsApplied", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 1006 1007 return scip->pricestore == NULL ? 0 : SCIPpricestoreGetNVarsApplied(scip->pricestore); 1008 } 1009 1010 /** gets number of separation rounds performed so far at the current node 1011 * 1012 * @return the number of separation rounds performed so far at the current node 1013 * 1014 * @pre This method can be called if SCIP is in one of the following stages: 1015 * - \ref SCIP_STAGE_SOLVING 1016 */ 1017 int SCIPgetNSepaRounds( 1018 SCIP* scip /**< SCIP data structure */ 1019 ) 1020 { 1021 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNSepaRounds", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 1022 1023 return scip->stat->nseparounds; 1024 } 1025 1026 /** get total number of cuts added to the sepastore so far; this includes global cuts from the cut pool as often as they are separated 1027 * 1028 * @return the total number of cuts added to the sepastore so far 1029 * 1030 * @pre This method can be called if SCIP is in one of the following stages: 1031 * - \ref SCIP_STAGE_PRESOLVED 1032 * - \ref SCIP_STAGE_SOLVING 1033 * - \ref SCIP_STAGE_SOLVED 1034 */ 1035 int SCIPgetNCutsFound( 1036 SCIP* scip /**< SCIP data structure */ 1037 ) 1038 { 1039 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNCutsFound", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 1040 1041 return scip->sepastore == NULL ? 0 : SCIPsepastoreGetNCutsAdded(scip->sepastore); 1042 } 1043 1044 /** get number of cuts found so far in current separation round 1045 * 1046 * @return the number of cuts found so far in current separation round 1047 * 1048 * @pre This method can be called if SCIP is in one of the following stages: 1049 * - \ref SCIP_STAGE_PRESOLVED 1050 * - \ref SCIP_STAGE_SOLVING 1051 * - \ref SCIP_STAGE_SOLVED 1052 */ 1053 int SCIPgetNCutsFoundRound( 1054 SCIP* scip /**< SCIP data structure */ 1055 ) 1056 { 1057 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNCutsFoundRound", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 1058 1059 return scip->sepastore == NULL ? 0 : SCIPsepastoreGetNCutsFoundRound(scip->sepastore); 1060 } 1061 1062 /** get total number of cuts applied to the LPs 1063 * 1064 * @return the total number of cuts applied to the LPs 1065 * 1066 * @pre This method can be called if SCIP is in one of the following stages: 1067 * - \ref SCIP_STAGE_PRESOLVED 1068 * - \ref SCIP_STAGE_SOLVING 1069 * - \ref SCIP_STAGE_SOLVED 1070 */ 1071 int SCIPgetNCutsApplied( 1072 SCIP* scip /**< SCIP data structure */ 1073 ) 1074 { 1075 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNCutsApplied", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 1076 1077 return scip->sepastore == NULL ? 0 : SCIPsepastoreGetNCutsApplied(scip->sepastore); 1078 } 1079 1080 /** get total number of constraints found in conflict analysis (conflict, reconvergence constraints, and dual proofs) 1081 * 1082 * @return the total number of constraints found in conflict analysis (conflict, reconvergence constraints, and dual proofs) 1083 * 1084 * @pre This method can be called if SCIP is in one of the following stages: 1085 * - \ref SCIP_STAGE_TRANSFORMED 1086 * - \ref SCIP_STAGE_INITPRESOLVE 1087 * - \ref SCIP_STAGE_PRESOLVING 1088 * - \ref SCIP_STAGE_EXITPRESOLVE 1089 * - \ref SCIP_STAGE_PRESOLVED 1090 * - \ref SCIP_STAGE_INITSOLVE 1091 * - \ref SCIP_STAGE_SOLVING 1092 * - \ref SCIP_STAGE_SOLVED 1093 * - \ref SCIP_STAGE_EXITSOLVE 1094 */ 1095 SCIP_Longint SCIPgetNConflictConssFound( 1096 SCIP* scip /**< SCIP data structure */ 1097 ) 1098 { 1099 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNConflictConssFound", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) ); 1100 1101 return scip->conflict == NULL ? 0 : (SCIPconflictGetNPropConflictConss(scip->conflict) 1102 + SCIPconflictGetNPropReconvergenceConss(scip->conflict) 1103 + SCIPconflictGetNInfeasibleLPConflictConss(scip->conflict) 1104 + SCIPconflictGetNInfeasibleLPReconvergenceConss(scip->conflict) 1105 + SCIPconflictGetNBoundexceedingLPConflictConss(scip->conflict) 1106 + SCIPconflictGetNBoundexceedingLPReconvergenceConss(scip->conflict) 1107 + SCIPconflictGetNStrongbranchConflictConss(scip->conflict) 1108 + SCIPconflictGetNStrongbranchReconvergenceConss(scip->conflict) 1109 + SCIPconflictGetNPseudoConflictConss(scip->conflict) 1110 + SCIPconflictGetNPseudoReconvergenceConss(scip->conflict) 1111 + SCIPconflictGetNDualproofsBndGlobal(scip->conflict) 1112 + SCIPconflictGetNDualproofsInfGlobal(scip->conflict)); 1113 } 1114 1115 /** get number of conflict constraints found so far at the current node 1116 * 1117 * @return the number of conflict constraints found so far at the current node 1118 * 1119 * @pre This method can be called if SCIP is in one of the following stages: 1120 * - \ref SCIP_STAGE_TRANSFORMED 1121 * - \ref SCIP_STAGE_INITPRESOLVE 1122 * - \ref SCIP_STAGE_PRESOLVING 1123 * - \ref SCIP_STAGE_EXITPRESOLVE 1124 * - \ref SCIP_STAGE_PRESOLVED 1125 * - \ref SCIP_STAGE_INITSOLVE 1126 * - \ref SCIP_STAGE_SOLVING 1127 * - \ref SCIP_STAGE_SOLVED 1128 * - \ref SCIP_STAGE_EXITSOLVE 1129 */ 1130 int SCIPgetNConflictConssFoundNode( 1131 SCIP* scip /**< SCIP data structure */ 1132 ) 1133 { 1134 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNConflictConssFoundNode", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) ); 1135 1136 return scip->conflict == NULL ? 0 : SCIPconflictGetNConflicts(scip->conflict); 1137 } 1138 1139 /** get total number of conflict constraints added to the problem 1140 * 1141 * @return the total number of conflict constraints added to the problem 1142 * 1143 * @pre This method can be called if SCIP is in one of the following stages: 1144 * - \ref SCIP_STAGE_TRANSFORMED 1145 * - \ref SCIP_STAGE_INITPRESOLVE 1146 * - \ref SCIP_STAGE_PRESOLVING 1147 * - \ref SCIP_STAGE_EXITPRESOLVE 1148 * - \ref SCIP_STAGE_PRESOLVED 1149 * - \ref SCIP_STAGE_INITSOLVE 1150 * - \ref SCIP_STAGE_SOLVING 1151 * - \ref SCIP_STAGE_SOLVED 1152 * - \ref SCIP_STAGE_EXITSOLVE 1153 */ 1154 SCIP_Longint SCIPgetNConflictConssApplied( 1155 SCIP* scip /**< SCIP data structure */ 1156 ) 1157 { 1158 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNConflictConssApplied", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) ); 1159 1160 return scip->conflict == NULL ? 0 : SCIPconflictGetNAppliedConss(scip->conflict); 1161 } 1162 1163 /** get total number of dual proof constraints added to the problem 1164 * 1165 * @return the total number of dual proof constraints added to the problem 1166 * 1167 * @pre This method can be called if SCIP is in one of the following stages: 1168 * - \ref SCIP_STAGE_TRANSFORMED 1169 * - \ref SCIP_STAGE_INITPRESOLVE 1170 * - \ref SCIP_STAGE_PRESOLVING 1171 * - \ref SCIP_STAGE_EXITPRESOLVE 1172 * - \ref SCIP_STAGE_PRESOLVED 1173 * - \ref SCIP_STAGE_INITSOLVE 1174 * - \ref SCIP_STAGE_SOLVING 1175 * - \ref SCIP_STAGE_SOLVED 1176 * - \ref SCIP_STAGE_EXITSOLVE 1177 */ 1178 SCIP_Longint SCIPgetNConflictDualproofsApplied( 1179 SCIP* scip /**< SCIP data structure */ 1180 ) 1181 { 1182 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNConflictDualproofsApplied", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) ); 1183 1184 return scip->conflict == NULL ? 0 : (SCIPconflictGetNDualproofsInfSuccess(scip->conflict) + 1185 SCIPconflictGetNDualproofsBndSuccess(scip->conflict)); 1186 } 1187 1188 /** gets maximal depth of all processed nodes in current branch and bound run (excluding probing nodes) 1189 * 1190 * @return the maximal depth of all processed nodes in current branch and bound run (excluding probing nodes) 1191 * 1192 * @pre This method can be called if SCIP is in one of the following stages: 1193 * - \ref SCIP_STAGE_TRANSFORMED 1194 * - \ref SCIP_STAGE_INITPRESOLVE 1195 * - \ref SCIP_STAGE_PRESOLVING 1196 * - \ref SCIP_STAGE_EXITPRESOLVE 1197 * - \ref SCIP_STAGE_PRESOLVED 1198 * - \ref SCIP_STAGE_INITSOLVE 1199 * - \ref SCIP_STAGE_SOLVING 1200 * - \ref SCIP_STAGE_SOLVED 1201 * - \ref SCIP_STAGE_EXITSOLVE 1202 */ 1203 int SCIPgetMaxDepth( 1204 SCIP* scip /**< SCIP data structure */ 1205 ) 1206 { 1207 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetMaxDepth", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) ); 1208 1209 return scip->stat->maxdepth; 1210 } 1211 1212 /** gets maximal depth of all processed nodes over all branch and bound runs 1213 * 1214 * @return the maximal depth of all processed nodes over all branch and bound runs 1215 * 1216 * @pre This method can be called if SCIP is in one of the following stages: 1217 * - \ref SCIP_STAGE_TRANSFORMED 1218 * - \ref SCIP_STAGE_INITPRESOLVE 1219 * - \ref SCIP_STAGE_PRESOLVING 1220 * - \ref SCIP_STAGE_EXITPRESOLVE 1221 * - \ref SCIP_STAGE_PRESOLVED 1222 * - \ref SCIP_STAGE_INITSOLVE 1223 * - \ref SCIP_STAGE_SOLVING 1224 * - \ref SCIP_STAGE_SOLVED 1225 * - \ref SCIP_STAGE_EXITSOLVE 1226 */ 1227 int SCIPgetMaxTotalDepth( 1228 SCIP* scip /**< SCIP data structure */ 1229 ) 1230 { 1231 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetMaxTotalDepth", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) ); 1232 1233 return scip->stat->maxtotaldepth; 1234 } 1235 1236 /** gets total number of backtracks, i.e. number of times, the new node was selected from the leaves queue 1237 * 1238 * @return the total number of backtracks, i.e. number of times, the new node was selected from the leaves queue 1239 * 1240 * @pre This method can be called if SCIP is in one of the following stages: 1241 * - \ref SCIP_STAGE_TRANSFORMED 1242 * - \ref SCIP_STAGE_INITPRESOLVE 1243 * - \ref SCIP_STAGE_PRESOLVING 1244 * - \ref SCIP_STAGE_EXITPRESOLVE 1245 * - \ref SCIP_STAGE_PRESOLVED 1246 * - \ref SCIP_STAGE_INITSOLVE 1247 * - \ref SCIP_STAGE_SOLVING 1248 * - \ref SCIP_STAGE_SOLVED 1249 * - \ref SCIP_STAGE_EXITSOLVE 1250 */ 1251 SCIP_Longint SCIPgetNBacktracks( 1252 SCIP* scip /**< SCIP data structure */ 1253 ) 1254 { 1255 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNBacktracks", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) ); 1256 1257 return scip->stat->nbacktracks; 1258 } 1259 1260 /** gets total number of active constraints at the current node 1261 * 1262 * @return the total number of active constraints at the current node 1263 * 1264 * @pre This method can be called if SCIP is in one of the following stages: 1265 * - \ref SCIP_STAGE_INITPRESOLVE 1266 * - \ref SCIP_STAGE_PRESOLVING 1267 * - \ref SCIP_STAGE_EXITPRESOLVE 1268 * - \ref SCIP_STAGE_PRESOLVED 1269 * - \ref SCIP_STAGE_SOLVING 1270 */ 1271 int SCIPgetNActiveConss( 1272 SCIP* scip /**< SCIP data structure */ 1273 ) 1274 { 1275 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNActiveConss", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 1276 1277 return scip->stat->nactiveconss; 1278 } 1279 1280 /** gets total number of enabled constraints at the current node 1281 * 1282 * @return the total number of enabled constraints at the current node 1283 * 1284 * @pre This method can be called if SCIP is in one of the following stages: 1285 * - \ref SCIP_STAGE_PRESOLVED 1286 * - \ref SCIP_STAGE_SOLVING 1287 */ 1288 int SCIPgetNEnabledConss( 1289 SCIP* scip /**< SCIP data structure */ 1290 ) 1291 { 1292 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNEnabledConss", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 1293 1294 return scip->stat->nenabledconss; 1295 } 1296 1297 /** gets average dual bound of all unprocessed nodes for original problem 1298 * 1299 * @return the average dual bound of all unprocessed nodes for original problem 1300 * 1301 * @pre This method can be called if SCIP is in one of the following stages: 1302 * - \ref SCIP_STAGE_PRESOLVED 1303 * - \ref SCIP_STAGE_SOLVING 1304 * - \ref SCIP_STAGE_SOLVED 1305 */ 1306 SCIP_Real SCIPgetAvgDualbound( 1307 SCIP* scip /**< SCIP data structure */ 1308 ) 1309 { 1310 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetAvgDualbound", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 1311 1312 return SCIPprobExternObjval(scip->transprob, scip->origprob, scip->set, 1313 SCIPtreeGetAvgLowerbound(scip->tree, scip->primal->cutoffbound)); 1314 } 1315 1316 /** gets average lower (dual) bound of all unprocessed nodes in transformed problem 1317 * 1318 * @return the average lower (dual) bound of all unprocessed nodes in transformed problem 1319 * 1320 * @pre This method can be called if SCIP is in one of the following stages: 1321 * - \ref SCIP_STAGE_PRESOLVED 1322 * - \ref SCIP_STAGE_SOLVING 1323 * - \ref SCIP_STAGE_SOLVED 1324 */ 1325 SCIP_Real SCIPgetAvgLowerbound( 1326 SCIP* scip /**< SCIP data structure */ 1327 ) 1328 { 1329 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetAvgLowerbound", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 1330 1331 return SCIPtreeGetAvgLowerbound(scip->tree, scip->primal->cutoffbound); 1332 } 1333 1334 /** gets global dual bound 1335 * 1336 * @return the global dual bound 1337 * 1338 * @pre This method can be called if SCIP is in one of the following stages: 1339 * - \ref SCIP_STAGE_TRANSFORMED 1340 * - \ref SCIP_STAGE_INITPRESOLVE 1341 * - \ref SCIP_STAGE_PRESOLVING 1342 * - \ref SCIP_STAGE_EXITPRESOLVE 1343 * - \ref SCIP_STAGE_PRESOLVED 1344 * - \ref SCIP_STAGE_INITSOLVE 1345 * - \ref SCIP_STAGE_SOLVING 1346 * - \ref SCIP_STAGE_SOLVED 1347 * - \ref SCIP_STAGE_EXITSOLVE 1348 */ 1349 SCIP_Real SCIPgetDualbound( 1350 SCIP* scip /**< SCIP data structure */ 1351 ) 1352 { 1353 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetDualbound", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) ); 1354 1355 /* in case we are in presolving we use the stored dual bound if it exits */ 1356 if( scip->set->stage <= SCIP_STAGE_INITSOLVE && scip->transprob->dualbound < SCIP_INVALID ) 1357 return scip->transprob->dualbound; 1358 1359 return SCIPprobExternObjval(scip->transprob, scip->origprob, scip->set, SCIPgetLowerbound(scip)); 1360 } 1361 1362 /** gets global lower (dual) bound in transformed problem 1363 * 1364 * @return the global lower (dual) bound in transformed problem 1365 * 1366 * @pre This method can be called if SCIP is in one of the following stages: 1367 * - \ref SCIP_STAGE_TRANSFORMED 1368 * - \ref SCIP_STAGE_INITPRESOLVE 1369 * - \ref SCIP_STAGE_PRESOLVING 1370 * - \ref SCIP_STAGE_EXITPRESOLVE 1371 * - \ref SCIP_STAGE_PRESOLVED 1372 * - \ref SCIP_STAGE_INITSOLVE 1373 * - \ref SCIP_STAGE_SOLVING 1374 * - \ref SCIP_STAGE_SOLVED 1375 */ 1376 SCIP_Real SCIPgetLowerbound( 1377 SCIP* scip /**< SCIP data structure */ 1378 ) 1379 { 1380 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetLowerbound", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 1381 1382 if( scip->set->stage <= SCIP_STAGE_INITSOLVE ) 1383 return -SCIPinfinity(scip); 1384 else if( SCIPgetStatus(scip) == SCIP_STATUS_INFORUNBD || SCIPgetStatus(scip) == SCIP_STATUS_UNBOUNDED ) 1385 { 1386 /* in case we could not prove whether the problem is unbounded or infeasible, we want to terminate with lower 1387 * bound = -inf instead of lower bound = upper bound = +inf also in case we prove that the problem is unbounded, 1388 * it seems to make sense to return with lower bound = -inf, since -infinity is the only valid lower bound 1389 */ 1390 return -SCIPinfinity(scip); 1391 } 1392 else if( SCIPgetStatus(scip) == SCIP_STATUS_INFEASIBLE ) 1393 { 1394 /* SCIPtreeGetLowerbound() should return +inf in the case of infeasibility, but when infeasibility is detected 1395 * during presolving this does not seem to be the case; hence, we treat this case explicitly 1396 */ 1397 return SCIPinfinity(scip); 1398 } 1399 else 1400 { 1401 SCIP_Real treelowerbound; 1402 1403 /* it may happen that the remaining tree is empty or all open nodes have a lower bound above the cutoff bound, but 1404 * have not yet been cut off, e.g., when the user calls SCIPgetDualbound() in some event handler; in this case, 1405 * the global lower bound is given by the upper bound value 1406 */ 1407 treelowerbound = SCIPtreeGetLowerbound(scip->tree, scip->set); 1408 1409 if( treelowerbound < scip->primal->upperbound) 1410 return treelowerbound; 1411 else 1412 return scip->primal->upperbound; 1413 } 1414 } 1415 1416 /** gets dual bound of the root node for the original problem 1417 * 1418 * @return the dual bound of the root node for the original problem 1419 * 1420 * @pre This method can be called if SCIP is in one of the following stages: 1421 * - \ref SCIP_STAGE_PRESOLVING 1422 * - \ref SCIP_STAGE_EXITPRESOLVE 1423 * - \ref SCIP_STAGE_PRESOLVED 1424 * - \ref SCIP_STAGE_INITSOLVE 1425 * - \ref SCIP_STAGE_SOLVING 1426 * - \ref SCIP_STAGE_SOLVED 1427 */ 1428 SCIP_Real SCIPgetDualboundRoot( 1429 SCIP* scip /**< SCIP data structure */ 1430 ) 1431 { 1432 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetDualboundRoot", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 1433 1434 if( SCIPsetIsInfinity(scip->set, scip->stat->rootlowerbound) ) 1435 return SCIPgetPrimalbound(scip); 1436 else 1437 return SCIPprobExternObjval(scip->transprob, scip->origprob, scip->set, scip->stat->rootlowerbound); 1438 } 1439 1440 /** gets lower (dual) bound in transformed problem of the root node 1441 * 1442 * @return the lower (dual) bound in transformed problem of the root node 1443 * 1444 * @pre This method can be called if SCIP is in one of the following stages: 1445 * - \ref SCIP_STAGE_PRESOLVING 1446 * - \ref SCIP_STAGE_EXITPRESOLVE 1447 * - \ref SCIP_STAGE_PRESOLVED 1448 * - \ref SCIP_STAGE_INITSOLVE 1449 * - \ref SCIP_STAGE_SOLVING 1450 * - \ref SCIP_STAGE_SOLVED 1451 */ 1452 SCIP_Real SCIPgetLowerboundRoot( 1453 SCIP* scip /**< SCIP data structure */ 1454 ) 1455 { 1456 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetLowerboundRoot", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 1457 1458 if( SCIPsetIsInfinity(scip->set, scip->stat->rootlowerbound) ) 1459 return SCIPgetUpperbound(scip); 1460 else 1461 return scip->stat->rootlowerbound; 1462 } 1463 1464 /** gets dual bound for the original problem obtained by the first LP solve at the root node 1465 * 1466 * @return the dual bound for the original problem of the first LP solve at the root node 1467 * 1468 * @pre This method can be called if SCIP is in one of the following stages: 1469 * - \ref SCIP_STAGE_PRESOLVING 1470 * - \ref SCIP_STAGE_EXITPRESOLVE 1471 * - \ref SCIP_STAGE_PRESOLVED 1472 * - \ref SCIP_STAGE_INITSOLVE 1473 * - \ref SCIP_STAGE_SOLVING 1474 * - \ref SCIP_STAGE_SOLVED 1475 */ 1476 SCIP_Real SCIPgetFirstLPDualboundRoot( 1477 SCIP* scip /**< SCIP data structure */ 1478 ) 1479 { 1480 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetFirstLPDualboundRoot", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 1481 1482 return scip->stat->firstlpdualbound; 1483 } 1484 1485 /** gets lower (dual) bound in transformed problem obtained by the first LP solve at the root node 1486 * 1487 * @return the lower (dual) bound in transformed problem obtained by first LP solve at the root node 1488 * 1489 * @pre This method can be called if SCIP is in one of the following stages: 1490 * - \ref SCIP_STAGE_PRESOLVING 1491 * - \ref SCIP_STAGE_EXITPRESOLVE 1492 * - \ref SCIP_STAGE_PRESOLVED 1493 * - \ref SCIP_STAGE_INITSOLVE 1494 * - \ref SCIP_STAGE_SOLVING 1495 * - \ref SCIP_STAGE_SOLVED 1496 */ 1497 SCIP_Real SCIPgetFirstLPLowerboundRoot( 1498 SCIP* scip /**< SCIP data structure */ 1499 ) 1500 { 1501 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetFirstLPLowerboundRoot", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 1502 1503 if( scip->stat->firstlpdualbound == SCIP_INVALID ) /*lint !e777*/ 1504 return -SCIPinfinity(scip); 1505 else 1506 return SCIPprobInternObjval(scip->transprob, scip->origprob, scip->set, scip->stat->firstlpdualbound); 1507 } 1508 1509 /** the primal bound of the very first solution */ 1510 SCIP_Real SCIPgetFirstPrimalBound( 1511 SCIP* scip /**< SCIP data structure */ 1512 ) 1513 { 1514 return scip->stat->firstprimalbound; 1515 } 1516 1517 /** gets global primal bound (objective value of best solution or user objective limit) for the original problem 1518 * 1519 * @return the global primal bound (objective value of best solution or user objective limit) for the original problem 1520 * 1521 * @pre This method can be called if SCIP is in one of the following stages: 1522 * - \ref SCIP_STAGE_TRANSFORMED 1523 * - \ref SCIP_STAGE_INITPRESOLVE 1524 * - \ref SCIP_STAGE_PRESOLVING 1525 * - \ref SCIP_STAGE_EXITPRESOLVE 1526 * - \ref SCIP_STAGE_PRESOLVED 1527 * - \ref SCIP_STAGE_INITSOLVE 1528 * - \ref SCIP_STAGE_SOLVING 1529 * - \ref SCIP_STAGE_SOLVED 1530 * - \ref SCIP_STAGE_EXITSOLVE 1531 */ 1532 SCIP_Real SCIPgetPrimalbound( 1533 SCIP* scip /**< SCIP data structure */ 1534 ) 1535 { 1536 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetPrimalbound", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) ); 1537 1538 return SCIPprobExternObjval(scip->transprob, scip->origprob, scip->set, SCIPgetUpperbound(scip)); 1539 } 1540 1541 /** gets global upper (primal) bound in transformed problem (objective value of best solution or user objective limit) 1542 * 1543 * @return the global upper (primal) bound in transformed problem (objective value of best solution or user objective limit) 1544 * 1545 * @pre This method can be called if SCIP is in one of the following stages: 1546 * - \ref SCIP_STAGE_TRANSFORMED 1547 * - \ref SCIP_STAGE_INITPRESOLVE 1548 * - \ref SCIP_STAGE_PRESOLVING 1549 * - \ref SCIP_STAGE_EXITPRESOLVE 1550 * - \ref SCIP_STAGE_PRESOLVED 1551 * - \ref SCIP_STAGE_INITSOLVE 1552 * - \ref SCIP_STAGE_SOLVING 1553 * - \ref SCIP_STAGE_SOLVED 1554 * - \ref SCIP_STAGE_EXITSOLVE 1555 */ 1556 SCIP_Real SCIPgetUpperbound( 1557 SCIP* scip /**< SCIP data structure */ 1558 ) 1559 { 1560 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetUpperbound", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) ); 1561 1562 if( SCIPgetStatus(scip) == SCIP_STATUS_UNBOUNDED ) 1563 return -SCIPinfinity(scip); 1564 else 1565 return scip->primal->upperbound; 1566 } 1567 1568 /** gets global cutoff bound in transformed problem: a sub problem with lower bound larger than the cutoff 1569 * cannot contain a better feasible solution; usually, this bound is equal to the upper bound, but if the 1570 * objective value is always integral, the cutoff bound is (nearly) one less than the upper bound; 1571 * additionally, due to objective function domain propagation, the cutoff bound can be further reduced 1572 * 1573 * @return global cutoff bound in transformed problem 1574 * 1575 * @pre This method can be called if SCIP is in one of the following stages: 1576 * - \ref SCIP_STAGE_TRANSFORMED 1577 * - \ref SCIP_STAGE_INITPRESOLVE 1578 * - \ref SCIP_STAGE_PRESOLVING 1579 * - \ref SCIP_STAGE_EXITPRESOLVE 1580 * - \ref SCIP_STAGE_PRESOLVED 1581 * - \ref SCIP_STAGE_INITSOLVE 1582 * - \ref SCIP_STAGE_SOLVING 1583 * - \ref SCIP_STAGE_SOLVED 1584 * - \ref SCIP_STAGE_EXITSOLVE 1585 */ 1586 SCIP_Real SCIPgetCutoffbound( 1587 SCIP* scip /**< SCIP data structure */ 1588 ) 1589 { 1590 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetCutoffbound", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) ); 1591 1592 return scip->primal->cutoffbound; 1593 } 1594 1595 /** updates the cutoff bound 1596 * 1597 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 1598 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1599 * 1600 * @note using this method in the solving stage can lead to an erroneous SCIP solving status; in particular, 1601 * if a solution not respecting the cutoff bound was found before installing a cutoff bound which 1602 * renders the remaining problem infeasible, this solution may be reported as optimal 1603 * 1604 * @pre This method can be called if SCIP is in one of the following stages: 1605 * - \ref SCIP_STAGE_TRANSFORMED 1606 * - \ref SCIP_STAGE_PRESOLVING 1607 * - \ref SCIP_STAGE_PRESOLVED 1608 * - \ref SCIP_STAGE_INITSOLVE 1609 * - \ref SCIP_STAGE_SOLVING 1610 * 1611 * @note the given cutoff bound has to better or equal to known one (SCIPgetCutoffbound()) 1612 * @note a given cutoff bound is also used for updating the objective limit, if possible 1613 */ 1614 SCIP_RETCODE SCIPupdateCutoffbound( 1615 SCIP* scip, /**< SCIP data structure */ 1616 SCIP_Real cutoffbound /**< new cutoff bound */ 1617 ) 1618 { 1619 SCIP_CALL( SCIPcheckStage(scip, "SCIPupdateCutoffbound", FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 1620 1621 assert(cutoffbound <= SCIPgetCutoffbound(scip)); 1622 1623 SCIP_CALL( SCIPprimalSetCutoffbound(scip->primal, scip->mem->probmem, scip->set, scip->stat, scip->eventfilter, 1624 scip->eventqueue, scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp, cutoffbound, FALSE) ); 1625 1626 return SCIP_OKAY; 1627 } 1628 1629 1630 /** returns whether the current primal bound is justified with a feasible primal solution; if not, the primal bound 1631 * was set from the user as objective limit 1632 * 1633 * @return TRUE if the current primal bound is justified with a feasible primal solution, otherwise FALSE 1634 * 1635 * @pre This method can be called if SCIP is in one of the following stages: 1636 * - \ref SCIP_STAGE_TRANSFORMED 1637 * - \ref SCIP_STAGE_INITPRESOLVE 1638 * - \ref SCIP_STAGE_PRESOLVING 1639 * - \ref SCIP_STAGE_EXITPRESOLVE 1640 * - \ref SCIP_STAGE_PRESOLVED 1641 * - \ref SCIP_STAGE_INITSOLVE 1642 * - \ref SCIP_STAGE_SOLVING 1643 * - \ref SCIP_STAGE_SOLVED 1644 * - \ref SCIP_STAGE_EXITSOLVE 1645 */ 1646 SCIP_Bool SCIPisPrimalboundSol( 1647 SCIP* scip /**< SCIP data structure */ 1648 ) 1649 { 1650 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPisPrimalboundSol", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) ); 1651 1652 return SCIPprimalUpperboundIsSol(scip->primal, scip->set, scip->transprob, scip->origprob); 1653 } 1654 1655 /** gets current gap |(primalbound - dualbound)/min(|primalbound|,|dualbound|)| if both bounds have same sign, 1656 * or infinity, if they have opposite sign 1657 * 1658 * @return the current gap |(primalbound - dualbound)/min(|primalbound|,|dualbound|)| if both bounds have same sign, 1659 * or infinity, if they have opposite sign 1660 * 1661 * @pre This method can be called if SCIP is in one of the following stages: 1662 * - \ref SCIP_STAGE_PRESOLVING 1663 * - \ref SCIP_STAGE_EXITPRESOLVE 1664 * - \ref SCIP_STAGE_PRESOLVED 1665 * - \ref SCIP_STAGE_INITSOLVE 1666 * - \ref SCIP_STAGE_SOLVING 1667 * - \ref SCIP_STAGE_SOLVED 1668 */ 1669 SCIP_Real SCIPgetGap( 1670 SCIP* scip /**< SCIP data structure */ 1671 ) 1672 { 1673 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetGap", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 1674 1675 /* in case we could not prove whether the problem is unbounded or infeasible, we want to terminate with gap = +inf; 1676 * if the problem was proven to be unbounded or proven to be infeasible we return gap = 0 1677 */ 1678 if( SCIPgetStatus(scip) == SCIP_STATUS_INFORUNBD ) 1679 return SCIPsetInfinity(scip->set); 1680 else if( SCIPgetStatus(scip) == SCIP_STATUS_INFEASIBLE || SCIPgetStatus(scip) == SCIP_STATUS_UNBOUNDED ) 1681 return 0.0; 1682 1683 /* the lowerbound is infinity, but SCIP may not have updated the status; in this case, the problem was already solved 1684 * so we return gap = 0 1685 */ 1686 if( SCIPsetIsInfinity(scip->set, SCIPgetLowerbound(scip)) ) 1687 return 0.0; 1688 1689 return SCIPcomputeGap(SCIPsetEpsilon(scip->set), SCIPsetInfinity(scip->set), SCIPgetPrimalbound(scip), SCIPgetDualbound(scip)); 1690 } 1691 1692 /** gets current gap |(upperbound - lowerbound)/min(|upperbound|,|lowerbound|)| in transformed problem if both bounds 1693 * have same sign, or infinity, if they have opposite sign 1694 * 1695 * @return current gap |(upperbound - lowerbound)/min(|upperbound|,|lowerbound|)| in transformed problem if both bounds 1696 * have same sign, or infinity, if they have opposite sign 1697 * 1698 * @pre This method can be called if SCIP is in one of the following stages: 1699 * - \ref SCIP_STAGE_PRESOLVED 1700 * - \ref SCIP_STAGE_SOLVING 1701 * - \ref SCIP_STAGE_SOLVED 1702 */ 1703 SCIP_Real SCIPgetTransGap( 1704 SCIP* scip /**< SCIP data structure */ 1705 ) 1706 { 1707 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetTransGap", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 1708 1709 /* in case we could not prove whether the problem is unbounded or infeasible, we want to terminate with gap = +inf; 1710 * if the problem was proven to be unbounded or proven to be infeasible we return gap = 0 1711 */ 1712 if( SCIPgetStatus(scip) == SCIP_STATUS_INFORUNBD ) 1713 return SCIPsetInfinity(scip->set); 1714 else if( SCIPgetStatus(scip) == SCIP_STATUS_INFEASIBLE || SCIPgetStatus(scip) == SCIP_STATUS_UNBOUNDED ) 1715 return 0.0; 1716 1717 /* the lowerbound is infinity, but SCIP may not have updated the status; in this case, the problem was already solved 1718 * so we return gap = 0 1719 */ 1720 if( SCIPsetIsInfinity(scip->set, SCIPgetLowerbound(scip)) ) 1721 return 0.0; 1722 1723 return SCIPcomputeGap(SCIPsetEpsilon(scip->set), SCIPsetInfinity(scip->set), SCIPgetUpperbound(scip), SCIPgetLowerbound(scip)); 1724 } 1725 1726 /** gets number of feasible primal solutions found so far 1727 * 1728 * @return the number of feasible primal solutions found so far 1729 * 1730 * @pre This method can be called if SCIP is in one of the following stages: 1731 * - \ref SCIP_STAGE_TRANSFORMED 1732 * - \ref SCIP_STAGE_INITPRESOLVE 1733 * - \ref SCIP_STAGE_PRESOLVING 1734 * - \ref SCIP_STAGE_EXITPRESOLVE 1735 * - \ref SCIP_STAGE_PRESOLVED 1736 * - \ref SCIP_STAGE_INITSOLVE 1737 * - \ref SCIP_STAGE_SOLVING 1738 * - \ref SCIP_STAGE_SOLVED 1739 * - \ref SCIP_STAGE_EXITSOLVE 1740 */ 1741 SCIP_Longint SCIPgetNSolsFound( 1742 SCIP* scip /**< SCIP data structure */ 1743 ) 1744 { 1745 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNSolsFound", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) ); 1746 1747 return scip->primal->nsolsfound; 1748 } 1749 1750 /** gets number of feasible primal solutions respecting the objective limit found so far 1751 * 1752 * @return the number of feasible primal solutions respecting the objective limit found so far 1753 * 1754 * @pre This method can be called if SCIP is in one of the following stages: 1755 * - \ref SCIP_STAGE_INIT 1756 * - \ref SCIP_STAGE_PROBLEM 1757 * - \ref SCIP_STAGE_TRANSFORMING 1758 * - \ref SCIP_STAGE_TRANSFORMED 1759 * - \ref SCIP_STAGE_INITPRESOLVE 1760 * - \ref SCIP_STAGE_PRESOLVING 1761 * - \ref SCIP_STAGE_EXITPRESOLVE 1762 * - \ref SCIP_STAGE_PRESOLVED 1763 * - \ref SCIP_STAGE_INITSOLVE 1764 * - \ref SCIP_STAGE_SOLVING 1765 * - \ref SCIP_STAGE_SOLVED 1766 * - \ref SCIP_STAGE_EXITSOLVE 1767 */ 1768 SCIP_Longint SCIPgetNLimSolsFound( 1769 SCIP* scip /**< SCIP data structure */ 1770 ) 1771 { 1772 if( SCIPgetStage(scip) < SCIP_STAGE_TRANSFORMED) 1773 return 0; 1774 1775 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNLimSolsFound", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) ); 1776 1777 return scip->primal->nlimsolsfound; 1778 } 1779 1780 /** gets number of feasible primal solutions found so far, that improved the primal bound at the time they were found 1781 * 1782 * @return the number of feasible primal solutions found so far, that improved the primal bound at the time they were found 1783 * 1784 * @pre This method can be called if SCIP is in one of the following stages: 1785 * - \ref SCIP_STAGE_TRANSFORMED 1786 * - \ref SCIP_STAGE_INITPRESOLVE 1787 * - \ref SCIP_STAGE_PRESOLVING 1788 * - \ref SCIP_STAGE_EXITPRESOLVE 1789 * - \ref SCIP_STAGE_PRESOLVED 1790 * - \ref SCIP_STAGE_INITSOLVE 1791 * - \ref SCIP_STAGE_SOLVING 1792 * - \ref SCIP_STAGE_SOLVED 1793 * - \ref SCIP_STAGE_EXITSOLVE 1794 */ 1795 SCIP_Longint SCIPgetNBestSolsFound( 1796 SCIP* scip /**< SCIP data structure */ 1797 ) 1798 { 1799 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNBestSolsFound", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) ); 1800 1801 return scip->primal->nbestsolsfound; 1802 } 1803 1804 /** gets the average pseudo cost value for the given direction over all variables 1805 * 1806 * @return the average pseudo cost value for the given direction over all variables 1807 * 1808 * @pre This method can be called if SCIP is in one of the following stages: 1809 * - \ref SCIP_STAGE_SOLVING 1810 * - \ref SCIP_STAGE_SOLVED 1811 */ 1812 SCIP_Real SCIPgetAvgPseudocost( 1813 SCIP* scip, /**< SCIP data structure */ 1814 SCIP_Real solvaldelta /**< difference of variable's new LP value - old LP value */ 1815 ) 1816 { 1817 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetAvgPseudocost", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 1818 1819 return SCIPhistoryGetPseudocost(scip->stat->glbhistory, solvaldelta); 1820 } 1821 1822 /** gets the average pseudo cost value for the given direction over all variables, 1823 * only using the pseudo cost information of the current run 1824 * 1825 * @return the average pseudo cost value for the given direction over all variables, 1826 * only using the pseudo cost information of the current run 1827 * 1828 * @pre This method can be called if SCIP is in one of the following stages: 1829 * - \ref SCIP_STAGE_SOLVING 1830 * - \ref SCIP_STAGE_SOLVED 1831 */ 1832 SCIP_Real SCIPgetAvgPseudocostCurrentRun( 1833 SCIP* scip, /**< SCIP data structure */ 1834 SCIP_Real solvaldelta /**< difference of variable's new LP value - old LP value */ 1835 ) 1836 { 1837 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetAvgPseudocostCurrentRun", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 1838 1839 return SCIPhistoryGetPseudocost(scip->stat->glbhistorycrun, solvaldelta); 1840 } 1841 1842 /** gets the average number of pseudo cost updates for the given direction over all variables 1843 * 1844 * @return the average number of pseudo cost updates for the given direction over all variables 1845 * 1846 * @pre This method can be called if SCIP is in one of the following stages: 1847 * - \ref SCIP_STAGE_SOLVING 1848 * - \ref SCIP_STAGE_SOLVED 1849 */ 1850 SCIP_Real SCIPgetAvgPseudocostCount( 1851 SCIP* scip, /**< SCIP data structure */ 1852 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */ 1853 ) 1854 { 1855 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetAvgPseudocostCount", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 1856 1857 return SCIPhistoryGetPseudocostCount(scip->stat->glbhistory, dir) 1858 / MAX(scip->transprob->nbinvars + scip->transprob->nintvars, 1); 1859 } 1860 1861 /** gets the average number of pseudo cost updates for the given direction over all variables, 1862 * only using the pseudo cost information of the current run 1863 * 1864 * @return the average number of pseudo cost updates for the given direction over all variables, 1865 * only using the pseudo cost information of the current run 1866 * 1867 * @pre This method can be called if SCIP is in one of the following stages: 1868 * - \ref SCIP_STAGE_SOLVING 1869 * - \ref SCIP_STAGE_SOLVED 1870 */ 1871 SCIP_Real SCIPgetAvgPseudocostCountCurrentRun( 1872 SCIP* scip, /**< SCIP data structure */ 1873 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */ 1874 ) 1875 { 1876 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetAvgPseudocostCountCurrentRun", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 1877 1878 return SCIPhistoryGetPseudocostCount(scip->stat->glbhistorycrun, dir) 1879 / MAX(scip->transprob->nbinvars + scip->transprob->nintvars, 1); 1880 } 1881 1882 /** gets the average pseudo cost score value over all variables, assuming a fractionality of 0.5 1883 * 1884 * @return the average pseudo cost score value over all variables, assuming a fractionality of 0.5 1885 * 1886 * @pre This method can be called if SCIP is in one of the following stages: 1887 * - \ref SCIP_STAGE_SOLVING 1888 * - \ref SCIP_STAGE_SOLVED 1889 */ 1890 SCIP_Real SCIPgetAvgPseudocostScore( 1891 SCIP* scip /**< SCIP data structure */ 1892 ) 1893 { 1894 SCIP_Real pscostdown; 1895 SCIP_Real pscostup; 1896 1897 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetAvgPseudocostScore", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 1898 1899 pscostdown = SCIPhistoryGetPseudocost(scip->stat->glbhistory, -0.5); 1900 pscostup = SCIPhistoryGetPseudocost(scip->stat->glbhistory, +0.5); 1901 1902 return SCIPbranchGetScore(scip->set, NULL, pscostdown, pscostup); 1903 } 1904 1905 /** returns the variance of pseudo costs for all variables in the requested direction 1906 * 1907 * @return the variance of pseudo costs for all variables in the requested direction 1908 * 1909 * @pre This method can be called if SCIP is in one of the following stages: 1910 * - \ref SCIP_STAGE_SOLVING 1911 * - \ref SCIP_STAGE_SOLVED 1912 */ 1913 SCIP_Real SCIPgetPseudocostVariance( 1914 SCIP* scip, /**< SCIP data structure */ 1915 SCIP_BRANCHDIR branchdir, /**< the branching direction, up or down */ 1916 SCIP_Bool onlycurrentrun /**< use only history of current run? */ 1917 ) 1918 { 1919 SCIP_HISTORY* history; 1920 1921 assert(scip != NULL); 1922 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetPseudocostVariance", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 1923 1924 history = (onlycurrentrun ? scip->stat->glbhistorycrun : scip->stat->glbhistory); 1925 assert(history != NULL); 1926 1927 return SCIPhistoryGetPseudocostVariance(history, branchdir); 1928 } 1929 1930 /** gets the number of pseudo cost updates for the given direction over all variables 1931 * 1932 * @return the number of pseudo cost updates for the given direction over all variables 1933 * 1934 * @pre This method can be called if SCIP is in one of the following stages: 1935 * - \ref SCIP_STAGE_SOLVING 1936 * - \ref SCIP_STAGE_SOLVED 1937 */ 1938 SCIP_Real SCIPgetPseudocostCount( 1939 SCIP* scip, /**< SCIP data structure */ 1940 SCIP_BRANCHDIR dir, /**< branching direction (downwards, or upwards) */ 1941 SCIP_Bool onlycurrentrun /**< use only history of current run? */ 1942 ) 1943 { 1944 SCIP_HISTORY* history; 1945 1946 assert(scip != NULL); 1947 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetPseudocostCount", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 1948 1949 history = (onlycurrentrun ? scip->stat->glbhistorycrun : scip->stat->glbhistory); 1950 1951 return SCIPhistoryGetPseudocostCount(history, dir); 1952 } 1953 1954 /** gets the average pseudo cost score value over all variables, assuming a fractionality of 0.5, 1955 * only using the pseudo cost information of the current run 1956 * 1957 * @return the average pseudo cost score value over all variables, assuming a fractionality of 0.5, 1958 * only using the pseudo cost information of the current run 1959 * 1960 * @pre This method can be called if SCIP is in one of the following stages: 1961 * - \ref SCIP_STAGE_SOLVING 1962 * - \ref SCIP_STAGE_SOLVED 1963 */ 1964 SCIP_Real SCIPgetAvgPseudocostScoreCurrentRun( 1965 SCIP* scip /**< SCIP data structure */ 1966 ) 1967 { 1968 SCIP_Real pscostdown; 1969 SCIP_Real pscostup; 1970 1971 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetAvgPseudocostScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 1972 1973 pscostdown = SCIPhistoryGetPseudocost(scip->stat->glbhistorycrun, -0.5); 1974 pscostup = SCIPhistoryGetPseudocost(scip->stat->glbhistorycrun, +0.5); 1975 1976 return SCIPbranchGetScore(scip->set, NULL, pscostdown, pscostup); 1977 } 1978 1979 /** gets the average conflict score value over all variables 1980 * 1981 * @return the average conflict score value over all variables 1982 * 1983 * @pre This method can be called if SCIP is in one of the following stages: 1984 * - \ref SCIP_STAGE_SOLVING 1985 * - \ref SCIP_STAGE_SOLVED 1986 */ 1987 SCIP_Real SCIPgetAvgConflictScore( 1988 SCIP* scip /**< SCIP data structure */ 1989 ) 1990 { 1991 SCIP_Real conflictscoredown; 1992 SCIP_Real conflictscoreup; 1993 SCIP_Real scale; 1994 1995 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetAvgConflictScore", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 1996 1997 scale = scip->transprob->nvars * scip->stat->vsidsweight; 1998 conflictscoredown = SCIPhistoryGetVSIDS(scip->stat->glbhistory, SCIP_BRANCHDIR_DOWNWARDS) / scale; 1999 conflictscoreup = SCIPhistoryGetVSIDS(scip->stat->glbhistory, SCIP_BRANCHDIR_UPWARDS) / scale; 2000 2001 return SCIPbranchGetScore(scip->set, NULL, conflictscoredown, conflictscoreup); 2002 } 2003 2004 /** gets the average conflict score value over all variables, only using the conflict score information of the current run 2005 * 2006 * @return the average conflict score value over all variables, only using the conflict score information of the current run 2007 * 2008 * @pre This method can be called if SCIP is in one of the following stages: 2009 * - \ref SCIP_STAGE_SOLVING 2010 * - \ref SCIP_STAGE_SOLVED 2011 */ 2012 SCIP_Real SCIPgetAvgConflictScoreCurrentRun( 2013 SCIP* scip /**< SCIP data structure */ 2014 ) 2015 { 2016 SCIP_Real conflictscoredown; 2017 SCIP_Real conflictscoreup; 2018 SCIP_Real scale; 2019 2020 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetAvgConflictScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 2021 2022 scale = scip->transprob->nvars * scip->stat->vsidsweight; 2023 conflictscoredown = SCIPhistoryGetVSIDS(scip->stat->glbhistorycrun, SCIP_BRANCHDIR_DOWNWARDS) / scale; 2024 conflictscoreup = SCIPhistoryGetVSIDS(scip->stat->glbhistorycrun, SCIP_BRANCHDIR_UPWARDS) / scale; 2025 2026 return SCIPbranchGetScore(scip->set, NULL, conflictscoredown, conflictscoreup); 2027 } 2028 2029 /** gets the average inference score value over all variables 2030 * 2031 * @return the average inference score value over all variables 2032 * 2033 * @pre This method can be called if SCIP is in one of the following stages: 2034 * - \ref SCIP_STAGE_SOLVING 2035 * - \ref SCIP_STAGE_SOLVED 2036 */ 2037 SCIP_Real SCIPgetAvgConflictlengthScore( 2038 SCIP* scip /**< SCIP data structure */ 2039 ) 2040 { 2041 SCIP_Real conflictlengthdown; 2042 SCIP_Real conflictlengthup; 2043 2044 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetAvgConflictlengthScore", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 2045 2046 conflictlengthdown = SCIPhistoryGetAvgConflictlength(scip->stat->glbhistory, SCIP_BRANCHDIR_DOWNWARDS); 2047 conflictlengthup = SCIPhistoryGetAvgConflictlength(scip->stat->glbhistory, SCIP_BRANCHDIR_UPWARDS); 2048 2049 return SCIPbranchGetScore(scip->set, NULL, conflictlengthdown, conflictlengthup); 2050 } 2051 2052 /** gets the average conflictlength score value over all variables, only using the conflictlength information of the 2053 * current run 2054 * 2055 * @return the average conflictlength score value over all variables, only using the conflictlength information of the 2056 * current run 2057 * 2058 * @pre This method can be called if SCIP is in one of the following stages: 2059 * - \ref SCIP_STAGE_SOLVING 2060 * - \ref SCIP_STAGE_SOLVED 2061 */ 2062 SCIP_Real SCIPgetAvgConflictlengthScoreCurrentRun( 2063 SCIP* scip /**< SCIP data structure */ 2064 ) 2065 { 2066 SCIP_Real conflictlengthdown; 2067 SCIP_Real conflictlengthup; 2068 2069 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetAvgConflictlengthScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 2070 2071 conflictlengthdown = SCIPhistoryGetAvgConflictlength(scip->stat->glbhistorycrun, SCIP_BRANCHDIR_DOWNWARDS); 2072 conflictlengthup = SCIPhistoryGetAvgConflictlength(scip->stat->glbhistorycrun, SCIP_BRANCHDIR_UPWARDS); 2073 2074 return SCIPbranchGetScore(scip->set, NULL, conflictlengthdown, conflictlengthup); 2075 } 2076 2077 /** returns the average number of inferences found after branching in given direction over all variables 2078 * 2079 * @return the average number of inferences found after branching in given direction over all variables 2080 * 2081 * @pre This method can be called if SCIP is in one of the following stages: 2082 * - \ref SCIP_STAGE_SOLVING 2083 * - \ref SCIP_STAGE_SOLVED 2084 */ 2085 SCIP_Real SCIPgetAvgInferences( 2086 SCIP* scip, /**< SCIP data structure */ 2087 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */ 2088 ) 2089 { 2090 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetAvgInferences", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 2091 2092 return SCIPhistoryGetAvgInferences(scip->stat->glbhistory, dir); 2093 } 2094 2095 /** returns the average number of inferences found after branching in given direction over all variables, 2096 * only using the inference information of the current run 2097 * 2098 * @return the average number of inferences found after branching in given direction over all variables, 2099 * only using the inference information of the current run 2100 * 2101 * @pre This method can be called if SCIP is in one of the following stages: 2102 * - \ref SCIP_STAGE_SOLVING 2103 * - \ref SCIP_STAGE_SOLVED 2104 */ 2105 SCIP_Real SCIPgetAvgInferencesCurrentRun( 2106 SCIP* scip, /**< SCIP data structure */ 2107 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */ 2108 ) 2109 { 2110 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetAvgInferencesCurrentRun", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 2111 2112 return SCIPhistoryGetAvgInferences(scip->stat->glbhistorycrun, dir); 2113 } 2114 2115 /** gets the average inference score value over all variables 2116 * 2117 * @return the average inference score value over all variables 2118 * 2119 * @pre This method can be called if SCIP is in one of the following stages: 2120 * - \ref SCIP_STAGE_SOLVING 2121 * - \ref SCIP_STAGE_SOLVED 2122 */ 2123 SCIP_Real SCIPgetAvgInferenceScore( 2124 SCIP* scip /**< SCIP data structure */ 2125 ) 2126 { 2127 SCIP_Real inferencesdown; 2128 SCIP_Real inferencesup; 2129 2130 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetAvgInferenceScore", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 2131 2132 inferencesdown = SCIPhistoryGetAvgInferences(scip->stat->glbhistory, SCIP_BRANCHDIR_DOWNWARDS); 2133 inferencesup = SCIPhistoryGetAvgInferences(scip->stat->glbhistory, SCIP_BRANCHDIR_UPWARDS); 2134 2135 return SCIPbranchGetScore(scip->set, NULL, inferencesdown, inferencesup); 2136 } 2137 2138 /** gets the average inference score value over all variables, only using the inference information of the 2139 * current run 2140 * 2141 * @return the average inference score value over all variables, only using the inference information of the 2142 * current run 2143 * 2144 * @pre This method can be called if SCIP is in one of the following stages: 2145 * - \ref SCIP_STAGE_SOLVING 2146 * - \ref SCIP_STAGE_SOLVED 2147 */ 2148 SCIP_Real SCIPgetAvgInferenceScoreCurrentRun( 2149 SCIP* scip /**< SCIP data structure */ 2150 ) 2151 { 2152 SCIP_Real inferencesdown; 2153 SCIP_Real inferencesup; 2154 2155 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetAvgInferenceScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 2156 2157 inferencesdown = SCIPhistoryGetAvgInferences(scip->stat->glbhistorycrun, SCIP_BRANCHDIR_DOWNWARDS); 2158 inferencesup = SCIPhistoryGetAvgInferences(scip->stat->glbhistorycrun, SCIP_BRANCHDIR_UPWARDS); 2159 2160 return SCIPbranchGetScore(scip->set, NULL, inferencesdown, inferencesup); 2161 } 2162 2163 /** returns the average number of cutoffs found after branching in given direction over all variables 2164 * 2165 * @return the average number of cutoffs found after branching in given direction over all variables 2166 * 2167 * @pre This method can be called if SCIP is in one of the following stages: 2168 * - \ref SCIP_STAGE_SOLVING 2169 * - \ref SCIP_STAGE_SOLVED 2170 */ 2171 SCIP_Real SCIPgetAvgCutoffs( 2172 SCIP* scip, /**< SCIP data structure */ 2173 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */ 2174 ) 2175 { 2176 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetAvgCutoffs", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 2177 2178 return SCIPhistoryGetAvgCutoffs(scip->stat->glbhistory, dir); 2179 } 2180 2181 /** returns the average number of cutoffs found after branching in given direction over all variables, 2182 * only using the cutoff information of the current run 2183 * 2184 * @return the average number of cutoffs found after branching in given direction over all variables, 2185 * only using the cutoff information of the current run 2186 * 2187 * @pre This method can be called if SCIP is in one of the following stages: 2188 * - \ref SCIP_STAGE_SOLVING 2189 * - \ref SCIP_STAGE_SOLVED 2190 */ 2191 SCIP_Real SCIPgetAvgCutoffsCurrentRun( 2192 SCIP* scip, /**< SCIP data structure */ 2193 SCIP_BRANCHDIR dir /**< branching direction (downwards, or upwards) */ 2194 ) 2195 { 2196 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetAvgCutoffsCurrentRun", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 2197 2198 return SCIPhistoryGetAvgCutoffs(scip->stat->glbhistorycrun, dir); 2199 } 2200 2201 /** gets the average cutoff score value over all variables 2202 * 2203 * @return the average cutoff score value over all variables 2204 * 2205 * @pre This method can be called if SCIP is in one of the following stages: 2206 * - \ref SCIP_STAGE_SOLVING 2207 * - \ref SCIP_STAGE_SOLVED 2208 */ 2209 SCIP_Real SCIPgetAvgCutoffScore( 2210 SCIP* scip /**< SCIP data structure */ 2211 ) 2212 { 2213 SCIP_Real cutoffsdown; 2214 SCIP_Real cutoffsup; 2215 2216 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetAvgCutoffScore", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 2217 2218 cutoffsdown = SCIPhistoryGetAvgCutoffs(scip->stat->glbhistory, SCIP_BRANCHDIR_DOWNWARDS); 2219 cutoffsup = SCIPhistoryGetAvgCutoffs(scip->stat->glbhistory, SCIP_BRANCHDIR_UPWARDS); 2220 2221 return SCIPbranchGetScore(scip->set, NULL, cutoffsdown, cutoffsup); 2222 } 2223 2224 /** gets the average cutoff score value over all variables, only using the cutoff score information of the current run 2225 * 2226 * @return the average cutoff score value over all variables, only using the cutoff score information of the current run 2227 * 2228 * @pre This method can be called if SCIP is in one of the following stages: 2229 * - \ref SCIP_STAGE_SOLVING 2230 * - \ref SCIP_STAGE_SOLVED 2231 */ 2232 SCIP_Real SCIPgetAvgCutoffScoreCurrentRun( 2233 SCIP* scip /**< SCIP data structure */ 2234 ) 2235 { 2236 SCIP_Real cutoffsdown; 2237 SCIP_Real cutoffsup; 2238 2239 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetAvgCutoffScoreCurrentRun", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 2240 2241 cutoffsdown = SCIPhistoryGetAvgCutoffs(scip->stat->glbhistorycrun, SCIP_BRANCHDIR_DOWNWARDS); 2242 cutoffsup = SCIPhistoryGetAvgCutoffs(scip->stat->glbhistorycrun, SCIP_BRANCHDIR_UPWARDS); 2243 2244 return SCIPbranchGetScore(scip->set, NULL, cutoffsdown, cutoffsup); 2245 } 2246 2247 /** returns the average normalized efficacy of a GMI cut over all variables 2248 * 2249 * @return increases the average normalized efficacy of a GMI cut over all variables 2250 * 2251 * @pre This method can be called if SCIP is in one of the following stages: 2252 * - \ref SCIP_STAGE_SOLVING 2253 * - \ref SCIP_STAGE_SOLVED 2254 */ 2255 void SCIPincAvgGMIeff( 2256 SCIP* scip, /**< SCIP data structure */ 2257 SCIP_Real gmieff /**< average normalized GMI cut efficacy over all variables */ 2258 ) 2259 { 2260 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPincAvgGMIeff", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 2261 2262 SCIPhistoryIncGMIeffSum(scip->stat->glbhistory, gmieff); 2263 } 2264 2265 /** Increases the cumulative normalized efficacy of average (over all variables) GMI cuts 2266 * 2267 * @return the average normalized efficacy of a GMI cut over all variables 2268 * 2269 * @pre This method can be called if SCIP is in one of the following stages: 2270 * - \ref SCIP_STAGE_SOLVING 2271 * - \ref SCIP_STAGE_SOLVED 2272 */ 2273 SCIP_Real SCIPgetAvgGMIeff( 2274 SCIP* scip /**< SCIP data structure */ 2275 ) 2276 { 2277 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetAvgGMIeff", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 2278 2279 return SCIPhistoryGetAvgGMIeff(scip->stat->glbhistory); 2280 } 2281 2282 /** computes a deterministic measure of time from statistics 2283 * 2284 * @return the deterministic time 2285 * 2286 * @pre This method can be called if SCIP is in one of the following stages: 2287 * - \ref SCIP_STAGE_PRESOLVING 2288 * - \ref SCIP_STAGE_PRESOLVED 2289 * - \ref SCIP_STAGE_SOLVING 2290 * - \ref SCIP_STAGE_SOLVED 2291 */ 2292 SCIP_Real SCIPgetDeterministicTime( 2293 SCIP* scip /**< SCIP data structure */ 2294 ) 2295 { 2296 /* TODO: SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetDeterministicTime", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); */ 2297 if(scip->stat == NULL) 2298 return 0.0; 2299 2300 return 1e-6 * scip->stat->nnz * ( 2301 0.00328285264101 * scip->stat->nprimalresolvelpiterations + 2302 0.00531625104146 * scip->stat->ndualresolvelpiterations + 2303 0.000738719124051 * scip->stat->nprobboundchgs + 2304 0.0011123144764 * scip->stat->nisstoppedcalls ); 2305 } 2306 2307 /** outputs problem to file stream */ 2308 static 2309 SCIP_RETCODE printProblem( 2310 SCIP* scip, /**< SCIP data structure */ 2311 SCIP_PROB* prob, /**< problem data */ 2312 FILE* file, /**< output file (or NULL for standard output) */ 2313 const char* extension, /**< file format (or NULL for default CIP format) */ 2314 SCIP_Bool genericnames /**< using generic variable and constraint names? */ 2315 ) 2316 { 2317 SCIP_RESULT result; 2318 int i; 2319 assert(scip != NULL); 2320 assert(prob != NULL); 2321 2322 /* try all readers until one could read the file */ 2323 result = SCIP_DIDNOTRUN; 2324 for( i = 0; i < scip->set->nreaders && result == SCIP_DIDNOTRUN; ++i ) 2325 { 2326 SCIP_RETCODE retcode; 2327 2328 if( extension != NULL ) 2329 retcode = SCIPreaderWrite(scip->set->readers[i], prob, scip->set, file, extension, genericnames, &result); 2330 else 2331 retcode = SCIPreaderWrite(scip->set->readers[i], prob, scip->set, file, "cip", genericnames, &result); 2332 2333 /* check for reader errors */ 2334 if( retcode == SCIP_WRITEERROR ) 2335 return retcode; 2336 2337 SCIP_CALL( retcode ); 2338 } 2339 2340 switch( result ) 2341 { 2342 case SCIP_DIDNOTRUN: 2343 return SCIP_PLUGINNOTFOUND; 2344 2345 case SCIP_SUCCESS: 2346 return SCIP_OKAY; 2347 2348 default: 2349 assert(i < scip->set->nreaders); 2350 SCIPerrorMessage("invalid result code <%d> from reader <%s> writing <%s> format\n", 2351 result, SCIPreaderGetName(scip->set->readers[i]), extension); 2352 return SCIP_READERROR; 2353 } /*lint !e788*/ 2354 } 2355 2356 /** outputs original problem to file stream 2357 * 2358 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 2359 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 2360 * 2361 * @pre This method can be called if SCIP is in one of the following stages: 2362 * - \ref SCIP_STAGE_PROBLEM 2363 * - \ref SCIP_STAGE_TRANSFORMING 2364 * - \ref SCIP_STAGE_TRANSFORMED 2365 * - \ref SCIP_STAGE_INITPRESOLVE 2366 * - \ref SCIP_STAGE_PRESOLVING 2367 * - \ref SCIP_STAGE_EXITPRESOLVE 2368 * - \ref SCIP_STAGE_PRESOLVED 2369 * - \ref SCIP_STAGE_INITSOLVE 2370 * - \ref SCIP_STAGE_SOLVING 2371 * - \ref SCIP_STAGE_SOLVED 2372 * - \ref SCIP_STAGE_EXITSOLVE 2373 * - \ref SCIP_STAGE_FREETRANS 2374 */ 2375 SCIP_RETCODE SCIPprintOrigProblem( 2376 SCIP* scip, /**< SCIP data structure */ 2377 FILE* file, /**< output file (or NULL for standard output) */ 2378 const char* extension, /**< file format (or NULL for default CIP format)*/ 2379 SCIP_Bool genericnames /**< using generic variable and constraint names? */ 2380 ) 2381 { 2382 SCIP_RETCODE retcode; 2383 2384 SCIP_CALL( SCIPcheckStage(scip, "SCIPprintOrigProblem", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 2385 2386 assert(scip != NULL); 2387 assert( scip->origprob != NULL ); 2388 2389 retcode = printProblem(scip, scip->origprob, file, extension, genericnames); 2390 2391 /* check for write errors */ 2392 if( retcode == SCIP_WRITEERROR || retcode == SCIP_PLUGINNOTFOUND ) 2393 return retcode; 2394 else 2395 { 2396 SCIP_CALL( retcode ); 2397 } 2398 2399 return SCIP_OKAY; 2400 } 2401 2402 /** outputs transformed problem of the current node to file stream 2403 * 2404 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 2405 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 2406 * 2407 * @pre This method can be called if SCIP is in one of the following stages: 2408 * - \ref SCIP_STAGE_TRANSFORMED 2409 * - \ref SCIP_STAGE_INITPRESOLVE 2410 * - \ref SCIP_STAGE_PRESOLVING 2411 * - \ref SCIP_STAGE_EXITPRESOLVE 2412 * - \ref SCIP_STAGE_PRESOLVED 2413 * - \ref SCIP_STAGE_INITSOLVE 2414 * - \ref SCIP_STAGE_SOLVING 2415 * - \ref SCIP_STAGE_SOLVED 2416 * - \ref SCIP_STAGE_EXITSOLVE 2417 * - \ref SCIP_STAGE_FREETRANS 2418 */ 2419 SCIP_RETCODE SCIPprintTransProblem( 2420 SCIP* scip, /**< SCIP data structure */ 2421 FILE* file, /**< output file (or NULL for standard output) */ 2422 const char* extension, /**< file format (or NULL for default CIP format)*/ 2423 SCIP_Bool genericnames /**< using generic variable and constraint names? */ 2424 ) 2425 { 2426 SCIP_RETCODE retcode; 2427 2428 SCIP_CALL( SCIPcheckStage(scip, "SCIPprintTransProblem", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 2429 2430 assert(scip != NULL); 2431 assert(scip->transprob != NULL ); 2432 2433 retcode = printProblem(scip, scip->transprob, file, extension, genericnames); 2434 2435 /* check for write errors */ 2436 if( retcode == SCIP_WRITEERROR || retcode == SCIP_PLUGINNOTFOUND ) 2437 return retcode; 2438 else 2439 { 2440 SCIP_CALL( retcode ); 2441 } 2442 2443 return SCIP_OKAY; 2444 } 2445 2446 /** outputs status statistics 2447 * 2448 * @note If limits have been changed between the solution and the call to this function, the status is recomputed and 2449 * thus may to correspond to the original status. 2450 * 2451 * @pre This method can be called if SCIP is in one of the following stages: 2452 * - \ref SCIP_STAGE_INIT 2453 * - \ref SCIP_STAGE_PROBLEM 2454 * - \ref SCIP_STAGE_TRANSFORMED 2455 * - \ref SCIP_STAGE_INITPRESOLVE 2456 * - \ref SCIP_STAGE_PRESOLVING 2457 * - \ref SCIP_STAGE_EXITPRESOLVE 2458 * - \ref SCIP_STAGE_PRESOLVED 2459 * - \ref SCIP_STAGE_SOLVING 2460 * - \ref SCIP_STAGE_SOLVED 2461 */ 2462 void SCIPprintStatusStatistics( 2463 SCIP* scip, /**< SCIP data structure */ 2464 FILE* file /**< output file */ 2465 ) 2466 { 2467 assert(scip != NULL); 2468 assert(scip->set != NULL); 2469 2470 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPprintStatusStatistics", TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 2471 2472 SCIPmessageFPrintInfo(scip->messagehdlr, file, "SCIP Status : "); 2473 SCIP_CALL_ABORT( SCIPprintStage(scip, file) ); 2474 SCIPmessageFPrintInfo(scip->messagehdlr, file, "\n"); 2475 } 2476 2477 /** outputs statistics for original problem 2478 * 2479 * @pre This method can be called if SCIP is in one of the following stages: 2480 * - \ref SCIP_STAGE_PROBLEM 2481 * - \ref SCIP_STAGE_TRANSFORMED 2482 * - \ref SCIP_STAGE_INITPRESOLVE 2483 * - \ref SCIP_STAGE_PRESOLVING 2484 * - \ref SCIP_STAGE_EXITPRESOLVE 2485 * - \ref SCIP_STAGE_PRESOLVED 2486 * - \ref SCIP_STAGE_SOLVING 2487 * - \ref SCIP_STAGE_SOLVED 2488 */ 2489 void SCIPprintOrigProblemStatistics( 2490 SCIP* scip, /**< SCIP data structure */ 2491 FILE* file /**< output file */ 2492 ) 2493 { 2494 assert(scip != NULL); 2495 assert(scip->set != NULL); 2496 2497 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPprintOrigProblemStatistics", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 2498 2499 SCIPmessageFPrintInfo(scip->messagehdlr, file, "Original Problem :\n"); 2500 SCIPprobPrintStatistics(scip->origprob, scip->set, scip->messagehdlr, file); 2501 } 2502 2503 /** outputs statistics for transformed problem 2504 * 2505 * @pre This method can be called if SCIP is in one of the following stages: 2506 * - \ref SCIP_STAGE_PROBLEM 2507 * - \ref SCIP_STAGE_TRANSFORMED 2508 * - \ref SCIP_STAGE_INITPRESOLVE 2509 * - \ref SCIP_STAGE_PRESOLVING 2510 * - \ref SCIP_STAGE_EXITPRESOLVE 2511 * - \ref SCIP_STAGE_PRESOLVED 2512 * - \ref SCIP_STAGE_SOLVING 2513 * - \ref SCIP_STAGE_SOLVED 2514 */ 2515 void SCIPprintTransProblemStatistics( 2516 SCIP* scip, /**< SCIP data structure */ 2517 FILE* file /**< output file */ 2518 ) 2519 { 2520 assert(scip != NULL); 2521 assert(scip->set != NULL); 2522 2523 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPprintTransProblemStatistics", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 2524 2525 SCIPmessageFPrintInfo(scip->messagehdlr, file, "Presolved Problem :\n"); 2526 SCIPprobPrintStatistics(scip->transprob, scip->set, scip->messagehdlr, file); 2527 SCIPmessageFPrintInfo(scip->messagehdlr, file, " Nonzeros : %" SCIP_LONGINT_FORMAT " constraint, %" SCIP_LONGINT_FORMAT " clique table\n", 2528 scip->stat->nnz, SCIPcliquetableGetNEntries(scip->cliquetable)); 2529 } 2530 2531 /** outputs presolver statistics 2532 * 2533 * @pre This method can be called if SCIP is in one of the following stages: 2534 * - \ref SCIP_STAGE_TRANSFORMED 2535 * - \ref SCIP_STAGE_INITPRESOLVE 2536 * - \ref SCIP_STAGE_PRESOLVING 2537 * - \ref SCIP_STAGE_EXITPRESOLVE 2538 * - \ref SCIP_STAGE_PRESOLVED 2539 * - \ref SCIP_STAGE_SOLVING 2540 * - \ref SCIP_STAGE_SOLVED 2541 */ 2542 void SCIPprintPresolverStatistics( 2543 SCIP* scip, /**< SCIP data structure */ 2544 FILE* file /**< output file */ 2545 ) 2546 { 2547 int i; 2548 2549 assert(scip != NULL); 2550 assert(scip->set != NULL); 2551 2552 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPprintPresolverStatistics", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 2553 2554 SCIPmessageFPrintInfo(scip->messagehdlr, file, "Presolvers : ExecTime SetupTime Calls FixedVars AggrVars ChgTypes ChgBounds AddHoles DelCons AddCons ChgSides ChgCoefs\n"); 2555 2556 /* sort presolvers w.r.t. their name */ 2557 SCIPsetSortPresolsName(scip->set); 2558 2559 /* presolver statistics */ 2560 for( i = 0; i < scip->set->npresols; ++i ) 2561 { 2562 SCIP_PRESOL* presol; 2563 presol = scip->set->presols[i]; 2564 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %-17.17s:", SCIPpresolGetName(presol)); 2565 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %10.2f %10.2f %6d %10d %10d %10d %10d %10d %10d %10d %10d %10d\n", 2566 SCIPpresolGetTime(presol), 2567 SCIPpresolGetSetupTime(presol), 2568 SCIPpresolGetNCalls(presol), 2569 SCIPpresolGetNFixedVars(presol), 2570 SCIPpresolGetNAggrVars(presol), 2571 SCIPpresolGetNChgVarTypes(presol), 2572 SCIPpresolGetNChgBds(presol), 2573 SCIPpresolGetNAddHoles(presol), 2574 SCIPpresolGetNDelConss(presol), 2575 SCIPpresolGetNAddConss(presol), 2576 SCIPpresolGetNChgSides(presol), 2577 SCIPpresolGetNChgCoefs(presol)); 2578 } 2579 2580 /* sort propagators w.r.t. their name */ 2581 SCIPsetSortPropsName(scip->set); 2582 2583 for( i = 0; i < scip->set->nprops; ++i ) 2584 { 2585 SCIP_PROP* prop; 2586 prop = scip->set->props[i]; 2587 if( SCIPpropDoesPresolve(prop) ) 2588 { 2589 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %-17.17s:", SCIPpropGetName(prop)); 2590 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %10.2f %10.2f %6d %10d %10d %10d %10d %10d %10d %10d %10d %10d\n", 2591 SCIPpropGetPresolTime(prop), 2592 SCIPpropGetSetupTime(prop), 2593 SCIPpropGetNPresolCalls(prop), 2594 SCIPpropGetNFixedVars(prop), 2595 SCIPpropGetNAggrVars(prop), 2596 SCIPpropGetNChgVarTypes(prop), 2597 SCIPpropGetNChgBds(prop), 2598 SCIPpropGetNAddHoles(prop), 2599 SCIPpropGetNDelConss(prop), 2600 SCIPpropGetNAddConss(prop), 2601 SCIPpropGetNChgSides(prop), 2602 SCIPpropGetNChgCoefs(prop)); 2603 } 2604 } 2605 2606 /* constraint handler presolving methods statistics */ 2607 for( i = 0; i < scip->set->nconshdlrs; ++i ) 2608 { 2609 SCIP_CONSHDLR* conshdlr; 2610 int maxnactiveconss; 2611 2612 conshdlr = scip->set->conshdlrs[i]; 2613 maxnactiveconss = SCIPconshdlrGetMaxNActiveConss(conshdlr); 2614 if( SCIPconshdlrDoesPresolve(conshdlr) 2615 && (maxnactiveconss > 0 || !SCIPconshdlrNeedsCons(conshdlr) 2616 || SCIPconshdlrGetNFixedVars(conshdlr) > 0 2617 || SCIPconshdlrGetNAggrVars(conshdlr) > 0 2618 || SCIPconshdlrGetNChgVarTypes(conshdlr) > 0 2619 || SCIPconshdlrGetNChgBds(conshdlr) > 0 2620 || SCIPconshdlrGetNAddHoles(conshdlr) > 0 2621 || SCIPconshdlrGetNDelConss(conshdlr) > 0 2622 || SCIPconshdlrGetNAddConss(conshdlr) > 0 2623 || SCIPconshdlrGetNChgSides(conshdlr) > 0 2624 || SCIPconshdlrGetNChgCoefs(conshdlr) > 0 2625 || SCIPconshdlrGetNUpgdConss(conshdlr) > 0) ) 2626 { 2627 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %-17.17s:", SCIPconshdlrGetName(conshdlr)); 2628 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %10.2f %10.2f %6d %10d %10d %10d %10d %10d %10d %10d %10d %10d\n", 2629 SCIPconshdlrGetPresolTime(conshdlr), 2630 SCIPconshdlrGetSetupTime(conshdlr), 2631 SCIPconshdlrGetNPresolCalls(conshdlr), 2632 SCIPconshdlrGetNFixedVars(conshdlr), 2633 SCIPconshdlrGetNAggrVars(conshdlr), 2634 SCIPconshdlrGetNChgVarTypes(conshdlr), 2635 SCIPconshdlrGetNChgBds(conshdlr), 2636 SCIPconshdlrGetNAddHoles(conshdlr), 2637 SCIPconshdlrGetNDelConss(conshdlr), 2638 SCIPconshdlrGetNAddConss(conshdlr), 2639 SCIPconshdlrGetNChgSides(conshdlr), 2640 SCIPconshdlrGetNChgCoefs(conshdlr)); 2641 } 2642 } 2643 2644 /* root node bound changes */ 2645 SCIPmessageFPrintInfo(scip->messagehdlr, file, " root node : - - - %10d - - %10d - - - - -\n", 2646 scip->stat->nrootintfixings, scip->stat->nrootboundchgs); 2647 } 2648 2649 /** outputs constraint statistics 2650 * 2651 * @pre This method can be called if SCIP is in one of the following stages: 2652 * - \ref SCIP_STAGE_TRANSFORMED 2653 * - \ref SCIP_STAGE_INITPRESOLVE 2654 * - \ref SCIP_STAGE_PRESOLVING 2655 * - \ref SCIP_STAGE_EXITPRESOLVE 2656 * - \ref SCIP_STAGE_PRESOLVED 2657 * - \ref SCIP_STAGE_SOLVING 2658 * - \ref SCIP_STAGE_SOLVED 2659 */ 2660 void SCIPprintConstraintStatistics( 2661 SCIP* scip, /**< SCIP data structure */ 2662 FILE* file /**< output file */ 2663 ) 2664 { 2665 int i; 2666 2667 assert(scip != NULL); 2668 assert(scip->set != NULL); 2669 2670 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPprintConstraintStatistics", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 2671 2672 /* Add maximal number of constraints of the same type? So far this information is not added because of lack of space. */ 2673 SCIPmessageFPrintInfo(scip->messagehdlr, file, "Constraints : Number MaxNumber #Separate #Propagate #EnfoLP #EnfoRelax #EnfoPS #Check #ResProp Cutoffs DomReds Cuts Applied Conss Children\n"); 2674 2675 for( i = 0; i < scip->set->nconshdlrs; ++i ) 2676 { 2677 SCIP_CONSHDLR* conshdlr; 2678 int startnactiveconss; 2679 int maxnactiveconss; 2680 2681 conshdlr = scip->set->conshdlrs[i]; 2682 startnactiveconss = SCIPconshdlrGetStartNActiveConss(conshdlr); 2683 maxnactiveconss = SCIPconshdlrGetMaxNActiveConss(conshdlr); 2684 if( maxnactiveconss > 0 || !SCIPconshdlrNeedsCons(conshdlr) ) 2685 { 2686 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %-17.17s:", SCIPconshdlrGetName(conshdlr)); 2687 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %10d%c%10d %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT "\n", 2688 startnactiveconss, 2689 maxnactiveconss > startnactiveconss ? '+' : ' ', 2690 maxnactiveconss, 2691 SCIPconshdlrGetNSepaCalls(conshdlr), 2692 SCIPconshdlrGetNPropCalls(conshdlr), 2693 SCIPconshdlrGetNEnfoLPCalls(conshdlr), 2694 SCIPconshdlrGetNEnfoRelaxCalls(conshdlr), 2695 SCIPconshdlrGetNEnfoPSCalls(conshdlr), 2696 SCIPconshdlrGetNCheckCalls(conshdlr), 2697 SCIPconshdlrGetNRespropCalls(conshdlr), 2698 SCIPconshdlrGetNCutoffs(conshdlr), 2699 SCIPconshdlrGetNDomredsFound(conshdlr), 2700 SCIPconshdlrGetNCutsFound(conshdlr), 2701 SCIPconshdlrGetNCutsApplied(conshdlr), 2702 SCIPconshdlrGetNConssFound(conshdlr), 2703 SCIPconshdlrGetNChildren(conshdlr)); 2704 } 2705 } 2706 } 2707 2708 /** outputs constraint timing statistics 2709 * 2710 * @pre This method can be called if SCIP is in one of the following stages: 2711 * - \ref SCIP_STAGE_TRANSFORMED 2712 * - \ref SCIP_STAGE_INITPRESOLVE 2713 * - \ref SCIP_STAGE_PRESOLVING 2714 * - \ref SCIP_STAGE_EXITPRESOLVE 2715 * - \ref SCIP_STAGE_PRESOLVED 2716 * - \ref SCIP_STAGE_SOLVING 2717 * - \ref SCIP_STAGE_SOLVED 2718 */ 2719 void SCIPprintConstraintTimingStatistics( 2720 SCIP* scip, /**< SCIP data structure */ 2721 FILE* file /**< output file */ 2722 ) 2723 { 2724 int i; 2725 2726 assert(scip != NULL); 2727 assert(scip->set != NULL); 2728 2729 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPprintConstraintTimingStatistics", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 2730 2731 SCIPmessageFPrintInfo(scip->messagehdlr, file, "Constraint Timings : TotalTime SetupTime Separate Propagate EnfoLP EnfoPS EnfoRelax Check ResProp SB-Prop\n"); 2732 2733 for( i = 0; i < scip->set->nconshdlrs; ++i ) 2734 { 2735 SCIP_CONSHDLR* conshdlr; 2736 int maxnactiveconss; 2737 2738 conshdlr = scip->set->conshdlrs[i]; 2739 maxnactiveconss = SCIPconshdlrGetMaxNActiveConss(conshdlr); 2740 if( maxnactiveconss > 0 || !SCIPconshdlrNeedsCons(conshdlr) ) 2741 { 2742 SCIP_Real totaltime; 2743 2744 totaltime = SCIPconshdlrGetSepaTime(conshdlr) + SCIPconshdlrGetPropTime(conshdlr) 2745 + SCIPconshdlrGetStrongBranchPropTime(conshdlr) 2746 + SCIPconshdlrGetEnfoLPTime(conshdlr) 2747 + SCIPconshdlrGetEnfoPSTime(conshdlr) 2748 + SCIPconshdlrGetEnfoRelaxTime(conshdlr) 2749 + SCIPconshdlrGetCheckTime(conshdlr) 2750 + SCIPconshdlrGetRespropTime(conshdlr) 2751 + SCIPconshdlrGetSetupTime(conshdlr); 2752 2753 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %-17.17s:", SCIPconshdlrGetName(conshdlr)); 2754 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %10.2f %10.2f %10.2f %10.2f %10.2f %10.2f %10.2f %10.2f %10.2f %10.2f\n", 2755 totaltime, 2756 SCIPconshdlrGetSetupTime(conshdlr), 2757 SCIPconshdlrGetSepaTime(conshdlr), 2758 SCIPconshdlrGetPropTime(conshdlr), 2759 SCIPconshdlrGetEnfoLPTime(conshdlr), 2760 SCIPconshdlrGetEnfoPSTime(conshdlr), 2761 SCIPconshdlrGetEnfoRelaxTime(conshdlr), 2762 SCIPconshdlrGetCheckTime(conshdlr), 2763 SCIPconshdlrGetRespropTime(conshdlr), 2764 SCIPconshdlrGetStrongBranchPropTime(conshdlr)); 2765 } 2766 } 2767 } 2768 2769 /** outputs propagator statistics 2770 * 2771 * @pre This method can be called if SCIP is in one of the following stages: 2772 * - \ref SCIP_STAGE_TRANSFORMED 2773 * - \ref SCIP_STAGE_INITPRESOLVE 2774 * - \ref SCIP_STAGE_PRESOLVING 2775 * - \ref SCIP_STAGE_EXITPRESOLVE 2776 * - \ref SCIP_STAGE_PRESOLVED 2777 * - \ref SCIP_STAGE_SOLVING 2778 * - \ref SCIP_STAGE_SOLVED 2779 */ 2780 void SCIPprintPropagatorStatistics( 2781 SCIP* scip, /**< SCIP data structure */ 2782 FILE* file /**< output file */ 2783 ) 2784 { 2785 int i; 2786 2787 assert(scip != NULL); 2788 assert(scip->set != NULL); 2789 2790 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPprintPropagatorStatistics", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 2791 2792 SCIPmessageFPrintInfo(scip->messagehdlr, file, "Propagators : #Propagate #ResProp Cutoffs DomReds\n"); 2793 2794 /* sort propagaters w.r.t. their name */ 2795 SCIPsetSortPropsName(scip->set); 2796 2797 for( i = 0; i < scip->set->nprops; ++i ) 2798 { 2799 SCIP_PROP* prop; 2800 prop = scip->set->props[i]; 2801 2802 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %-17.17s: %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT "\n", 2803 SCIPpropGetName(prop), 2804 SCIPpropGetNCalls(prop), 2805 SCIPpropGetNRespropCalls(prop), 2806 SCIPpropGetNCutoffs(prop), 2807 SCIPpropGetNDomredsFound(prop)); 2808 } 2809 2810 SCIPmessageFPrintInfo(scip->messagehdlr, file, "Propagator Timings : TotalTime SetupTime Presolve Propagate ResProp SB-Prop\n"); 2811 2812 for( i = 0; i < scip->set->nprops; ++i ) 2813 { 2814 SCIP_PROP* prop; 2815 SCIP_Real totaltime; 2816 2817 prop = scip->set->props[i]; 2818 totaltime = SCIPpropGetPresolTime(prop) + SCIPpropGetTime(prop) + SCIPpropGetRespropTime(prop) 2819 + SCIPpropGetStrongBranchPropTime(prop) + SCIPpropGetSetupTime(prop); 2820 2821 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %-17.17s:", SCIPpropGetName(prop)); 2822 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %10.2f %10.2f %10.2f %10.2f %10.2f %10.2f\n", 2823 totaltime, 2824 SCIPpropGetSetupTime(prop), 2825 SCIPpropGetPresolTime(prop), 2826 SCIPpropGetTime(prop), 2827 SCIPpropGetRespropTime(prop), 2828 SCIPpropGetStrongBranchPropTime(prop)); 2829 } 2830 } 2831 2832 /** outputs conflict statistics 2833 * 2834 * @pre This method can be called if SCIP is in one of the following stages: 2835 * - \ref SCIP_STAGE_TRANSFORMED 2836 * - \ref SCIP_STAGE_INITPRESOLVE 2837 * - \ref SCIP_STAGE_PRESOLVING 2838 * - \ref SCIP_STAGE_EXITPRESOLVE 2839 * - \ref SCIP_STAGE_PRESOLVED 2840 * - \ref SCIP_STAGE_SOLVING 2841 * - \ref SCIP_STAGE_SOLVED 2842 */ 2843 void SCIPprintConflictStatistics( 2844 SCIP* scip, /**< SCIP data structure */ 2845 FILE* file /**< output file */ 2846 ) 2847 { 2848 char initstoresize[SCIP_MAXSTRLEN]; 2849 char maxstoresize[SCIP_MAXSTRLEN]; 2850 2851 assert(scip != NULL); 2852 assert(scip->set != NULL); 2853 2854 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPprintConflictStatistics", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 2855 2856 if( scip->set->conf_maxstoresize == 0 ) 2857 { 2858 (void)SCIPsnprintf(initstoresize, SCIP_MAXSTRLEN, "inf"); 2859 (void)SCIPsnprintf(maxstoresize, SCIP_MAXSTRLEN, "inf"); 2860 } 2861 else 2862 { 2863 int initsize = SCIPconflictstoreGetInitPoolSize(scip->conflictstore); 2864 int maxsize = SCIPconflictstoreGetMaxPoolSize(scip->conflictstore); 2865 2866 if( maxsize == -1 ) 2867 { 2868 (void)SCIPsnprintf(initstoresize, SCIP_MAXSTRLEN, "--"); 2869 (void)SCIPsnprintf(maxstoresize, SCIP_MAXSTRLEN, "--"); 2870 } 2871 else 2872 { 2873 assert(initsize >= 0); 2874 assert(maxsize >= 0); 2875 2876 (void)SCIPsnprintf(initstoresize, SCIP_MAXSTRLEN, "%d", initsize); 2877 (void)SCIPsnprintf(maxstoresize, SCIP_MAXSTRLEN, "%d", maxsize); 2878 } 2879 } 2880 SCIPmessageFPrintInfo(scip->messagehdlr, file, "Conflict Analysis : Time Calls Success DomReds Conflicts Literals Reconvs ReconvLits Dualrays Nonzeros LP Iters (pool size: [%s,%s])\n", initstoresize, maxstoresize); 2881 SCIPmessageFPrintInfo(scip->messagehdlr, file, " propagation : %10.2f %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " - %10" SCIP_LONGINT_FORMAT " %10.1f %10" SCIP_LONGINT_FORMAT " %10.1f - - -\n", 2882 SCIPconflictGetPropTime(scip->conflict), 2883 SCIPconflictGetNPropCalls(scip->conflict), 2884 SCIPconflictGetNPropSuccess(scip->conflict), 2885 SCIPconflictGetNPropConflictConss(scip->conflict), 2886 SCIPconflictGetNPropConflictConss(scip->conflict) > 0 2887 ? (SCIP_Real)SCIPconflictGetNPropConflictLiterals(scip->conflict) 2888 / (SCIP_Real)SCIPconflictGetNPropConflictConss(scip->conflict) : 0, 2889 SCIPconflictGetNPropReconvergenceConss(scip->conflict), 2890 SCIPconflictGetNPropReconvergenceConss(scip->conflict) > 0 2891 ? (SCIP_Real)SCIPconflictGetNPropReconvergenceLiterals(scip->conflict) 2892 / (SCIP_Real)SCIPconflictGetNPropReconvergenceConss(scip->conflict) : 0); 2893 SCIPmessageFPrintInfo(scip->messagehdlr, file, " infeasible LP : %10.2f %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " - %10" SCIP_LONGINT_FORMAT " %10.1f %10" SCIP_LONGINT_FORMAT " %10.1f %10" SCIP_LONGINT_FORMAT " %10.1f %10" SCIP_LONGINT_FORMAT "\n", 2894 SCIPconflictGetInfeasibleLPTime(scip->conflict), 2895 SCIPconflictGetNInfeasibleLPCalls(scip->conflict), 2896 SCIPconflictGetNInfeasibleLPSuccess(scip->conflict), 2897 SCIPconflictGetNInfeasibleLPConflictConss(scip->conflict), 2898 SCIPconflictGetNInfeasibleLPConflictConss(scip->conflict) > 0 2899 ? (SCIP_Real)SCIPconflictGetNInfeasibleLPConflictLiterals(scip->conflict) 2900 / (SCIP_Real)SCIPconflictGetNInfeasibleLPConflictConss(scip->conflict) : 0, 2901 SCIPconflictGetNInfeasibleLPReconvergenceConss(scip->conflict), 2902 SCIPconflictGetNInfeasibleLPReconvergenceConss(scip->conflict) > 0 2903 ? (SCIP_Real)SCIPconflictGetNInfeasibleLPReconvergenceLiterals(scip->conflict) 2904 / (SCIP_Real)SCIPconflictGetNInfeasibleLPReconvergenceConss(scip->conflict) : 0, 2905 SCIPconflictGetNDualproofsInfSuccess(scip->conflict), 2906 SCIPconflictGetNDualproofsInfSuccess(scip->conflict) > 0 2907 ? (SCIP_Real)SCIPconflictGetNDualproofsInfNonzeros(scip->conflict) 2908 / (SCIP_Real)SCIPconflictGetNDualproofsInfSuccess(scip->conflict) : 0, 2909 SCIPconflictGetNInfeasibleLPIterations(scip->conflict)); 2910 SCIPmessageFPrintInfo(scip->messagehdlr, file, " bound exceed. LP : %10.2f %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " - %10" SCIP_LONGINT_FORMAT " %10.1f %10" SCIP_LONGINT_FORMAT " %10.1f %10" SCIP_LONGINT_FORMAT " %10.1f %10" SCIP_LONGINT_FORMAT "\n", 2911 SCIPconflictGetBoundexceedingLPTime(scip->conflict), 2912 SCIPconflictGetNBoundexceedingLPCalls(scip->conflict), 2913 SCIPconflictGetNBoundexceedingLPSuccess(scip->conflict), 2914 SCIPconflictGetNBoundexceedingLPConflictConss(scip->conflict), 2915 SCIPconflictGetNBoundexceedingLPConflictConss(scip->conflict) > 0 2916 ? (SCIP_Real)SCIPconflictGetNBoundexceedingLPConflictLiterals(scip->conflict) 2917 / (SCIP_Real)SCIPconflictGetNBoundexceedingLPConflictConss(scip->conflict) : 0, 2918 SCIPconflictGetNBoundexceedingLPReconvergenceConss(scip->conflict), 2919 SCIPconflictGetNBoundexceedingLPReconvergenceConss(scip->conflict) > 0 2920 ? (SCIP_Real)SCIPconflictGetNBoundexceedingLPReconvergenceLiterals(scip->conflict) 2921 / (SCIP_Real)SCIPconflictGetNBoundexceedingLPReconvergenceConss(scip->conflict) : 0, 2922 SCIPconflictGetNDualproofsBndSuccess(scip->conflict), 2923 SCIPconflictGetNDualproofsBndSuccess(scip->conflict) > 0 2924 ? (SCIP_Real)SCIPconflictGetNDualproofsBndNonzeros(scip->conflict) 2925 / (SCIP_Real)SCIPconflictGetNDualproofsBndSuccess(scip->conflict) : 0, 2926 SCIPconflictGetNBoundexceedingLPIterations(scip->conflict)); 2927 SCIPmessageFPrintInfo(scip->messagehdlr, file, " strong branching : %10.2f %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " - %10" SCIP_LONGINT_FORMAT " %10.1f %10" SCIP_LONGINT_FORMAT " %10.1f - - %10" SCIP_LONGINT_FORMAT "\n", 2928 SCIPconflictGetStrongbranchTime(scip->conflict), 2929 SCIPconflictGetNStrongbranchCalls(scip->conflict), 2930 SCIPconflictGetNStrongbranchSuccess(scip->conflict), 2931 SCIPconflictGetNStrongbranchConflictConss(scip->conflict), 2932 SCIPconflictGetNStrongbranchConflictConss(scip->conflict) > 0 2933 ? (SCIP_Real)SCIPconflictGetNStrongbranchConflictLiterals(scip->conflict) 2934 / (SCIP_Real)SCIPconflictGetNStrongbranchConflictConss(scip->conflict) : 0, 2935 SCIPconflictGetNStrongbranchReconvergenceConss(scip->conflict), 2936 SCIPconflictGetNStrongbranchReconvergenceConss(scip->conflict) > 0 2937 ? (SCIP_Real)SCIPconflictGetNStrongbranchReconvergenceLiterals(scip->conflict) 2938 / (SCIP_Real)SCIPconflictGetNStrongbranchReconvergenceConss(scip->conflict) : 0, 2939 SCIPconflictGetNStrongbranchIterations(scip->conflict)); 2940 SCIPmessageFPrintInfo(scip->messagehdlr, file, " pseudo solution : %10.2f %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " - %10" SCIP_LONGINT_FORMAT " %10.1f %10" SCIP_LONGINT_FORMAT " %10.1f - - -\n", 2941 SCIPconflictGetPseudoTime(scip->conflict), 2942 SCIPconflictGetNPseudoCalls(scip->conflict), 2943 SCIPconflictGetNPseudoSuccess(scip->conflict), 2944 SCIPconflictGetNPseudoConflictConss(scip->conflict), 2945 SCIPconflictGetNPseudoConflictConss(scip->conflict) > 0 2946 ? (SCIP_Real)SCIPconflictGetNPseudoConflictLiterals(scip->conflict) 2947 / (SCIP_Real)SCIPconflictGetNPseudoConflictConss(scip->conflict) : 0, 2948 SCIPconflictGetNPseudoReconvergenceConss(scip->conflict), 2949 SCIPconflictGetNPseudoReconvergenceConss(scip->conflict) > 0 2950 ? (SCIP_Real)SCIPconflictGetNPseudoReconvergenceLiterals(scip->conflict) 2951 / (SCIP_Real)SCIPconflictGetNPseudoReconvergenceConss(scip->conflict) : 0); 2952 SCIPmessageFPrintInfo(scip->messagehdlr, file, " applied globally : %10.2f - - %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10.1f - - %10" SCIP_LONGINT_FORMAT " - -\n", 2953 SCIPconflictGetGlobalApplTime(scip->conflict), 2954 SCIPconflictGetNGlobalChgBds(scip->conflict), 2955 SCIPconflictGetNAppliedGlobalConss(scip->conflict), 2956 SCIPconflictGetNAppliedGlobalConss(scip->conflict) > 0 2957 ? (SCIP_Real)SCIPconflictGetNAppliedGlobalLiterals(scip->conflict) 2958 / (SCIP_Real)SCIPconflictGetNAppliedGlobalConss(scip->conflict) : 0, 2959 SCIPconflictGetNDualproofsInfGlobal(scip->conflict) + SCIPconflictGetNDualproofsBndGlobal(scip->conflict)); 2960 SCIPmessageFPrintInfo(scip->messagehdlr, file, " applied locally : - - - %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10.1f - - %10" SCIP_LONGINT_FORMAT " - -\n", 2961 SCIPconflictGetNLocalChgBds(scip->conflict), 2962 SCIPconflictGetNAppliedLocalConss(scip->conflict), 2963 SCIPconflictGetNAppliedLocalConss(scip->conflict) > 0 2964 ? (SCIP_Real)SCIPconflictGetNAppliedLocalLiterals(scip->conflict) 2965 / (SCIP_Real)SCIPconflictGetNAppliedLocalConss(scip->conflict) : 0, 2966 SCIPconflictGetNDualproofsInfLocal(scip->conflict) + SCIPconflictGetNDualproofsBndLocal(scip->conflict)); 2967 } 2968 2969 /** outputs separator statistics 2970 * 2971 * Columns: 2972 * - RootCalls: The number of calls that happened at the root. 2973 * - FoundCuts: The total number of cuts generated by the separators. 2974 * Note: Cutpool-FoundCuts \f$= \sum_{i=1}^nsepas ( Foundcuts_i - DirectAdd_i )\f$. 2975 * - ViaPoolAdd: The total number of cuts added to the sepastore from the cutpool. 2976 * - DirectAdd: The total number of cuts added directly to the sepastore from the separator. 2977 * - Applied: The sum of all cuts from the separator that were applied to the LP. 2978 * - ViaPoolApp: The number of cuts that entered the sepastore from the cutpool that were applied to the LP. 2979 * - DirectApp: The number of cuts that entered the sepastore directly and were applied to the LP. 2980 * 2981 * The number of cuts ViaPoolAdd + Directly should be equal to the number of cuts Filtered + Forced + Selected in the 2982 * cutselector statistics. 2983 * 2984 * @note The following edge case may lead to over or undercounting of statistics: When SCIPapplyCutsProbing() is 2985 * called, cuts are counted for the cut selection statistics, but not for the separator statistics. This 2986 * happens, e.g., in the default plugin prop_obbt.c. 2987 * 2988 * @pre This method can be called if SCIP is in one of the following stages: 2989 * - \ref SCIP_STAGE_SOLVING 2990 * - \ref SCIP_STAGE_SOLVED 2991 */ 2992 void SCIPprintSeparatorStatistics( 2993 SCIP* scip, /**< SCIP data structure */ 2994 FILE* file /**< output file */ 2995 ) 2996 { 2997 int i; 2998 2999 assert(scip != NULL); 3000 assert(scip->set != NULL); 3001 3002 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPprintSeparatorStatistics", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 3003 3004 SCIPmessageFPrintInfo(scip->messagehdlr, file, "Separators : ExecTime SetupTime Calls RootCalls Cutoffs DomReds FoundCuts ViaPoolAdd DirectAdd Applied ViaPoolApp DirectApp Conss\n"); 3005 SCIPmessageFPrintInfo(scip->messagehdlr, file, " cut pool : %10.2f - %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " - - %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " - - - - - (maximal pool size: %10" SCIP_LONGINT_FORMAT")\n", 3006 SCIPcutpoolGetTime(scip->cutpool), 3007 SCIPcutpoolGetNCalls(scip->cutpool), 3008 SCIPcutpoolGetNRootCalls(scip->cutpool), 3009 SCIPcutpoolGetNCutsFound(scip->cutpool), 3010 SCIPcutpoolGetNCutsAdded(scip->cutpool), 3011 SCIPcutpoolGetMaxNCuts(scip->cutpool)); 3012 3013 /* sort separators w.r.t. their name */ 3014 SCIPsetSortSepasName(scip->set); 3015 3016 for( i = 0; i < scip->set->nsepas; ++i ) 3017 { 3018 SCIP_SEPA* sepa; 3019 3020 sepa = scip->set->sepas[i]; 3021 3022 /* only output data for separators without parent separator */ 3023 if( SCIPsepaGetParentsepa(sepa) == NULL ) 3024 { 3025 /* output data */ 3026 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %-17.17s: %10.2f %10.2f %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT "\n", 3027 SCIPsepaGetName(sepa), 3028 SCIPsepaGetTime(sepa), 3029 SCIPsepaGetSetupTime(sepa), 3030 SCIPsepaGetNCalls(sepa), 3031 SCIPsepaGetNRootCalls(sepa), 3032 SCIPsepaGetNCutoffs(sepa), 3033 SCIPsepaGetNDomredsFound(sepa), 3034 SCIPsepaGetNCutsFound(sepa), 3035 SCIPsepaGetNCutsAddedViaPool(sepa), 3036 SCIPsepaGetNCutsAddedDirect(sepa), 3037 SCIPsepaGetNCutsApplied(sepa), 3038 SCIPsepaGetNCutsAppliedViaPool(sepa), 3039 SCIPsepaGetNCutsAppliedDirect(sepa), 3040 SCIPsepaGetNConssFound(sepa)); 3041 3042 /* for parent separators search for dependent separators */ 3043 if( SCIPsepaIsParentsepa(sepa) ) 3044 { 3045 SCIP_SEPA* parentsepa; 3046 int k; 3047 3048 for( k = 0; k < scip->set->nsepas; ++k ) 3049 { 3050 if( k == i ) 3051 continue; 3052 3053 parentsepa = SCIPsepaGetParentsepa(scip->set->sepas[k]); 3054 if( parentsepa != sepa ) 3055 continue; 3056 3057 SCIPmessageFPrintInfo(scip->messagehdlr, file, " > %-15.17s: %10s %10s %10s %10s %10s %10s %10s %10" SCIP_LONGINT_FORMAT" %10" SCIP_LONGINT_FORMAT" %10" SCIP_LONGINT_FORMAT" %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10s\n", 3058 SCIPsepaGetName(scip->set->sepas[k]), "-", "-", "-", "-", "-", "-", "-", 3059 SCIPsepaGetNCutsAddedViaPool(scip->set->sepas[k]), 3060 SCIPsepaGetNCutsAddedDirect(scip->set->sepas[k]), 3061 SCIPsepaGetNCutsApplied(scip->set->sepas[k]), 3062 SCIPsepaGetNCutsAppliedViaPool(scip->set->sepas[k]), 3063 SCIPsepaGetNCutsAppliedDirect(scip->set->sepas[k]), "-"); 3064 } 3065 } 3066 } 3067 } 3068 } 3069 3070 /** outputs cutselector statistics 3071 * 3072 * Filtered = ViaPoolAdd(Separators) + DirectAdd(Separators) - Selected - Cuts(Constraints) 3073 * Selected = Applied(Separators) + Applied(Constraints) 3074 * 3075 * @pre This method can be called if SCIP is in one of the following stages: 3076 * - \ref SCIP_STAGE_SOLVING 3077 * - \ref SCIP_STAGE_SOLVED 3078 */ 3079 void SCIPprintCutselectorStatistics( 3080 SCIP* scip, /**< SCIP data structure */ 3081 FILE* file /**< output file */ 3082 ) 3083 { 3084 int i; 3085 3086 assert(scip != NULL); 3087 assert(scip->set != NULL); 3088 3089 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPprintCutselectorStatistics", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 3090 3091 SCIPmessageFPrintInfo(scip->messagehdlr, file, "Cutselectors : ExecTime SetupTime Calls RootCalls Selected Forced Filtered RootSelec RootForc RootFilt \n"); 3092 3093 /* sort cutsels w.r.t. their priority */ 3094 SCIPsetSortCutsels(scip->set); 3095 3096 for( i = 0; i < scip->set->ncutsels; ++i ) 3097 { 3098 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %-17.17s: %10.2f %10.2f %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT "\n", 3099 SCIPcutselGetName(scip->set->cutsels[i]), 3100 SCIPcutselGetTime(scip->set->cutsels[i]), 3101 SCIPcutselGetSetupTime(scip->set->cutsels[i]), 3102 SCIPcutselGetNCalls(scip->set->cutsels[i]), 3103 SCIPcutselGetNRootCalls(scip->set->cutsels[i]), 3104 SCIPcutselGetNRootCuts(scip->set->cutsels[i]) + SCIPcutselGetNLocalCuts(scip->set->cutsels[i]), 3105 SCIPcutselGetNRootForcedCuts(scip->set->cutsels[i]) + SCIPcutselGetNLocalForcedCuts(scip->set->cutsels[i]), 3106 SCIPcutselGetNRootCutsFiltered(scip->set->cutsels[i]) + SCIPcutselGetNLocalCutsFiltered(scip->set->cutsels[i]), 3107 SCIPcutselGetNRootCuts(scip->set->cutsels[i]), 3108 SCIPcutselGetNRootForcedCuts(scip->set->cutsels[i]), 3109 SCIPcutselGetNRootCutsFiltered(scip->set->cutsels[i]) 3110 ); 3111 } 3112 } 3113 3114 /** outputs pricer statistics 3115 * 3116 * @pre This method can be called if SCIP is in one of the following stages: 3117 * - \ref SCIP_STAGE_SOLVING 3118 * - \ref SCIP_STAGE_SOLVED 3119 */ 3120 void SCIPprintPricerStatistics( 3121 SCIP* scip, /**< SCIP data structure */ 3122 FILE* file /**< output file */ 3123 ) 3124 { 3125 int i; 3126 3127 assert(scip != NULL); 3128 assert(scip->set != NULL); 3129 3130 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPprintPricerStatistics", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 3131 3132 SCIPmessageFPrintInfo(scip->messagehdlr, file, "Pricers : ExecTime SetupTime Calls Vars\n"); 3133 SCIPmessageFPrintInfo(scip->messagehdlr, file, " problem variables: %10.2f - %10d %10d\n", 3134 SCIPpricestoreGetProbPricingTime(scip->pricestore), 3135 SCIPpricestoreGetNProbPricings(scip->pricestore), 3136 SCIPpricestoreGetNProbvarsFound(scip->pricestore)); 3137 3138 /* sort pricers w.r.t. their name */ 3139 SCIPsetSortPricersName(scip->set); 3140 3141 for( i = 0; i < scip->set->nactivepricers; ++i ) 3142 { 3143 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %-17.17s: %10.2f %10.2f %10d %10d\n", 3144 SCIPpricerGetName(scip->set->pricers[i]), 3145 SCIPpricerGetTime(scip->set->pricers[i]), 3146 SCIPpricerGetSetupTime(scip->set->pricers[i]), 3147 SCIPpricerGetNCalls(scip->set->pricers[i]), 3148 SCIPpricerGetNVarsFound(scip->set->pricers[i])); 3149 } 3150 } 3151 3152 /** outputs branching rule statistics 3153 * 3154 * @pre This method can be called if SCIP is in one of the following stages: 3155 * - \ref SCIP_STAGE_SOLVING 3156 * - \ref SCIP_STAGE_SOLVED 3157 */ 3158 void SCIPprintBranchruleStatistics( 3159 SCIP* scip, /**< SCIP data structure */ 3160 FILE* file /**< output file */ 3161 ) 3162 { 3163 int i; 3164 3165 assert(scip != NULL); 3166 assert(scip->set != NULL); 3167 3168 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPprintBranchruleStatistics", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 3169 3170 SCIPmessageFPrintInfo(scip->messagehdlr, file, "Branching Rules : ExecTime SetupTime BranchLP BranchExt BranchPS Cutoffs DomReds Cuts Conss Children\n"); 3171 3172 /* sort branching rules w.r.t. their name */ 3173 SCIPsetSortBranchrulesName(scip->set); 3174 3175 for( i = 0; i < scip->set->nbranchrules; ++i ) 3176 { 3177 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %-17.17s: %10.2f %10.2f %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT "\n", 3178 SCIPbranchruleGetName(scip->set->branchrules[i]), 3179 SCIPbranchruleGetTime(scip->set->branchrules[i]), 3180 SCIPbranchruleGetSetupTime(scip->set->branchrules[i]), 3181 SCIPbranchruleGetNLPCalls(scip->set->branchrules[i]), 3182 SCIPbranchruleGetNExternCalls(scip->set->branchrules[i]), 3183 SCIPbranchruleGetNPseudoCalls(scip->set->branchrules[i]), 3184 SCIPbranchruleGetNCutoffs(scip->set->branchrules[i]), 3185 SCIPbranchruleGetNDomredsFound(scip->set->branchrules[i]), 3186 SCIPbranchruleGetNCutsFound(scip->set->branchrules[i]), 3187 SCIPbranchruleGetNConssFound(scip->set->branchrules[i]), 3188 SCIPbranchruleGetNChildren(scip->set->branchrules[i])); 3189 } 3190 } 3191 3192 /** outputs heuristics statistics 3193 * 3194 * @pre This method can be called if SCIP is in one of the following stages: 3195 * - \ref SCIP_STAGE_PRESOLVING 3196 * - \ref SCIP_STAGE_EXITPRESOLVE 3197 * - \ref SCIP_STAGE_PRESOLVED 3198 * - \ref SCIP_STAGE_SOLVING 3199 * - \ref SCIP_STAGE_SOLVED 3200 */ 3201 void SCIPprintHeuristicStatistics( 3202 SCIP* scip, /**< SCIP data structure */ 3203 FILE* file /**< output file */ 3204 ) 3205 { 3206 int ndivesets = 0; 3207 int i; 3208 3209 assert(scip != NULL); 3210 assert(scip->set != NULL); 3211 assert(scip->tree != NULL); 3212 3213 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPprintHeuristicStatistics", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 3214 3215 SCIPmessageFPrintInfo(scip->messagehdlr, file, "Primal Heuristics : ExecTime SetupTime Calls Found Best\n"); 3216 SCIPmessageFPrintInfo(scip->messagehdlr, file, " LP solutions : %10.2f - - %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT "\n", 3217 SCIPclockGetTime(scip->stat->lpsoltime), 3218 scip->stat->nlpsolsfound, scip->stat->nlpbestsolsfound); 3219 SCIPmessageFPrintInfo(scip->messagehdlr, file, " relax solutions : %10.2f - - %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT "\n", 3220 SCIPclockGetTime(scip->stat->relaxsoltime), 3221 scip->stat->nrelaxsolsfound, scip->stat->nrelaxbestsolsfound); 3222 SCIPmessageFPrintInfo(scip->messagehdlr, file, " pseudo solutions : %10.2f - - %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT "\n", 3223 SCIPclockGetTime(scip->stat->pseudosoltime), 3224 scip->stat->npssolsfound, scip->stat->npsbestsolsfound); 3225 SCIPmessageFPrintInfo(scip->messagehdlr, file, " strong branching : %10.2f - - %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT "\n", 3226 SCIPclockGetTime(scip->stat->sbsoltime), 3227 scip->stat->nsbsolsfound, scip->stat->nsbbestsolsfound); 3228 3229 /* sort heuristics w.r.t. their names */ 3230 SCIPsetSortHeursName(scip->set); 3231 3232 for( i = 0; i < scip->set->nheurs; ++i ) 3233 { 3234 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %-17.17s: %10.2f %10.2f %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT "\n", 3235 SCIPheurGetName(scip->set->heurs[i]), 3236 SCIPheurGetTime(scip->set->heurs[i]), 3237 SCIPheurGetSetupTime(scip->set->heurs[i]), 3238 SCIPheurGetNCalls(scip->set->heurs[i]), 3239 SCIPheurGetNSolsFound(scip->set->heurs[i]), 3240 SCIPheurGetNBestSolsFound(scip->set->heurs[i])); 3241 3242 /* count heuristics that use diving; needed to determine output later */ 3243 ndivesets += SCIPheurGetNDivesets(scip->set->heurs[i]); 3244 } 3245 3246 SCIPmessageFPrintInfo(scip->messagehdlr, file, " other solutions : - - - %10" SCIP_LONGINT_FORMAT " -\n", 3247 scip->stat->nexternalsolsfound); 3248 3249 if ( ndivesets > 0 && scip->set->misc_showdivingstats ) 3250 { 3251 int c; 3252 SCIP_DIVECONTEXT divecontexts[] = {SCIP_DIVECONTEXT_SINGLE, SCIP_DIVECONTEXT_ADAPTIVE, SCIP_DIVECONTEXT_SCHEDULER}; 3253 3254 /* print statistics for all three contexts individually */ 3255 for( c = 0; c < 3; ++c ) 3256 { 3257 SCIP_DIVECONTEXT divecontext = divecontexts[c]; 3258 3259 if( divecontext == SCIP_DIVECONTEXT_SINGLE ) 3260 { 3261 SCIPmessageFPrintInfo(scip->messagehdlr, file, 3262 "Diving %-12s: Calls Nodes LP Iters Backtracks Conflicts MinDepth MaxDepth AvgDepth RoundSols NLeafSols MinSolDpt MaxSolDpt AvgSolDpt\n", "(single)"); 3263 } 3264 else 3265 { 3266 SCIPmessageFPrintInfo(scip->messagehdlr, file, 3267 "Diving %-12s: Calls Nodes LP Iters Backtracks Conflicts MinDepth MaxDepth AvgDepth RoundSols NLeafSols MinSolDpt MaxSolDpt AvgSolDpt\n", 3268 divecontext == SCIP_DIVECONTEXT_ADAPTIVE ? "(adaptive)" : "(scheduler)"); 3269 } 3270 3271 for( i = 0; i < scip->set->nheurs; ++i ) 3272 { 3273 int s; 3274 for( s = 0; s < SCIPheurGetNDivesets(scip->set->heurs[i]); ++s ) 3275 { 3276 SCIP_DIVESET* diveset = SCIPheurGetDivesets(scip->set->heurs[i])[s]; 3277 3278 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %-17.17s: %10d", 3279 SCIPdivesetGetName(diveset), 3280 SCIPdivesetGetNCalls(diveset, divecontext)); 3281 if( SCIPdivesetGetNCalls(diveset, divecontext) > 0 ) 3282 { 3283 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10d %10d %10.1f %10" SCIP_LONGINT_FORMAT, 3284 SCIPdivesetGetNProbingNodes(diveset, divecontext), 3285 SCIPdivesetGetNLPIterations(diveset, divecontext), 3286 SCIPdivesetGetNBacktracks(diveset, divecontext), 3287 SCIPdivesetGetNConflicts(diveset, divecontext), 3288 SCIPdivesetGetMinDepth(diveset, divecontext), 3289 SCIPdivesetGetMaxDepth(diveset, divecontext), 3290 SCIPdivesetGetAvgDepth(diveset, divecontext), 3291 SCIPdivesetGetNSols(diveset, divecontext) - SCIPdivesetGetNSolutionCalls(diveset, divecontext)); 3292 3293 if( SCIPdivesetGetNSolutionCalls(diveset, divecontext) > 0 ) 3294 { 3295 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %10d %10d %10d %10.1f\n", 3296 SCIPdivesetGetNSolutionCalls(diveset, divecontext), 3297 SCIPdivesetGetMinSolutionDepth(diveset, divecontext), 3298 SCIPdivesetGetMaxSolutionDepth(diveset, divecontext), 3299 SCIPdivesetGetAvgSolutionDepth(diveset, divecontext)); 3300 } 3301 else 3302 SCIPmessageFPrintInfo(scip->messagehdlr, file, " - - - -\n"); 3303 } 3304 else 3305 SCIPmessageFPrintInfo(scip->messagehdlr, file, " - - - - - - - - - - - -\n"); 3306 } 3307 } 3308 } 3309 } 3310 } 3311 3312 /** outputs compression statistics 3313 * 3314 * @pre This method can be called if SCIP is in one of the following stages: 3315 * - \ref SCIP_STAGE_PRESOLVING 3316 * - \ref SCIP_STAGE_EXITPRESOLVE 3317 * - \ref SCIP_STAGE_PRESOLVED 3318 * - \ref SCIP_STAGE_SOLVING 3319 * - \ref SCIP_STAGE_SOLVED 3320 */ 3321 void SCIPprintCompressionStatistics( 3322 SCIP* scip, /**< SCIP data structure */ 3323 FILE* file /**< output file */ 3324 ) 3325 { 3326 int i; 3327 3328 assert(scip != NULL); 3329 3330 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPprintCompressionStatistics", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 3331 3332 /* only print compression statistics if tree reoptimization is enabled */ 3333 if( !scip->set->reopt_enable ) 3334 return; 3335 3336 SCIPmessageFPrintInfo(scip->messagehdlr, file, "Tree Compressions : ExecTime SetupTime Calls Found\n"); 3337 3338 /* sort compressions w.r.t. their names */ 3339 SCIPsetSortComprsName(scip->set); 3340 3341 for( i = 0; i < scip->set->ncomprs; ++i ) 3342 { 3343 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %-17.17s: %10.2f %10.2f %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT "\n", 3344 SCIPcomprGetName(scip->set->comprs[i]), 3345 SCIPcomprGetTime(scip->set->comprs[i]), 3346 SCIPcomprGetSetupTime(scip->set->comprs[i]), 3347 SCIPcomprGetNCalls(scip->set->comprs[i]), 3348 SCIPcomprGetNFound(scip->set->comprs[i])); 3349 } 3350 } 3351 3352 /** outputs LP statistics 3353 * 3354 * @pre This method can be called if SCIP is in one of the following stages: 3355 * - \ref SCIP_STAGE_SOLVING 3356 * - \ref SCIP_STAGE_SOLVED 3357 */ 3358 void SCIPprintLPStatistics( 3359 SCIP* scip, /**< SCIP data structure */ 3360 FILE* file /**< output file */ 3361 ) 3362 { 3363 assert(scip != NULL); 3364 assert(scip->stat != NULL); 3365 assert(scip->lp != NULL); 3366 3367 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPprintLPStatistics", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 3368 3369 SCIPmessageFPrintInfo(scip->messagehdlr, file, "LP : Time Calls Iterations Iter/call Iter/sec Time-0-It Calls-0-It ItLimit\n"); 3370 3371 SCIPmessageFPrintInfo(scip->messagehdlr, file, " primal LP : %10.2f %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10.2f", 3372 SCIPclockGetTime(scip->stat->primallptime), 3373 scip->stat->nprimallps + scip->stat->nprimalzeroitlps, 3374 scip->stat->nprimallpiterations, 3375 scip->stat->nprimallps > 0 ? (SCIP_Real)scip->stat->nprimallpiterations/(SCIP_Real)scip->stat->nprimallps : 0.0); 3376 if( SCIPclockGetTime(scip->stat->primallptime) >= 0.01 ) 3377 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %10.2f", (SCIP_Real)scip->stat->nprimallpiterations/SCIPclockGetTime(scip->stat->primallptime)); 3378 else 3379 SCIPmessageFPrintInfo(scip->messagehdlr, file, " -"); 3380 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %10.2f %10" SCIP_LONGINT_FORMAT "\n", 3381 scip->stat->primalzeroittime, 3382 scip->stat->nprimalzeroitlps); 3383 3384 SCIPmessageFPrintInfo(scip->messagehdlr, file, " dual LP : %10.2f %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10.2f", 3385 SCIPclockGetTime(scip->stat->duallptime), 3386 scip->stat->nduallps + scip->stat->ndualzeroitlps, 3387 scip->stat->nduallpiterations, 3388 scip->stat->nduallps > 0 ? (SCIP_Real)scip->stat->nduallpiterations/(SCIP_Real)scip->stat->nduallps : 0.0); 3389 if( SCIPclockGetTime(scip->stat->duallptime) >= 0.01 ) 3390 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %10.2f", (SCIP_Real)scip->stat->nduallpiterations/SCIPclockGetTime(scip->stat->duallptime)); 3391 else 3392 SCIPmessageFPrintInfo(scip->messagehdlr, file, " -"); 3393 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %10.2f %10" SCIP_LONGINT_FORMAT "\n", 3394 scip->stat->dualzeroittime, 3395 scip->stat->ndualzeroitlps); 3396 3397 SCIPmessageFPrintInfo(scip->messagehdlr, file, " lex dual LP : %10.2f %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10.2f", 3398 SCIPclockGetTime(scip->stat->lexduallptime), 3399 scip->stat->nlexduallps, 3400 scip->stat->nlexduallpiterations, 3401 scip->stat->nlexduallps > 0 ? (SCIP_Real)scip->stat->nlexduallpiterations/(SCIP_Real)scip->stat->nlexduallps : 0.0); 3402 if( SCIPclockGetTime(scip->stat->lexduallptime) >= 0.01 ) 3403 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %10.2f\n", (SCIP_Real)scip->stat->nlexduallpiterations/SCIPclockGetTime(scip->stat->lexduallptime)); 3404 else 3405 SCIPmessageFPrintInfo(scip->messagehdlr, file, " -\n"); 3406 3407 SCIPmessageFPrintInfo(scip->messagehdlr, file, " barrier LP : %10.2f %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10.2f", 3408 SCIPclockGetTime(scip->stat->barrierlptime), 3409 scip->stat->nbarrierlps, 3410 scip->stat->nbarrierlpiterations, 3411 scip->stat->nbarrierlps > 0 ? (SCIP_Real)scip->stat->nbarrierlpiterations/(SCIP_Real)scip->stat->nbarrierlps : 0.0); 3412 if( SCIPclockGetTime(scip->stat->barrierlptime) >= 0.01 ) 3413 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %10.2f", (SCIP_Real)scip->stat->nbarrierlpiterations/SCIPclockGetTime(scip->stat->barrierlptime)); 3414 else 3415 SCIPmessageFPrintInfo(scip->messagehdlr, file, " -"); 3416 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %10.2f %10" SCIP_LONGINT_FORMAT "\n", 3417 scip->stat->barrierzeroittime, 3418 scip->stat->nbarrierzeroitlps); 3419 3420 SCIPmessageFPrintInfo(scip->messagehdlr, file, " resolve instable : %10.2f %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10.2f", 3421 SCIPclockGetTime(scip->stat->resolveinstablelptime), 3422 scip->stat->nresolveinstablelps, 3423 scip->stat->nresolveinstablelpiters, 3424 scip->stat->nresolveinstablelps > 0 ? (SCIP_Real)scip->stat->nresolveinstablelpiters/(SCIP_Real)scip->stat->nresolveinstablelps : 0.0); 3425 if( SCIPclockGetTime(scip->stat->resolveinstablelptime) >= 0.01 ) 3426 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %10.2f\n", (SCIP_Real)scip->stat->nresolveinstablelpiters/SCIPclockGetTime(scip->stat->resolveinstablelptime)); 3427 else 3428 SCIPmessageFPrintInfo(scip->messagehdlr, file, " -\n"); 3429 3430 SCIPmessageFPrintInfo(scip->messagehdlr, file, " diving/probing LP: %10.2f %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10.2f", 3431 SCIPclockGetTime(scip->stat->divinglptime), 3432 scip->stat->ndivinglps, 3433 scip->stat->ndivinglpiterations, 3434 scip->stat->ndivinglps > 0 ? (SCIP_Real)scip->stat->ndivinglpiterations/(SCIP_Real)scip->stat->ndivinglps : 0.0); 3435 if( SCIPclockGetTime(scip->stat->divinglptime) >= 0.01 ) 3436 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %10.2f\n", (SCIP_Real)scip->stat->ndivinglpiterations/SCIPclockGetTime(scip->stat->divinglptime)); 3437 else 3438 SCIPmessageFPrintInfo(scip->messagehdlr, file, " -\n"); 3439 3440 SCIPmessageFPrintInfo(scip->messagehdlr, file, " strong branching : %10.2f %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10.2f", 3441 SCIPclockGetTime(scip->stat->strongbranchtime), 3442 scip->stat->nstrongbranchs, 3443 scip->stat->nsblpiterations, 3444 scip->stat->nstrongbranchs > 0 ? (SCIP_Real)scip->stat->nsblpiterations/(SCIP_Real)scip->stat->nstrongbranchs : 0.0); 3445 if( SCIPclockGetTime(scip->stat->strongbranchtime) >= 0.01 ) 3446 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %10.2f", (SCIP_Real)scip->stat->nsblpiterations/SCIPclockGetTime(scip->stat->strongbranchtime)); 3447 else 3448 SCIPmessageFPrintInfo(scip->messagehdlr, file, " -"); 3449 SCIPmessageFPrintInfo(scip->messagehdlr, file, " - - %10" SCIP_LONGINT_FORMAT "\n", scip->stat->nsbtimesiterlimhit); 3450 3451 SCIPmessageFPrintInfo(scip->messagehdlr, file, " (at root node) : - %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10.2f -\n", 3452 scip->stat->nrootstrongbranchs, 3453 scip->stat->nrootsblpiterations, 3454 scip->stat->nrootstrongbranchs > 0 3455 ? (SCIP_Real)scip->stat->nrootsblpiterations/(SCIP_Real)scip->stat->nrootstrongbranchs : 0.0); 3456 3457 SCIPmessageFPrintInfo(scip->messagehdlr, file, " conflict analysis: %10.2f %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10.2f", 3458 SCIPclockGetTime(scip->stat->conflictlptime), 3459 scip->stat->nconflictlps, 3460 scip->stat->nconflictlpiterations, 3461 scip->stat->nconflictlps > 0 ? (SCIP_Real)scip->stat->nconflictlpiterations/(SCIP_Real)scip->stat->nconflictlps : 0.0); 3462 if( SCIPclockGetTime(scip->stat->conflictlptime) >= 0.01 ) 3463 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %10.2f\n", (SCIP_Real)scip->stat->nconflictlpiterations/SCIPclockGetTime(scip->stat->conflictlptime)); 3464 else 3465 SCIPmessageFPrintInfo(scip->messagehdlr, file, " -\n"); 3466 } 3467 3468 /** outputs NLP statistics 3469 * 3470 * @pre This method can be called if SCIP is in one of the following stages: 3471 * - \ref SCIP_STAGE_SOLVING 3472 * - \ref SCIP_STAGE_SOLVED 3473 */ 3474 void SCIPprintNLPStatistics( 3475 SCIP* scip, /**< SCIP data structure */ 3476 FILE* file /**< output file */ 3477 ) 3478 { 3479 int nnlrowlinear; 3480 int nnlrowconvexineq; 3481 int nnlrownonconvexineq; 3482 int nnlrownonlineareq; 3483 3484 assert(scip != NULL); 3485 assert(scip->stat != NULL); 3486 3487 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPprintNLPStatistics", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 3488 3489 if( scip->nlp == NULL ) 3490 return; 3491 3492 SCIPmessageFPrintInfo(scip->messagehdlr, file, "NLP relaxation :\n"); 3493 3494 SCIPmessageFPrintInfo(scip->messagehdlr, file, " solve time : %10.2f (%" SCIP_LONGINT_FORMAT " calls)\n", 3495 SCIPclockGetTime(scip->stat->nlpsoltime), 3496 scip->stat->nnlps); 3497 3498 SCIP_CALL_ABORT( SCIPgetNLPNlRowsStat(scip, &nnlrowlinear, &nnlrowconvexineq, &nnlrownonconvexineq, &nnlrownonlineareq) ); 3499 SCIPmessageFPrintInfo(scip->messagehdlr, file, " convexity : %10s (%d linear rows, %d convex ineq., %d nonconvex ineq., %d nonlinear eq. or two-sided ineq.)\n", 3500 (nnlrownonconvexineq == 0 && nnlrownonlineareq == 0) ? "convex" : "nonconvex", 3501 nnlrowlinear, nnlrowconvexineq, nnlrownonconvexineq, nnlrownonlineareq); 3502 } 3503 3504 /** outputs relaxator statistics 3505 * 3506 * @pre This method can be called if SCIP is in one of the following stages: 3507 * - \ref SCIP_STAGE_SOLVING 3508 * - \ref SCIP_STAGE_SOLVED 3509 */ 3510 void SCIPprintRelaxatorStatistics( 3511 SCIP* scip, /**< SCIP data structure */ 3512 FILE* file /**< output file */ 3513 ) 3514 { 3515 int i; 3516 3517 assert(scip != NULL); 3518 assert(scip->set != NULL); 3519 3520 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPprintRelaxatorStatistics", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 3521 3522 if( scip->set->nrelaxs == 0 ) 3523 return; 3524 3525 SCIPmessageFPrintInfo(scip->messagehdlr, file, "Relaxators : Time Calls Cutoffs ImprBounds ImprTime ReducedDom Separated AddedConss\n"); 3526 3527 /* sort relaxators w.r.t. their name */ 3528 SCIPsetSortRelaxsName(scip->set); 3529 3530 for( i = 0; i < scip->set->nrelaxs; ++i ) 3531 { 3532 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %-17.17s: %10.2f %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10.2f %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT "\n", 3533 SCIPrelaxGetName(scip->set->relaxs[i]), 3534 SCIPrelaxGetTime(scip->set->relaxs[i]), 3535 SCIPrelaxGetNCalls(scip->set->relaxs[i]), 3536 SCIPrelaxGetNCutoffs(scip->set->relaxs[i]), 3537 SCIPrelaxGetNImprovedLowerbound(scip->set->relaxs[i]), 3538 SCIPrelaxGetImprovedLowerboundTime(scip->set->relaxs[i]), 3539 SCIPrelaxGetNReducedDomains(scip->set->relaxs[i]), 3540 SCIPrelaxGetNSeparatedCuts(scip->set->relaxs[i]), 3541 SCIPrelaxGetNAddedConss(scip->set->relaxs[i]) 3542 ); 3543 } 3544 } 3545 3546 /** outputs tree statistics 3547 * 3548 * @pre This method can be called if SCIP is in one of the following stages: 3549 * - \ref SCIP_STAGE_SOLVING 3550 * - \ref SCIP_STAGE_SOLVED 3551 */ 3552 void SCIPprintTreeStatistics( 3553 SCIP* scip, /**< SCIP data structure */ 3554 FILE* file /**< output file */ 3555 ) 3556 { 3557 assert(scip != NULL); 3558 assert(scip->stat != NULL); 3559 assert(scip->tree != NULL); 3560 3561 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPprintTreeStatistics", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 3562 3563 SCIPmessageFPrintInfo(scip->messagehdlr, file, "B&B Tree :\n"); 3564 SCIPmessageFPrintInfo(scip->messagehdlr, file, " number of runs : %10d\n", scip->stat->nruns); 3565 SCIPmessageFPrintInfo(scip->messagehdlr, file, 3566 " nodes : %10" SCIP_LONGINT_FORMAT " (%" SCIP_LONGINT_FORMAT " internal, %" SCIP_LONGINT_FORMAT " leaves)\n", 3567 scip->stat->nnodes, scip->stat->ninternalnodes, scip->stat->nnodes - scip->stat->ninternalnodes ); 3568 SCIPmessageFPrintInfo(scip->messagehdlr, file, " feasible leaves : %10" SCIP_LONGINT_FORMAT "\n", scip->stat->nfeasleaves); 3569 SCIPmessageFPrintInfo(scip->messagehdlr, file, " infeas. leaves : %10" SCIP_LONGINT_FORMAT "\n", scip->stat->ninfeasleaves); 3570 SCIPmessageFPrintInfo(scip->messagehdlr, file, " objective leaves : %10" SCIP_LONGINT_FORMAT "\n", scip->stat->nobjleaves); 3571 SCIPmessageFPrintInfo(scip->messagehdlr, file, 3572 " nodes (total) : %10" SCIP_LONGINT_FORMAT " (%" SCIP_LONGINT_FORMAT " internal, %" SCIP_LONGINT_FORMAT " leaves)\n", 3573 scip->stat->ntotalnodes, scip->stat->ntotalinternalnodes, scip->stat->ntotalnodes - scip->stat->ntotalinternalnodes); 3574 SCIPmessageFPrintInfo(scip->messagehdlr, file, " nodes left : %10d\n", SCIPtreeGetNNodes(scip->tree)); 3575 SCIPmessageFPrintInfo(scip->messagehdlr, file, " max depth : %10d\n", scip->stat->maxdepth); 3576 SCIPmessageFPrintInfo(scip->messagehdlr, file, " max depth (total): %10d\n", scip->stat->maxtotaldepth); 3577 SCIPmessageFPrintInfo(scip->messagehdlr, file, " backtracks : %10" SCIP_LONGINT_FORMAT " (%.1f%%)\n", scip->stat->nbacktracks, 3578 scip->stat->nnodes > 0 ? 100.0 * (SCIP_Real)scip->stat->nbacktracks / (SCIP_Real)scip->stat->nnodes : 0.0); 3579 SCIPmessageFPrintInfo(scip->messagehdlr, file, " early backtracks : %10" SCIP_LONGINT_FORMAT " (%.1f%%)\n", scip->stat->nearlybacktracks, 3580 scip->stat->nbacktracks > 0 ? 100.0 * (SCIP_Real)scip->stat->nearlybacktracks / (SCIP_Real)scip->stat->nbacktracks : 0.0); 3581 SCIPmessageFPrintInfo(scip->messagehdlr, file, " nodes exc. ref. : %10" SCIP_LONGINT_FORMAT " (%.1f%%)\n", scip->stat->nnodesaboverefbound, 3582 scip->stat->nnodes > 0 ? 100.0 * (SCIP_Real)scip->stat->nnodesaboverefbound / (SCIP_Real)scip->stat->nnodes : 0.0); 3583 3584 SCIPmessageFPrintInfo(scip->messagehdlr, file, " delayed cutoffs : %10" SCIP_LONGINT_FORMAT "\n", scip->stat->ndelayedcutoffs); 3585 SCIPmessageFPrintInfo(scip->messagehdlr, file, " repropagations : %10" SCIP_LONGINT_FORMAT " (%" SCIP_LONGINT_FORMAT " domain reductions, %" SCIP_LONGINT_FORMAT " cutoffs)\n", 3586 scip->stat->nreprops, scip->stat->nrepropboundchgs, scip->stat->nrepropcutoffs); 3587 SCIPmessageFPrintInfo(scip->messagehdlr, file, " avg switch length: %10.2f\n", 3588 scip->stat->nnodes > 0 3589 ? (SCIP_Real)(scip->stat->nactivatednodes + scip->stat->ndeactivatednodes) / (SCIP_Real)scip->stat->nnodes : 0.0); 3590 SCIPmessageFPrintInfo(scip->messagehdlr, file, " switching time : %10.2f\n", SCIPclockGetTime(scip->stat->nodeactivationtime)); 3591 } 3592 3593 /** outputs solution statistics 3594 * 3595 * @pre This method can be called if SCIP is in one of the following stages: 3596 * - \ref SCIP_STAGE_PRESOLVING 3597 * - \ref SCIP_STAGE_EXITPRESOLVE 3598 * - \ref SCIP_STAGE_PRESOLVED 3599 * - \ref SCIP_STAGE_SOLVING 3600 * - \ref SCIP_STAGE_SOLVED 3601 */ 3602 void SCIPprintSolutionStatistics( 3603 SCIP* scip, /**< SCIP data structure */ 3604 FILE* file /**< output file */ 3605 ) 3606 { 3607 SCIP_Real primalbound; 3608 SCIP_Real dualbound; 3609 SCIP_Real gap; 3610 SCIP_Real firstprimalbound; 3611 SCIP_Bool objlimitreached; 3612 char limsolstring[SCIP_MAXSTRLEN]; 3613 3614 assert(scip != NULL); 3615 assert(scip->stat != NULL); 3616 assert(scip->primal != NULL); 3617 3618 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPprintSolutionStatistics", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 3619 3620 primalbound = SCIPgetPrimalbound(scip); 3621 dualbound = SCIPgetDualbound(scip); 3622 gap = SCIPgetGap(scip); 3623 3624 /* We output that the objective limit has been reached if the problem has been solved, no solution respecting the 3625 * objective limit has been found (nlimsolsfound == 0) and the primal bound is finite. Note that it still might be 3626 * that the original problem is infeasible, even without the objective limit, i.e., we cannot be sure that we 3627 * actually reached the objective limit. */ 3628 objlimitreached = FALSE; 3629 if( SCIPgetStage(scip) == SCIP_STAGE_SOLVED && scip->primal->nlimsolsfound == 0 3630 && !SCIPisInfinity(scip, primalbound) && SCIPgetStatus(scip) != SCIP_STATUS_INFORUNBD ) 3631 objlimitreached = TRUE; 3632 3633 if( scip->primal->nsolsfound != scip->primal->nlimsolsfound ) 3634 (void) SCIPsnprintf(limsolstring, SCIP_MAXSTRLEN, ", %" SCIP_LONGINT_FORMAT " respecting the objective limit", scip->primal->nlimsolsfound); 3635 else 3636 limsolstring[0] = '\0'; 3637 3638 SCIPmessageFPrintInfo(scip->messagehdlr, file, "Solution :\n"); 3639 SCIPmessageFPrintInfo(scip->messagehdlr, file, " Solutions found : %10" SCIP_LONGINT_FORMAT " (%" SCIP_LONGINT_FORMAT " improvements%s)\n", 3640 scip->primal->nsolsfound, scip->primal->nbestsolsfound, limsolstring); 3641 3642 if( SCIPsetIsInfinity(scip->set, REALABS(primalbound)) ) 3643 { 3644 if( scip->set->stage == SCIP_STAGE_SOLVED ) 3645 { 3646 if( scip->primal->nlimsolsfound == 0 ) 3647 { 3648 if( SCIPgetStatus(scip) == SCIP_STATUS_INFORUNBD ) 3649 { 3650 assert(!objlimitreached); 3651 SCIPmessageFPrintInfo(scip->messagehdlr, file, " Primal Bound : infeasible or unbounded\n"); 3652 } 3653 else 3654 { 3655 assert(SCIPgetStatus(scip) == SCIP_STATUS_INFEASIBLE); 3656 if( objlimitreached ) 3657 SCIPmessageFPrintInfo(scip->messagehdlr, file, " Primal Bound : infeasible (objective limit reached)\n"); 3658 else 3659 SCIPmessageFPrintInfo(scip->messagehdlr, file, " Primal Bound : infeasible\n"); 3660 } 3661 } 3662 else 3663 { 3664 assert(!objlimitreached); 3665 assert(SCIPgetStatus(scip) == SCIP_STATUS_UNBOUNDED); 3666 SCIPmessageFPrintInfo(scip->messagehdlr, file, " Primal Bound : unbounded\n"); 3667 } 3668 } 3669 else 3670 SCIPmessageFPrintInfo(scip->messagehdlr, file, " Primal Bound : -\n"); 3671 } 3672 else 3673 { 3674 if( scip->primal->nlimsolsfound == 0 ) 3675 { 3676 SCIPmessageFPrintInfo(scip->messagehdlr, file, " Primal Bound : %+21.14e (objective limit)\n", primalbound); 3677 3678 /* display (best) primal bound */ 3679 if( scip->primal->nsolsfound > 0 ) 3680 { 3681 SCIP_Real bestsol; 3682 bestsol = SCIPsolGetObj(scip->primal->sols[0], scip->set, scip->transprob, scip->origprob); 3683 bestsol = SCIPretransformObj(scip, bestsol); 3684 3685 SCIPmessageFPrintInfo(scip->messagehdlr, file, " Best Solution : %+21.14e\n", bestsol); 3686 } 3687 } 3688 else 3689 { 3690 /* display first primal bound line */ 3691 firstprimalbound = scip->stat->firstprimalbound; 3692 SCIPmessageFPrintInfo(scip->messagehdlr, file, " First Solution : %+21.14e", firstprimalbound); 3693 3694 SCIPmessageFPrintInfo(scip->messagehdlr, file, " (in run %d, after %" SCIP_LONGINT_FORMAT " nodes, %.2f seconds, depth %d, found by <%s>)\n", 3695 scip->stat->nrunsbeforefirst, 3696 scip->stat->nnodesbeforefirst, 3697 scip->stat->firstprimaltime, 3698 scip->stat->firstprimaldepth, 3699 ( scip->stat->firstprimalheur != NULL ) 3700 ? ( SCIPheurGetName(scip->stat->firstprimalheur) ) 3701 : (( scip->stat->nrunsbeforefirst == 0 ) ? "initial" : "relaxation")); 3702 3703 if( SCIPisInfinity(scip, scip->stat->firstsolgap) ) 3704 SCIPmessageFPrintInfo(scip->messagehdlr, file, " Gap First Sol. : infinite\n"); 3705 else 3706 SCIPmessageFPrintInfo(scip->messagehdlr, file, " Gap First Sol. : %10.2f %%\n", 100.0 * scip->stat->firstsolgap); 3707 3708 if( SCIPisInfinity(scip, scip->stat->lastsolgap) ) 3709 SCIPmessageFPrintInfo(scip->messagehdlr, file, " Gap Last Sol. : infinite\n"); 3710 else 3711 SCIPmessageFPrintInfo(scip->messagehdlr, file, " Gap Last Sol. : %10.2f %%\n", 100.0 * scip->stat->lastsolgap); 3712 3713 SCIPmessageFPrintInfo(scip->messagehdlr, file, " Primal Bound : %+21.14e", primalbound); 3714 3715 SCIPmessageFPrintInfo(scip->messagehdlr, file, " (in run %d, after %" SCIP_LONGINT_FORMAT " nodes, %.2f seconds, depth %d, found by <%s>)\n", 3716 SCIPsolGetRunnum(scip->primal->sols[0]), 3717 SCIPsolGetNodenum(scip->primal->sols[0]), 3718 SCIPsolGetTime(scip->primal->sols[0]), 3719 SCIPsolGetDepth(scip->primal->sols[0]), 3720 SCIPsolGetHeur(scip->primal->sols[0]) != NULL 3721 ? SCIPheurGetName(SCIPsolGetHeur(scip->primal->sols[0])) 3722 : (SCIPsolGetRunnum(scip->primal->sols[0]) == 0 ? "initial" : "relaxation")); 3723 } 3724 } 3725 3726 if( SCIPsetIsInfinity(scip->set, REALABS(dualbound)) ) 3727 SCIPmessageFPrintInfo(scip->messagehdlr, file, " Dual Bound : -\n"); 3728 else 3729 SCIPmessageFPrintInfo(scip->messagehdlr, file, " Dual Bound : %+21.14e\n", dualbound); 3730 3731 if( SCIPsetIsInfinity(scip->set, gap) ) 3732 SCIPmessageFPrintInfo(scip->messagehdlr, file, " Gap : infinite\n"); 3733 else 3734 SCIPmessageFPrintInfo(scip->messagehdlr, file, " Gap : %10.2f %%\n", 100.0 * gap); 3735 3736 if( scip->set->misc_calcintegral ) 3737 { 3738 int s; 3739 const char* names[] = { 3740 "primal-dual", 3741 "primal-ref", 3742 "dual-ref" 3743 }; 3744 SCIPmessageFPrintInfo(scip->messagehdlr, file, "Integrals : Total Avg%%\n"); 3745 if( SCIPgetStatus(scip) == SCIP_STATUS_INFEASIBLE && ! objlimitreached ) 3746 { 3747 for( s = 0; s < 3; ++s ) 3748 { 3749 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %-17s: %10s %10s (problem infeasible)\n", 3750 names[s], "-", "-"); 3751 } 3752 } 3753 else 3754 { 3755 SCIP_Real integrals[3]; 3756 SCIP_Real solvingtime = SCIPgetSolvingTime(scip); 3757 3758 if( !SCIPisFeasZero(scip, solvingtime) ) 3759 { 3760 integrals[0] = SCIPstatGetPrimalDualIntegral(scip->stat, scip->set, scip->transprob, scip->origprob, TRUE); 3761 3762 if( scip->set->misc_referencevalue != SCIP_INVALID ) /*lint !e777*/ 3763 { 3764 integrals[1] = SCIPstatGetPrimalReferenceIntegral(scip->stat, scip->set, scip->transprob, scip->origprob, FALSE); 3765 integrals[2] = SCIPstatGetDualReferenceIntegral(scip->stat, scip->set, scip->transprob, scip->origprob, FALSE); 3766 } 3767 else 3768 integrals[1] = integrals[2] = SCIP_INVALID; 3769 } 3770 else 3771 { 3772 BMSclearMemoryArray(integrals, 3); 3773 } 3774 3775 /* print integrals, if computed */ 3776 for( s = 0; s < 3; ++s ) 3777 { 3778 if( integrals[s] == SCIP_INVALID ) /*lint !e777*/ 3779 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %-17s: - - (not evaluated)\n", names[s]); 3780 else 3781 { 3782 SCIP_Real avg = integrals[s] / MAX(solvingtime,1e-6); 3783 3784 /* caution: this assert is non-deterministic since it depends on the solving time */ 3785 assert(0.0 <= avg && SCIPisLE(scip, avg, 100.0)); 3786 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %-17s: %10.2f %10.2f\n", names[s], integrals[s], avg); 3787 } 3788 } 3789 } 3790 } 3791 } 3792 3793 /** outputs concurrent solver statistics 3794 * 3795 * @pre This method can be called if SCIP is in one of the following stages: 3796 * - \ref SCIP_STAGE_TRANSFORMED 3797 * - \ref SCIP_STAGE_INITPRESOLVE 3798 * - \ref SCIP_STAGE_PRESOLVING 3799 * - \ref SCIP_STAGE_EXITPRESOLVE 3800 * - \ref SCIP_STAGE_PRESOLVED 3801 * - \ref SCIP_STAGE_SOLVING 3802 * - \ref SCIP_STAGE_SOLVED 3803 */ 3804 void SCIPprintConcsolverStatistics( 3805 SCIP* scip, /**< SCIP data structure */ 3806 FILE* file /**< output file */ 3807 ) 3808 { 3809 SCIP_CONCSOLVER** concsolvers; 3810 int nconcsolvers; 3811 int i; 3812 int winner; 3813 3814 assert(scip != NULL); 3815 assert(scip->set != NULL); 3816 3817 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPprintConcsolverStatistics", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 3818 3819 if( !SCIPsyncstoreIsInitialized(scip->syncstore) ) 3820 return; 3821 3822 nconcsolvers = SCIPgetNConcurrentSolvers(scip); 3823 concsolvers = SCIPgetConcurrentSolvers(scip); 3824 winner = SCIPsyncstoreGetWinner(scip->syncstore); 3825 3826 if( nconcsolvers > 0 ) 3827 { 3828 SCIPmessageFPrintInfo(scip->messagehdlr, file, "Concurrent Solvers : SolvingTime SyncTime Nodes LP Iters SolsShared SolsRecvd TighterBnds TighterIntBnds\n"); 3829 for( i = 0; i < nconcsolvers; ++i ) 3830 { 3831 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %c%-16s: %11.2f %11.2f %11" SCIP_LONGINT_FORMAT " %11" SCIP_LONGINT_FORMAT "%11" SCIP_LONGINT_FORMAT " %11" SCIP_LONGINT_FORMAT " %11" SCIP_LONGINT_FORMAT " %14" SCIP_LONGINT_FORMAT "\n", 3832 winner == i ? '*' : ' ', 3833 SCIPconcsolverGetName(concsolvers[i]), 3834 SCIPconcsolverGetSolvingTime(concsolvers[i]), 3835 SCIPconcsolverGetSyncTime(concsolvers[i]), 3836 SCIPconcsolverGetNNodes(concsolvers[i]), 3837 SCIPconcsolverGetNLPIterations(concsolvers[i]), 3838 SCIPconcsolverGetNSolsShared(concsolvers[i]), 3839 SCIPconcsolverGetNSolsRecvd(concsolvers[i]), 3840 SCIPconcsolverGetNTighterBnds(concsolvers[i]), 3841 SCIPconcsolverGetNTighterIntBnds(concsolvers[i]) 3842 ); 3843 } 3844 } 3845 } 3846 3847 /** display Benders' decomposition statistics */ 3848 void SCIPprintBendersStatistics( 3849 SCIP* scip, /**< SCIP data structure */ 3850 FILE* file /**< output file */ 3851 ) 3852 { 3853 SCIP_BENDERS** benders; 3854 int nbenders; 3855 int i; 3856 3857 assert(scip != NULL); 3858 assert(scip->set != NULL); 3859 3860 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPprintBendersStatistics", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 3861 3862 if( SCIPgetNActiveBenders(scip) == 0 ) 3863 return; 3864 3865 nbenders = SCIPgetNBenders(scip); 3866 benders = SCIPgetBenders(scip); 3867 3868 SCIPmessageFPrintInfo(scip->messagehdlr, file, "Benders Decomp : ExecTime SetupTime Calls Found Transfer StrCalls StrFails StrCuts\n"); 3869 for( i = 0; i < nbenders; ++i ) 3870 { 3871 if( SCIPbendersIsActive(benders[i]) ) 3872 { 3873 SCIP_BENDERSCUT** benderscuts; 3874 int nbenderscuts; 3875 int j; 3876 3877 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %-17.17s: %10.2f %10.2f %10d %10d %10d %10d %10d %10d\n", 3878 SCIPbendersGetName(scip->set->benders[i]), 3879 SCIPbendersGetTime(scip->set->benders[i]), 3880 SCIPbendersGetSetupTime(scip->set->benders[i]), 3881 SCIPbendersGetNCalls(scip->set->benders[i]), 3882 SCIPbendersGetNCutsFound(scip->set->benders[i]), 3883 SCIPbendersGetNTransferredCuts(scip->set->benders[i]), 3884 SCIPbendersGetNStrengthenCalls(scip->set->benders[i]), 3885 SCIPbendersGetNStrengthenFails(scip->set->benders[i]), 3886 SCIPbendersGetNStrengthenCutsFound(scip->set->benders[i])); 3887 3888 nbenderscuts = SCIPbendersGetNBenderscuts(scip->set->benders[i]); 3889 benderscuts = SCIPbendersGetBenderscuts(scip->set->benders[i]); 3890 3891 for( j = 0; j < nbenderscuts; j++ ) 3892 { 3893 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %-15.17s: %10.2f %10.2f %10" SCIP_LONGINT_FORMAT " %10" SCIP_LONGINT_FORMAT " -\n", 3894 SCIPbenderscutGetName(benderscuts[j]), 3895 SCIPbenderscutGetTime(benderscuts[j]), 3896 SCIPbenderscutGetSetupTime(benderscuts[j]), 3897 SCIPbenderscutGetNCalls(benderscuts[j]), 3898 SCIPbenderscutGetNFound(benderscuts[j])); 3899 } 3900 } 3901 } 3902 } 3903 3904 /** outputs root statistics 3905 * 3906 * @pre This method can be called if SCIP is in one of the following stages: 3907 * - \ref SCIP_STAGE_SOLVING 3908 * - \ref SCIP_STAGE_SOLVED 3909 */ 3910 void SCIPprintRootStatistics( 3911 SCIP* scip, /**< SCIP data structure */ 3912 FILE* file /**< output file */ 3913 ) 3914 { 3915 SCIP_Real dualboundroot; 3916 SCIP_Real firstdualboundroot; 3917 SCIP_Real firstlptime; 3918 SCIP_Real firstlpspeed; 3919 3920 assert(scip != NULL); 3921 assert(scip->stat != NULL); 3922 assert(scip->primal != NULL); 3923 3924 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPprintRootStatistics", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 3925 3926 dualboundroot = SCIPgetDualboundRoot(scip); 3927 firstdualboundroot = SCIPgetFirstLPDualboundRoot(scip); 3928 firstlptime = SCIPgetFirstLPTime(scip); 3929 3930 if( firstlptime > 0.0 ) 3931 firstlpspeed = (SCIP_Real)scip->stat->nrootfirstlpiterations/firstlptime; 3932 else 3933 firstlpspeed = 0.0; 3934 3935 SCIPmessageFPrintInfo(scip->messagehdlr, file, "Root Node :\n"); 3936 if( SCIPsetIsInfinity(scip->set, REALABS(firstdualboundroot)) ) 3937 SCIPmessageFPrintInfo(scip->messagehdlr, file, " First LP value : -\n"); 3938 else 3939 SCIPmessageFPrintInfo(scip->messagehdlr, file, " First LP value : %+21.14e\n", firstdualboundroot); 3940 if( firstlpspeed > 0.0 ) 3941 SCIPmessageFPrintInfo(scip->messagehdlr, file, " First LP Iters : %10" SCIP_LONGINT_FORMAT " (%.2f Iter/sec)\n", 3942 scip->stat->nrootfirstlpiterations, 3943 (SCIP_Real)scip->stat->nrootfirstlpiterations/firstlptime); 3944 else 3945 SCIPmessageFPrintInfo(scip->messagehdlr, file, " First LP Iters : %10" SCIP_LONGINT_FORMAT "\n", scip->stat->nrootfirstlpiterations); 3946 SCIPmessageFPrintInfo(scip->messagehdlr, file, " First LP Time : %10.2f\n", firstlptime); 3947 3948 if( SCIPsetIsInfinity(scip->set, REALABS(dualboundroot)) ) 3949 SCIPmessageFPrintInfo(scip->messagehdlr, file, " Final Dual Bound : -\n"); 3950 else 3951 SCIPmessageFPrintInfo(scip->messagehdlr, file, " Final Dual Bound : %+21.14e\n", dualboundroot); 3952 SCIPmessageFPrintInfo(scip->messagehdlr, file, " Final Root Iters : %10" SCIP_LONGINT_FORMAT "\n", scip->stat->nrootlpiterations); 3953 3954 SCIPmessageFPrintInfo(scip->messagehdlr, file, " Root LP Estimate : "); 3955 if( scip->stat->rootlpbestestimate != SCIP_INVALID ) /*lint !e777*/ 3956 { 3957 SCIPmessageFPrintInfo(scip->messagehdlr, file, "%+21.14e\n", SCIPretransformObj(scip, scip->stat->rootlpbestestimate)); 3958 } 3959 else 3960 SCIPmessageFPrintInfo(scip->messagehdlr, file, "%21s\n","-"); 3961 } 3962 3963 /** outputs timing statistics 3964 * 3965 * @pre This method can be called if SCIP is in one of the following stages: 3966 * - \ref SCIP_STAGE_PROBLEM 3967 * - \ref SCIP_STAGE_TRANSFORMED 3968 * - \ref SCIP_STAGE_INITPRESOLVE 3969 * - \ref SCIP_STAGE_PRESOLVING 3970 * - \ref SCIP_STAGE_EXITPRESOLVE 3971 * - \ref SCIP_STAGE_PRESOLVED 3972 * - \ref SCIP_STAGE_SOLVING 3973 * - \ref SCIP_STAGE_SOLVED 3974 */ 3975 void SCIPprintTimingStatistics( 3976 SCIP* scip, /**< SCIP data structure */ 3977 FILE* file /**< output file */ 3978 ) 3979 { 3980 SCIP_Real readingtime; 3981 3982 assert(scip != NULL); 3983 assert(scip->set != NULL); 3984 3985 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPprintTimingStatistics", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 3986 3987 readingtime = SCIPgetReadingTime(scip); 3988 3989 if( SCIPgetStage(scip) == SCIP_STAGE_PROBLEM ) 3990 { 3991 SCIPmessageFPrintInfo(scip->messagehdlr, file, "Total Time : %10.2f\n", readingtime); 3992 SCIPmessageFPrintInfo(scip->messagehdlr, file, " reading : %10.2f\n", readingtime); 3993 } 3994 else 3995 { 3996 SCIP_Real totaltime; 3997 SCIP_Real solvingtime; 3998 3999 solvingtime = SCIPclockGetTime(scip->stat->solvingtime); 4000 4001 if( scip->set->time_reading ) 4002 totaltime = solvingtime; 4003 else 4004 totaltime = solvingtime + readingtime; 4005 4006 SCIPmessageFPrintInfo(scip->messagehdlr, file, "Total Time : %10.2f\n", totaltime); 4007 SCIPmessageFPrintInfo(scip->messagehdlr, file, " solving : %10.2f\n", solvingtime); 4008 SCIPmessageFPrintInfo(scip->messagehdlr, file, " presolving : %10.2f (included in solving)\n", SCIPclockGetTime(scip->stat->presolvingtime)); 4009 SCIPmessageFPrintInfo(scip->messagehdlr, file, " reading : %10.2f%s\n", readingtime, scip->set->time_reading ? " (included in solving)" : ""); 4010 4011 if( scip->stat->ncopies > 0 ) 4012 { 4013 SCIP_Real copytime; 4014 4015 copytime = SCIPclockGetTime(scip->stat->copyclock); 4016 4017 SCIPmessageFPrintInfo(scip->messagehdlr, file, " copying : %10.2f (%d #copies) (minimal %.2f, maximal %.2f, average %.2f)\n", 4018 copytime, scip->stat->ncopies, scip->stat->mincopytime, scip->stat->maxcopytime, copytime / scip->stat->ncopies); 4019 } 4020 else 4021 SCIPmessageFPrintInfo(scip->messagehdlr, file, " copying : %10.2f %s\n", 0.0, "(0 times copied the problem)"); 4022 } 4023 } 4024 4025 /** outputs expression handler statistics 4026 * 4027 * @pre This method can be called if SCIP is in one of the following stages: 4028 * - \ref SCIP_STAGE_PROBLEM 4029 * - \ref SCIP_STAGE_TRANSFORMED 4030 * - \ref SCIP_STAGE_INITPRESOLVE 4031 * - \ref SCIP_STAGE_PRESOLVING 4032 * - \ref SCIP_STAGE_EXITPRESOLVE 4033 * - \ref SCIP_STAGE_PRESOLVED 4034 * - \ref SCIP_STAGE_SOLVING 4035 * - \ref SCIP_STAGE_SOLVED 4036 */ 4037 void SCIPprintExpressionHandlerStatistics( 4038 SCIP* scip, /**< SCIP data structure */ 4039 FILE* file /**< output file */ 4040 ) 4041 { 4042 SCIP_Bool headerprinted = FALSE; 4043 int i; 4044 4045 assert(scip != NULL); 4046 assert(scip->set != NULL); 4047 4048 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPprintExpressionHandlerStatistics", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 4049 4050 for( i = 0; i < scip->set->nexprhdlrs; ++i ) 4051 { 4052 SCIP_EXPRHDLR* exprhdlr = scip->set->exprhdlrs[i]; 4053 assert(exprhdlr != NULL); 4054 4055 /* skip unused expression handler */ 4056 if( SCIPexprhdlrGetNCreated(exprhdlr) == 0 ) 4057 continue; 4058 4059 if( !headerprinted ) 4060 { 4061 SCIPmessageFPrintInfo(scip->messagehdlr, file, 4062 "Expressions : %10s %10s %10s %10s %10s %10s %10s %10s %10s %10s %10s %10s\n", 4063 "#IntEval", "IntEvalTi", "#RevProp", "RevPropTi", "DomReds", "Cutoffs", "#Estimate", "EstimTime", "Branching", "#Simplify", "SimplifyTi", "Simplified"); 4064 headerprinted = TRUE; 4065 } 4066 4067 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %-17s:", SCIPexprhdlrGetName(exprhdlr)); 4068 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %10lld", SCIPexprhdlrGetNIntevalCalls(exprhdlr)); 4069 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %10.2f", SCIPexprhdlrGetIntevalTime(exprhdlr)); 4070 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %10lld", SCIPexprhdlrGetNReversepropCalls(exprhdlr)); 4071 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %10.2f", SCIPexprhdlrGetReversepropTime(exprhdlr)); 4072 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %10lld", SCIPexprhdlrGetNDomainReductions(exprhdlr)); 4073 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %10lld", SCIPexprhdlrGetNCutoffs(exprhdlr)); 4074 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %10lld", SCIPexprhdlrGetNEstimateCalls(exprhdlr)); 4075 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %10.2f", SCIPexprhdlrGetEstimateTime(exprhdlr)); 4076 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %10lld", SCIPexprhdlrGetNBranchings(exprhdlr)); 4077 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %10lld", SCIPexprhdlrGetNSimplifyCalls(exprhdlr)); 4078 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %10.2f", SCIPexprhdlrGetSimplifyTime(exprhdlr)); 4079 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %10lld", SCIPexprhdlrGetNSimplifications(exprhdlr)); 4080 SCIPmessageFPrintInfo(scip->messagehdlr, file, "\n"); 4081 } 4082 } 4083 4084 /** outputs NLPI statistics 4085 * 4086 * @pre This method can be called if SCIP is in one of the following stages: 4087 * - \ref SCIP_STAGE_PROBLEM 4088 * - \ref SCIP_STAGE_TRANSFORMED 4089 * - \ref SCIP_STAGE_INITPRESOLVE 4090 * - \ref SCIP_STAGE_PRESOLVING 4091 * - \ref SCIP_STAGE_EXITPRESOLVE 4092 * - \ref SCIP_STAGE_PRESOLVED 4093 * - \ref SCIP_STAGE_SOLVING 4094 * - \ref SCIP_STAGE_SOLVED 4095 */ 4096 void SCIPprintNLPIStatistics( 4097 SCIP* scip, /**< SCIP data structure */ 4098 FILE* file /**< output file */ 4099 ) 4100 { 4101 SCIP_Bool printedheader = FALSE; 4102 int i; 4103 4104 assert(scip != NULL); 4105 assert(scip->set != NULL); 4106 4107 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPprintNLPIStatistics", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 4108 4109 for( i = 0; i < scip->set->nnlpis; ++i ) 4110 { 4111 SCIP_Real solvetime; 4112 SCIP_Real evaltime = 0.0; 4113 SCIP_Longint niter; 4114 SCIP_NLPI* nlpi; 4115 int j; 4116 4117 nlpi = scip->set->nlpis[i]; 4118 assert(nlpi != NULL); 4119 4120 /* skip unused NLP solver */ 4121 if( SCIPnlpiGetNProblems(nlpi) == 0 ) 4122 continue; 4123 4124 if( !printedheader ) 4125 { 4126 SCIPmessageFPrintInfo(scip->messagehdlr, file, 4127 "NLP Solvers : %10s %10s %10s %10s %s%10s %10s" 4128 " %10s %10s %10s %10s %10s %10s %10s %10s %10s %10s" 4129 " %10s %10s %10s %10s %10s %10s %10s\n", 4130 "#Problems", "ProblemTi", "#Solves", "SolveTime", 4131 scip->set->time_nlpieval ? " EvalTime%" : "", 4132 "#Iter", "Time/Iter", 4133 "#Okay", "#TimeLimit", "#IterLimit", "#LObjLimit", "#Interrupt", "#NumError", "#EvalError", "#OutOfMem", "#LicenseEr", "#OtherTerm", 4134 "#GlobOpt", "#LocOpt", "#Feasible", "#LocInfeas", "#GlobInfea", "#Unbounded", "#Unknown" 4135 ); 4136 printedheader = TRUE; 4137 } 4138 4139 solvetime = SCIPnlpiGetSolveTime(nlpi); 4140 if( scip->set->time_nlpieval ) 4141 evaltime = SCIPnlpiGetEvalTime(nlpi); 4142 niter = SCIPnlpiGetNIterations(nlpi); 4143 4144 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %-17s:", SCIPnlpiGetName(nlpi)); 4145 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %10d", SCIPnlpiGetNProblems(nlpi)); 4146 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %10.2f", SCIPnlpiGetProblemTime(nlpi)); 4147 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %10d", SCIPnlpiGetNSolves(nlpi)); 4148 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %10.2f", solvetime); 4149 if( scip->set->time_nlpieval ) 4150 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %10.2f", solvetime > 0.0 ? 100.0 * evaltime / solvetime : 0.0); 4151 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %10" SCIP_LONGINT_FORMAT, niter); 4152 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %10.2f", niter > 0 ? solvetime / niter : 0.0); 4153 4154 for( j = (int)SCIP_NLPTERMSTAT_OKAY; j <= (int)SCIP_NLPTERMSTAT_OTHER; ++j ) 4155 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %10d", SCIPnlpiGetNTermStat(nlpi, (SCIP_NLPTERMSTAT)j)); 4156 4157 for( j = (int)SCIP_NLPSOLSTAT_GLOBOPT; j <= (int)SCIP_NLPSOLSTAT_UNKNOWN; ++j ) 4158 SCIPmessageFPrintInfo(scip->messagehdlr, file, " %10d", SCIPnlpiGetNSolStat(nlpi, (SCIP_NLPSOLSTAT)j)); 4159 4160 SCIPmessageFPrintInfo(scip->messagehdlr, file, "\n"); 4161 } 4162 } 4163 4164 /** comparison method for statistics tables */ 4165 static 4166 SCIP_DECL_SORTPTRCOMP(tablePosComp) 4167 { /*lint --e{715}*/ 4168 return (SCIPtableGetPosition((SCIP_TABLE*)elem1) - (SCIPtableGetPosition((SCIP_TABLE*)elem2))); 4169 } 4170 4171 /** outputs solving statistics 4172 * 4173 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 4174 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 4175 * 4176 * @note If limits have been changed between the solution and the call to this function, the status is recomputed and 4177 * thus may to correspond to the original status. 4178 * 4179 * @pre This method can be called if SCIP is in one of the following stages: 4180 * - \ref SCIP_STAGE_INIT 4181 * - \ref SCIP_STAGE_PROBLEM 4182 * - \ref SCIP_STAGE_TRANSFORMED 4183 * - \ref SCIP_STAGE_INITPRESOLVE 4184 * - \ref SCIP_STAGE_PRESOLVING 4185 * - \ref SCIP_STAGE_EXITPRESOLVE 4186 * - \ref SCIP_STAGE_PRESOLVED 4187 * - \ref SCIP_STAGE_SOLVING 4188 * - \ref SCIP_STAGE_SOLVED 4189 */ 4190 SCIP_RETCODE SCIPprintStatistics( 4191 SCIP* scip, /**< SCIP data structure */ 4192 FILE* file /**< output file (or NULL for standard output) */ 4193 ) 4194 { 4195 SCIP_TABLE** tables; 4196 int ntables; 4197 int i; 4198 4199 assert(scip != NULL); 4200 assert(scip->set != NULL); 4201 4202 SCIP_CALL( SCIPcheckStage(scip, "SCIPprintStatistics", TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 4203 4204 ntables = SCIPgetNTables(scip); 4205 tables = SCIPgetTables(scip); 4206 4207 /* sort all tables by position unless this has already been done */ 4208 if( ! scip->set->tablessorted ) 4209 { 4210 SCIPsortPtr((void**)tables, tablePosComp, ntables); 4211 4212 scip->set->tablessorted = TRUE; 4213 } 4214 4215 for( i = 0; i < ntables; ++i ) 4216 { 4217 /* skip tables which are not active or only used in later stages */ 4218 if( ( ! SCIPtableIsActive(tables[i]) ) || SCIPtableGetEarliestStage(tables[i]) > SCIPgetStage(scip) ) 4219 continue; 4220 4221 SCIP_CALL( SCIPtableOutput(tables[i], scip->set, file) ); 4222 } 4223 4224 return SCIP_OKAY; 4225 } 4226 4227 /** outputs reoptimization statistics 4228 * 4229 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 4230 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 4231 * 4232 * @pre This method can be called if SCIP is in one of the following stages: 4233 * - \ref SCIP_STAGE_INIT 4234 * - \ref SCIP_STAGE_PROBLEM 4235 * - \ref SCIP_STAGE_TRANSFORMED 4236 * - \ref SCIP_STAGE_INITPRESOLVE 4237 * - \ref SCIP_STAGE_PRESOLVING 4238 * - \ref SCIP_STAGE_EXITPRESOLVE 4239 * - \ref SCIP_STAGE_PRESOLVED 4240 * - \ref SCIP_STAGE_SOLVING 4241 * - \ref SCIP_STAGE_SOLVED 4242 */ 4243 SCIP_RETCODE SCIPprintReoptStatistics( 4244 SCIP* scip, /**< SCIP data structure */ 4245 FILE* file /**< output file (or NULL for standard output) */ 4246 ) 4247 { 4248 SCIP_Real solving; 4249 SCIP_Real presolving; 4250 SCIP_Real updatetime; 4251 4252 SCIP_CALL( SCIPcheckStage(scip, "SCIPprintReoptStatistics", TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 4253 4254 assert(scip != NULL); 4255 4256 /* skip if reoptimization is disabled */ 4257 if( !scip->set->reopt_enable ) 4258 return SCIP_OKAY; 4259 4260 /* skip if not problem yet */ 4261 if( scip->stat == NULL ) 4262 return SCIP_OKAY; 4263 4264 solving = SCIPclockGetTime(scip->stat->solvingtimeoverall); 4265 presolving = SCIPclockGetTime(scip->stat->presolvingtimeoverall); 4266 updatetime = SCIPclockGetTime(scip->stat->reoptupdatetime); 4267 4268 SCIPmessageFPrintInfo(scip->messagehdlr, file, "SCIP Reopt Status : finished after %d runs.\n", scip->stat->nreoptruns); 4269 SCIPmessageFPrintInfo(scip->messagehdlr, file, "Time (sec) :\n"); 4270 SCIPmessageFPrintInfo(scip->messagehdlr, file, " solving : %10.2f\n", solving); 4271 SCIPmessageFPrintInfo(scip->messagehdlr, file, " presolving : %10.2f (included in solving)\n", presolving); 4272 SCIPmessageFPrintInfo(scip->messagehdlr, file, " save time : %10.2f\n", SCIPreoptGetSavingtime(scip->reopt)); 4273 SCIPmessageFPrintInfo(scip->messagehdlr, file, " update time : %10.2f\n", updatetime); 4274 SCIPmessageFPrintInfo(scip->messagehdlr, file, "Nodes : feas infeas pruned cutoff\n"); 4275 SCIPmessageFPrintInfo(scip->messagehdlr, file, " total : %10d %10d %10d %10d\n", 4276 SCIPreoptGetNTotalFeasNodes(scip->reopt), SCIPreoptGetNTotalInfNodes(scip->reopt), 4277 SCIPreoptGetNTotalPrunedNodes(scip->reopt), SCIPreoptGetNTotalCutoffReoptnodes(scip->reopt)); 4278 if( scip->stat->nreoptruns > 0 ) 4279 { 4280 SCIPmessageFPrintInfo(scip->messagehdlr, file, " avg : %10.2f %10.2f %10.2f %10.2f\n", 4281 (SCIP_Real)SCIPreoptGetNTotalFeasNodes(scip->reopt)/scip->stat->nreoptruns, 4282 (SCIP_Real)SCIPreoptGetNTotalInfNodes(scip->reopt)/scip->stat->nreoptruns, 4283 (SCIP_Real)SCIPreoptGetNTotalPrunedNodes(scip->reopt)/scip->stat->nreoptruns, 4284 (SCIP_Real)SCIPreoptGetNTotalCutoffReoptnodes(scip->reopt)/scip->stat->nreoptruns); 4285 } 4286 else 4287 { 4288 SCIPmessageFPrintInfo(scip->messagehdlr, file, " avg : %10s %10s %10s %10s\n", "--", "--", "--", "--"); 4289 } 4290 SCIPmessageFPrintInfo(scip->messagehdlr, file, "Restarts : global local\n"); 4291 SCIPmessageFPrintInfo(scip->messagehdlr, file, " first : %10d --\n", SCIPreoptGetFirstRestarts(scip->reopt)); 4292 SCIPmessageFPrintInfo(scip->messagehdlr, file, " last : %10d --\n", SCIPreoptGetLastRestarts(scip->reopt)); 4293 SCIPmessageFPrintInfo(scip->messagehdlr, file, " total : %10d %10d\n", SCIPreoptGetNRestartsGlobal(scip->reopt), 4294 SCIPreoptGetNTotalRestartsLocal(scip->reopt)); 4295 if( scip->stat->nreoptruns > 0 ) 4296 { 4297 SCIPmessageFPrintInfo(scip->messagehdlr, file, " avg : -- %10.2f\n", 4298 (SCIP_Real)SCIPreoptGetNTotalRestartsLocal(scip->reopt)/scip->stat->nreoptruns); 4299 } 4300 else 4301 { 4302 SCIPmessageFPrintInfo(scip->messagehdlr, file, " avg : -- %10s\n", "--"); 4303 } 4304 4305 return SCIP_OKAY; 4306 } 4307 4308 /** outputs history statistics about branchings on variables 4309 * 4310 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 4311 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 4312 * 4313 * @pre This method can be called if SCIP is in one of the following stages: 4314 * - \ref SCIP_STAGE_INIT 4315 * - \ref SCIP_STAGE_PROBLEM 4316 * - \ref SCIP_STAGE_TRANSFORMED 4317 * - \ref SCIP_STAGE_INITPRESOLVE 4318 * - \ref SCIP_STAGE_PRESOLVING 4319 * - \ref SCIP_STAGE_EXITPRESOLVE 4320 * - \ref SCIP_STAGE_PRESOLVED 4321 * - \ref SCIP_STAGE_SOLVING 4322 * - \ref SCIP_STAGE_SOLVED 4323 */ 4324 SCIP_RETCODE SCIPprintBranchingStatistics( 4325 SCIP* scip, /**< SCIP data structure */ 4326 FILE* file /**< output file (or NULL for standard output) */ 4327 ) 4328 { 4329 SCIP_VAR** vars; 4330 int totalnstrongbranchs; 4331 int v; 4332 4333 SCIP_CALL( SCIPcheckStage(scip, "SCIPprintBranchingStatistics", TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 4334 4335 switch( scip->set->stage ) 4336 { 4337 case SCIP_STAGE_INIT: 4338 case SCIP_STAGE_PROBLEM: 4339 SCIPmessageFPrintInfo(scip->messagehdlr, file, "problem not yet solved. branching statistics not available.\n"); 4340 return SCIP_OKAY; 4341 4342 case SCIP_STAGE_TRANSFORMED: 4343 case SCIP_STAGE_INITPRESOLVE: 4344 case SCIP_STAGE_PRESOLVING: 4345 case SCIP_STAGE_EXITPRESOLVE: 4346 case SCIP_STAGE_PRESOLVED: 4347 case SCIP_STAGE_SOLVING: 4348 case SCIP_STAGE_SOLVED: 4349 SCIP_CALL( SCIPallocBufferArray(scip, &vars, scip->transprob->nvars) ); 4350 for( v = 0; v < scip->transprob->nvars; ++v ) 4351 { 4352 SCIP_VAR* var; 4353 int i; 4354 4355 var = scip->transprob->vars[v]; 4356 for( i = v; i > 0 && strcmp(SCIPvarGetName(var), SCIPvarGetName(vars[i-1])) < 0; i-- ) 4357 vars[i] = vars[i-1]; 4358 vars[i] = var; 4359 } 4360 4361 SCIPmessageFPrintInfo(scip->messagehdlr, file, " locks branchings inferences cutoffs LP gain pscostcount gain variance \n"); 4362 SCIPmessageFPrintInfo(scip->messagehdlr, file, "variable prio factor down up depth down up sb down up down up down up down up down up\n"); 4363 4364 totalnstrongbranchs = 0; 4365 for( v = 0; v < scip->transprob->nvars; ++v ) 4366 { 4367 if( SCIPvarGetNBranchings(vars[v], SCIP_BRANCHDIR_DOWNWARDS) > 0 4368 || SCIPvarGetNBranchings(vars[v], SCIP_BRANCHDIR_UPWARDS) > 0 4369 || SCIPgetVarNStrongbranchs(scip, vars[v]) > 0 ) 4370 { 4371 int nstrongbranchs; 4372 4373 nstrongbranchs = SCIPgetVarNStrongbranchs(scip, vars[v]); 4374 totalnstrongbranchs += nstrongbranchs; 4375 SCIPmessageFPrintInfo(scip->messagehdlr, file, "%-16s %5d %8.1f %6d %6d %6.1f %7" SCIP_LONGINT_FORMAT " %7" SCIP_LONGINT_FORMAT " %5d %8.1f %8.1f %5.1f%% %5.1f%% %15.4f %15.4f %7.1f %7.1f %15.2f %15.2f\n", 4376 SCIPvarGetName(vars[v]), 4377 SCIPvarGetBranchPriority(vars[v]), 4378 SCIPvarGetBranchFactor(vars[v]), 4379 SCIPvarGetNLocksDownType(vars[v], SCIP_LOCKTYPE_MODEL), 4380 SCIPvarGetNLocksUpType(vars[v], SCIP_LOCKTYPE_MODEL), 4381 (SCIPvarGetAvgBranchdepth(vars[v], SCIP_BRANCHDIR_DOWNWARDS) 4382 + SCIPvarGetAvgBranchdepth(vars[v], SCIP_BRANCHDIR_UPWARDS))/2.0 - 1.0, 4383 SCIPvarGetNBranchings(vars[v], SCIP_BRANCHDIR_DOWNWARDS), 4384 SCIPvarGetNBranchings(vars[v], SCIP_BRANCHDIR_UPWARDS), 4385 nstrongbranchs, 4386 SCIPvarGetAvgInferences(vars[v], scip->stat, SCIP_BRANCHDIR_DOWNWARDS), 4387 SCIPvarGetAvgInferences(vars[v], scip->stat, SCIP_BRANCHDIR_UPWARDS), 4388 100.0 * SCIPvarGetAvgCutoffs(vars[v], scip->stat, SCIP_BRANCHDIR_DOWNWARDS), 4389 100.0 * SCIPvarGetAvgCutoffs(vars[v], scip->stat, SCIP_BRANCHDIR_UPWARDS), 4390 SCIPvarGetPseudocost(vars[v], scip->stat, -1.0), 4391 SCIPvarGetPseudocost(vars[v], scip->stat, +1.0), 4392 SCIPvarGetPseudocostCount(vars[v], SCIP_BRANCHDIR_DOWNWARDS), 4393 SCIPvarGetPseudocostCount(vars[v], SCIP_BRANCHDIR_UPWARDS), 4394 SCIPvarGetPseudocostVariance(vars[v], SCIP_BRANCHDIR_DOWNWARDS, FALSE), 4395 SCIPvarGetPseudocostVariance(vars[v], SCIP_BRANCHDIR_UPWARDS, FALSE)); 4396 } 4397 } 4398 SCIPmessageFPrintInfo(scip->messagehdlr, file, "total %7" SCIP_LONGINT_FORMAT " %7" SCIP_LONGINT_FORMAT " %5d %8.1f %8.1f %5.1f%% %5.1f%% %15.4f %15.4f %7.1f %7.1f %15.2f %15.2f\n", 4399 SCIPhistoryGetNBranchings(scip->stat->glbhistory, SCIP_BRANCHDIR_DOWNWARDS), 4400 SCIPhistoryGetNBranchings(scip->stat->glbhistory, SCIP_BRANCHDIR_UPWARDS), 4401 totalnstrongbranchs, 4402 SCIPhistoryGetNBranchings(scip->stat->glbhistory, SCIP_BRANCHDIR_DOWNWARDS) > 0 4403 ? SCIPhistoryGetInferenceSum(scip->stat->glbhistory, SCIP_BRANCHDIR_DOWNWARDS) 4404 / (SCIP_Real)SCIPhistoryGetNBranchings(scip->stat->glbhistory, SCIP_BRANCHDIR_DOWNWARDS) : 0.0, 4405 SCIPhistoryGetNBranchings(scip->stat->glbhistory, SCIP_BRANCHDIR_UPWARDS) > 0 4406 ? SCIPhistoryGetInferenceSum(scip->stat->glbhistory, SCIP_BRANCHDIR_UPWARDS) 4407 / (SCIP_Real)SCIPhistoryGetNBranchings(scip->stat->glbhistory, SCIP_BRANCHDIR_UPWARDS) : 0.0, 4408 SCIPhistoryGetNBranchings(scip->stat->glbhistory, SCIP_BRANCHDIR_DOWNWARDS) > 0 4409 ? SCIPhistoryGetCutoffSum(scip->stat->glbhistory, SCIP_BRANCHDIR_DOWNWARDS) 4410 / (SCIP_Real)SCIPhistoryGetNBranchings(scip->stat->glbhistory, SCIP_BRANCHDIR_DOWNWARDS) : 0.0, 4411 SCIPhistoryGetNBranchings(scip->stat->glbhistory, SCIP_BRANCHDIR_UPWARDS) > 0 4412 ? SCIPhistoryGetCutoffSum(scip->stat->glbhistory, SCIP_BRANCHDIR_UPWARDS) 4413 / (SCIP_Real)SCIPhistoryGetNBranchings(scip->stat->glbhistory, SCIP_BRANCHDIR_UPWARDS) : 0.0, 4414 SCIPhistoryGetPseudocost(scip->stat->glbhistory, -1.0), 4415 SCIPhistoryGetPseudocost(scip->stat->glbhistory, +1.0), 4416 SCIPhistoryGetPseudocostCount(scip->stat->glbhistory, SCIP_BRANCHDIR_DOWNWARDS), 4417 SCIPhistoryGetPseudocostCount(scip->stat->glbhistory, SCIP_BRANCHDIR_UPWARDS), 4418 SCIPhistoryGetPseudocostVariance(scip->stat->glbhistory, SCIP_BRANCHDIR_DOWNWARDS), 4419 SCIPhistoryGetPseudocostVariance(scip->stat->glbhistory, SCIP_BRANCHDIR_UPWARDS)); 4420 4421 SCIPfreeBufferArray(scip, &vars); 4422 4423 return SCIP_OKAY; 4424 4425 default: 4426 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage); 4427 return SCIP_INVALIDCALL; 4428 } /*lint !e788*/ 4429 } 4430 4431 /** outputs node information display line 4432 * 4433 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 4434 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 4435 * 4436 * @pre This method can be called if SCIP is in one of the following stages: 4437 * - \ref SCIP_STAGE_SOLVING 4438 */ 4439 SCIP_RETCODE SCIPprintDisplayLine( 4440 SCIP* scip, /**< SCIP data structure */ 4441 FILE* file, /**< output file (or NULL for standard output) */ 4442 SCIP_VERBLEVEL verblevel, /**< minimal verbosity level to actually display the information line */ 4443 SCIP_Bool endline /**< should the line be terminated with a newline symbol? */ 4444 ) 4445 { 4446 SCIP_CALL( SCIPcheckStage(scip, "SCIPprintDisplayLine", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 4447 4448 if( (SCIP_VERBLEVEL)scip->set->disp_verblevel >= verblevel ) 4449 { 4450 SCIP_CALL( SCIPdispPrintLine(scip->set, scip->messagehdlr, scip->stat, file, TRUE, endline) ); 4451 } 4452 4453 return SCIP_OKAY; 4454 } 4455 4456 /** gets total number of implications between variables that are stored in the implication graph 4457 * 4458 * @return the total number of implications between variables that are stored in the implication graph 4459 * 4460 * @pre This method can be called if SCIP is in one of the following stages: 4461 * - \ref SCIP_STAGE_INITPRESOLVE 4462 * - \ref SCIP_STAGE_PRESOLVING 4463 * - \ref SCIP_STAGE_EXITPRESOLVE 4464 * - \ref SCIP_STAGE_PRESOLVED 4465 * - \ref SCIP_STAGE_INITSOLVE 4466 * - \ref SCIP_STAGE_SOLVING 4467 * - \ref SCIP_STAGE_SOLVED 4468 */ 4469 int SCIPgetNImplications( 4470 SCIP* scip /**< SCIP data structure */ 4471 ) 4472 { 4473 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNImplications", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 4474 4475 return scip->stat->nimplications; 4476 } 4477 4478 /** stores conflict graph of binary variables' implications into a file, which can be used as input for the DOT tool 4479 * 4480 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 4481 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 4482 * 4483 * @pre This method can be called if SCIP is in one of the following stages: 4484 * - \ref SCIP_STAGE_TRANSFORMED 4485 * - \ref SCIP_STAGE_INITPRESOLVE 4486 * - \ref SCIP_STAGE_PRESOLVING 4487 * - \ref SCIP_STAGE_EXITPRESOLVE 4488 * - \ref SCIP_STAGE_PRESOLVED 4489 * - \ref SCIP_STAGE_INITSOLVE 4490 * - \ref SCIP_STAGE_SOLVING 4491 * - \ref SCIP_STAGE_SOLVED 4492 * - \ref SCIP_STAGE_EXITSOLVE 4493 * 4494 * @deprecated because binary implications are now stored as cliques, please use SCIPwriteCliqueGraph() instead 4495 * 4496 */ /*lint -e715*/ 4497 SCIP_RETCODE SCIPwriteImplicationConflictGraph( 4498 SCIP* scip, /**< SCIP data structure */ 4499 const char* filename /**< file name, or NULL for stdout */ 4500 ) 4501 { /*lint --e{715}*/ 4502 SCIPwarningMessage(scip, "SCIPwriteImplicationConflictGraph() is deprecated and does not do anything anymore. All binary to binary implications are now stored in the clique data structure, which can be written to a GML formatted file via SCIPwriteCliqueGraph().\n"); 4503 4504 return SCIP_OKAY; 4505 } 4506 4507 /** update statistical information when a new solution was found */ 4508 void SCIPstoreSolutionGap( 4509 SCIP* scip /**< SCIP data structure */ 4510 ) 4511 { 4512 scip->stat->lastsolgap = SCIPcomputeGap(SCIPsetEpsilon(scip->set), SCIPsetInfinity(scip->set), SCIPgetPrimalbound(scip), SCIPgetDualbound(scip)); 4513 4514 if( scip->primal->nsols == 1 ) 4515 scip->stat->firstsolgap = scip->stat->lastsolgap; 4516 4517 if( scip->set->stage == SCIP_STAGE_SOLVING && scip->set->misc_calcintegral ) 4518 { 4519 SCIPstatUpdatePrimalDualIntegrals(scip->stat, scip->set, scip->transprob, scip->origprob, SCIPgetUpperbound(scip), SCIPgetLowerbound(scip) ); 4520 } 4521 } 4522 4523 /** recomputes and returns the primal dual gap stored in the stats */ 4524 SCIP_EXPORT 4525 SCIP_Real SCIPgetPrimalDualIntegral( 4526 SCIP* scip /**< SCIP data structure */ 4527 ) 4528 { 4529 return SCIPstatGetPrimalDualIntegral(scip->stat, scip->set, scip->transprob, scip->origprob, TRUE); 4530 } 4531