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 cutsel.c 26 * @ingroup OTHER_CFILES 27 * @brief methods for cut selectors 28 * @author Felipe Serrano 29 * @author Mark Turner 30 */ 31 32 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/ 33 34 #include <assert.h> 35 36 #include "scip/set.h" 37 #include "scip/clock.h" 38 #include "scip/paramset.h" 39 #include "scip/scip.h" 40 #include "scip/cutsel.h" 41 42 #include "scip/struct_cutsel.h" 43 44 45 /** method to call, when the priority of a cut selector was changed */ 46 static 47 SCIP_DECL_PARAMCHGD(paramChgdCutselPriority) 48 { /*lint --e{715}*/ 49 SCIP_PARAMDATA* paramdata; 50 51 paramdata = SCIPparamGetData(param); 52 assert(paramdata != NULL); 53 54 /* use SCIPsetCutselPriority() to mark the cutsels unsorted */ 55 SCIP_CALL( SCIPsetCutselPriority(scip, (SCIP_CUTSEL*)paramdata, SCIPparamGetInt(param)) ); /*lint !e740*/ 56 57 return SCIP_OKAY; 58 } 59 60 /** internal method for creating a cut selector */ 61 static 62 SCIP_RETCODE doCutselCreate( 63 SCIP_CUTSEL** cutsel, /**< pointer to store cut selector */ 64 SCIP_SET* set, /**< global SCIP settings */ 65 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */ 66 BMS_BLKMEM* blkmem, /**< block memory for parameter settings */ 67 const char* name, /**< name of cut selector */ 68 const char* desc, /**< description of cut selector */ 69 int priority, /**< priority of the cut selector */ 70 SCIP_DECL_CUTSELCOPY ((*cutselcopy)), /**< copy method of cut selector or NULL if you don't want to copy your plugin into sub-SCIPs */ 71 SCIP_DECL_CUTSELFREE ((*cutselfree)), /**< destructor of cut selector */ 72 SCIP_DECL_CUTSELINIT ((*cutselinit)), /**< initialize cut selector */ 73 SCIP_DECL_CUTSELEXIT ((*cutselexit)), /**< deinitialize cut selector */ 74 SCIP_DECL_CUTSELINITSOL((*cutselinitsol)),/**< solving process initialization method of cut selector */ 75 SCIP_DECL_CUTSELEXITSOL((*cutselexitsol)),/**< solving process deinitialization method of cut selector */ 76 SCIP_DECL_CUTSELSELECT((*cutselselect)), /**< cut selection method */ 77 SCIP_CUTSELDATA* cutseldata /**< cut selector data */ 78 ) 79 { 80 char paramname[SCIP_MAXSTRLEN]; 81 char paramdesc[SCIP_MAXSTRLEN]; 82 83 assert(cutsel != NULL); 84 assert(name != NULL); 85 assert(desc != NULL); 86 assert(cutselselect != NULL); 87 88 SCIP_ALLOC( BMSallocMemory(cutsel) ); 89 BMSclearMemory(*cutsel); 90 91 SCIP_ALLOC( BMSduplicateMemoryArray(&(*cutsel)->name, name, strlen(name)+1) ); 92 SCIP_ALLOC( BMSduplicateMemoryArray(&(*cutsel)->desc, desc, strlen(desc)+1) ); 93 (*cutsel)->priority = priority; 94 (*cutsel)->cutselcopy = cutselcopy; 95 (*cutsel)->cutselfree = cutselfree; 96 (*cutsel)->cutselinit = cutselinit; 97 (*cutsel)->cutselexit = cutselexit; 98 (*cutsel)->cutselinitsol = cutselinitsol; 99 (*cutsel)->cutselexitsol = cutselexitsol; 100 (*cutsel)->cutselselect = cutselselect; 101 (*cutsel)->cutseldata = cutseldata; 102 (*cutsel)->ncalls = 0; 103 (*cutsel)->nrootcalls = 0; 104 (*cutsel)->nrootcutsselected = 0; 105 (*cutsel)->nrootcutsforced = 0; 106 (*cutsel)->nrootcutsfiltered = 0; 107 (*cutsel)->nlocalcutsselected = 0; 108 (*cutsel)->nlocalcutsforced = 0; 109 (*cutsel)->nlocalcutsfiltered = 0; 110 (*cutsel)->initialized = FALSE; 111 112 /* create clocks */ 113 SCIP_CALL( SCIPclockCreate(&(*cutsel)->setuptime, SCIP_CLOCKTYPE_DEFAULT) ); 114 SCIP_CALL( SCIPclockCreate(&(*cutsel)->cutseltime, SCIP_CLOCKTYPE_DEFAULT) ); 115 116 /* add parameters */ 117 (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "cutselection/%s/priority", name); 118 (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "priority of cut selection rule <%s>", name); 119 SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc, 120 &(*cutsel)->priority, FALSE, priority, INT_MIN/4, INT_MAX/2, 121 paramChgdCutselPriority, (SCIP_PARAMDATA*)(*cutsel)) ); /*lint !e740*/ 122 123 return SCIP_OKAY; 124 } 125 126 127 /** creates a cut selector */ 128 SCIP_RETCODE SCIPcutselCreate( 129 SCIP_CUTSEL** cutsel, /**< pointer to store cut selector */ 130 SCIP_SET* set, /**< global SCIP settings */ 131 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */ 132 BMS_BLKMEM* blkmem, /**< block memory for parameter settings */ 133 const char* name, /**< name of cut selector */ 134 const char* desc, /**< description of cut selector */ 135 int priority, /**< priority of the cut selector in standard mode */ 136 SCIP_DECL_CUTSELCOPY ((*cutselcopy)), /**< copy method of cut selector or NULL if you don't want to copy your plugin into sub-SCIPs */ 137 SCIP_DECL_CUTSELFREE ((*cutselfree)), /**< destructor of cut selector */ 138 SCIP_DECL_CUTSELINIT ((*cutselinit)), /**< initialize cut selector */ 139 SCIP_DECL_CUTSELEXIT ((*cutselexit)), /**< deinitialize cut selector */ 140 SCIP_DECL_CUTSELINITSOL((*cutselinitsol)),/**< solving process initialization method of cut selector */ 141 SCIP_DECL_CUTSELEXITSOL((*cutselexitsol)),/**< solving process deinitialization method of cut selector */ 142 SCIP_DECL_CUTSELSELECT((*cutselselect)), /**< cut selection method */ 143 SCIP_CUTSELDATA* cutseldata /**< cut selector data */ 144 ) 145 { 146 assert(cutsel != NULL); 147 assert(name != NULL); 148 assert(desc != NULL); 149 assert(cutselselect != NULL); 150 151 SCIP_CALL_FINALLY( doCutselCreate(cutsel, set, messagehdlr, blkmem, name, desc, priority, 152 cutselcopy, cutselfree, cutselinit, cutselexit, cutselinitsol, cutselexitsol, cutselselect, 153 cutseldata), (void) SCIPcutselFree(cutsel, set) ); 154 155 return SCIP_OKAY; 156 } 157 158 /** gets name of cut selector */ 159 const char* SCIPcutselGetName( 160 SCIP_CUTSEL* cutsel /**< cut selector */ 161 ) 162 { 163 assert(cutsel != NULL); 164 165 return cutsel->name; 166 } 167 168 /** calls cut selectors to select cuts */ 169 SCIP_RETCODE SCIPcutselsSelect( 170 SCIP_SET* set, /**< global SCIP settings */ 171 SCIP_ROW** cuts, /**< array with cuts to select from */ 172 int ncuts, /**< length of cuts */ 173 int nforcedcuts, /**< number of forced cuts at start of given array */ 174 SCIP_Bool root, /**< are we at the root node? */ 175 SCIP_Bool initiallp, /**< is the separation storage currently being filled with the initial LP rows? */ 176 int maxnselectedcuts, /**< maximum number of cuts to be selected */ 177 int* nselectedcuts /**< pointer to return number of selected cuts */ 178 ) 179 { 180 int i; 181 SCIP_RESULT result = SCIP_DIDNOTFIND; 182 183 assert(nselectedcuts != NULL); 184 185 /* sort the cut selectors by priority */ 186 SCIPsetSortCutsels(set); 187 188 /* Redefine maxnselectedcuts to be w.r.t the optional cuts. */ 189 maxnselectedcuts -= nforcedcuts; 190 maxnselectedcuts = MIN(maxnselectedcuts, ncuts); 191 192 /* try all cut selectors until one succeeds */ 193 *nselectedcuts = 0; 194 for( i = 0; i < set->ncutsels && result == SCIP_DIDNOTFIND; ++i ) 195 { 196 SCIP_CUTSEL* cutsel; 197 198 cutsel = set->cutsels[i]; 199 200 assert(cutsel != NULL); 201 assert(ncuts - nforcedcuts > 0); 202 assert(maxnselectedcuts > 0); 203 204 /* start timing */ 205 SCIPclockStart(cutsel->cutseltime, set); 206 207 SCIP_CALL( cutsel->cutselselect(set->scip, cutsel, &(cuts[nforcedcuts]), ncuts - nforcedcuts, cuts, nforcedcuts, 208 root, maxnselectedcuts, nselectedcuts, &result) ); 209 210 /* stop timing */ 211 SCIPclockStop(cutsel->cutseltime, set); 212 213 assert(*nselectedcuts <= maxnselectedcuts); 214 assert(result == SCIP_SUCCESS || result == SCIP_DIDNOTFIND); 215 assert(result != SCIP_DIDNOTFIND || *nselectedcuts == 0); 216 217 ++cutsel->ncalls; 218 if( root ) 219 ++cutsel->nrootcalls; 220 221 if( result != SCIP_DIDNOTFIND && !initiallp ) 222 { 223 assert(0 <= ncuts); 224 assert(0 <= *nselectedcuts && *nselectedcuts <= ncuts); 225 226 if( root ) 227 { 228 cutsel->nrootcutsselected += *nselectedcuts; 229 cutsel->nrootcutsforced += nforcedcuts; 230 cutsel->nrootcutsfiltered += ncuts - *nselectedcuts; /*lint !e776*/ 231 } 232 else 233 { 234 cutsel->nlocalcutsselected += *nselectedcuts; 235 cutsel->nlocalcutsforced += nforcedcuts; 236 cutsel->nlocalcutsfiltered += ncuts - *nselectedcuts; /*lint !e776*/ 237 } 238 } 239 } 240 241 return SCIP_OKAY; 242 } 243 244 /** gets description of cut selector */ 245 const char* SCIPcutselGetDesc( 246 SCIP_CUTSEL* cutsel /**< cut selector */ 247 ) 248 { 249 assert(cutsel != NULL); 250 251 return cutsel->desc; 252 } 253 254 /** copies the given cut selector to a new scip */ 255 SCIP_RETCODE SCIPcutselCopyInclude( 256 SCIP_CUTSEL* cutsel, /**< cut selector */ 257 SCIP_SET* set /**< SCIP_SET of SCIP to copy to */ 258 ) 259 { 260 assert(cutsel != NULL); 261 assert(set != NULL); 262 assert(set->scip != NULL); 263 264 if( cutsel->cutselcopy != NULL ) 265 { 266 SCIPsetDebugMsg(set, "including cut selector %s in subscip %p\n", SCIPcutselGetName(cutsel), (void*)set->scip); 267 SCIP_CALL( cutsel->cutselcopy(set->scip, cutsel) ); 268 } 269 return SCIP_OKAY; 270 } 271 272 /** frees memory of cut selector */ 273 SCIP_RETCODE SCIPcutselFree( 274 SCIP_CUTSEL** cutsel, /**< pointer to cut selector data structure */ 275 SCIP_SET* set /**< global SCIP settings */ 276 ) 277 { 278 assert(cutsel != NULL); 279 280 if( *cutsel == NULL ) 281 return SCIP_OKAY; 282 283 assert(!(*cutsel)->initialized); 284 assert(set != NULL); 285 286 /* call destructor of cut selector */ 287 if( (*cutsel)->cutselfree != NULL ) 288 { 289 SCIP_CALL( (*cutsel)->cutselfree(set->scip, *cutsel) ); 290 } 291 292 /* free clocks */ 293 SCIPclockFree(&(*cutsel)->cutseltime); 294 SCIPclockFree(&(*cutsel)->setuptime); 295 296 BMSfreeMemoryArrayNull(&(*cutsel)->name); 297 BMSfreeMemoryArrayNull(&(*cutsel)->desc); 298 BMSfreeMemory(cutsel); 299 300 return SCIP_OKAY; 301 } 302 303 /** initializes cut selector */ 304 SCIP_RETCODE SCIPcutselInit( 305 SCIP_CUTSEL* cutsel, /**< cut selector */ 306 SCIP_SET* set /**< global SCIP settings */ 307 ) 308 { 309 assert(cutsel != NULL); 310 assert(set != NULL); 311 312 if( cutsel->initialized ) 313 { 314 SCIPerrorMessage("cut selector <%s> already initialized", cutsel->name); 315 return SCIP_INVALIDCALL; 316 } 317 318 if( set->misc_resetstat ) 319 { 320 SCIPclockReset(cutsel->setuptime); 321 SCIPclockReset(cutsel->cutseltime); 322 } 323 324 if( cutsel->cutselinit != NULL ) 325 { 326 /* start timing */ 327 SCIPclockStart(cutsel->setuptime, set); 328 329 SCIP_CALL( cutsel->cutselinit(set->scip, cutsel) ); 330 331 /* stop timing */ 332 SCIPclockStop(cutsel->setuptime, set); 333 } 334 335 cutsel->initialized = TRUE; 336 337 return SCIP_OKAY; 338 } 339 340 /** deinitializes cut selector */ 341 SCIP_RETCODE SCIPcutselExit( 342 SCIP_CUTSEL* cutsel, /**< cut selector */ 343 SCIP_SET* set /**< global SCIP settings */ 344 ) 345 { 346 assert(cutsel != NULL); 347 assert(set != NULL); 348 349 if( !cutsel->initialized ) 350 { 351 SCIPerrorMessage("cut selector <%s> not initialized", cutsel->name); 352 return SCIP_INVALIDCALL; 353 } 354 355 if( cutsel->cutselexit != NULL ) 356 { 357 /* start timing */ 358 SCIPclockStart(cutsel->setuptime, set); 359 360 SCIP_CALL( cutsel->cutselexit(set->scip, cutsel) ); 361 362 /* stop timing */ 363 SCIPclockStop(cutsel->setuptime, set); 364 } 365 cutsel->initialized = FALSE; 366 367 return SCIP_OKAY; 368 } 369 370 /** informs cut selector that the branch and bound process is being started */ 371 SCIP_RETCODE SCIPcutselInitsol( 372 SCIP_CUTSEL* cutsel, /**< cut selector */ 373 SCIP_SET* set /**< global SCIP settings */ 374 ) 375 { 376 assert(cutsel != NULL); 377 assert(set != NULL); 378 379 /* call solving process initialization method of cut selector */ 380 if( cutsel->cutselinitsol != NULL ) 381 { 382 /* start timing */ 383 SCIPclockStart(cutsel->setuptime, set); 384 385 SCIP_CALL( cutsel->cutselinitsol(set->scip, cutsel) ); 386 387 /* stop timing */ 388 SCIPclockStop(cutsel->setuptime, set); 389 } 390 391 return SCIP_OKAY; 392 } 393 394 /** informs cut selector that the branch and bound process is being started */ 395 SCIP_RETCODE SCIPcutselExitsol( 396 SCIP_CUTSEL* cutsel, /**< cut selector */ 397 SCIP_SET* set /**< global SCIP settings */ 398 ) 399 { 400 assert(cutsel != NULL); 401 assert(set != NULL); 402 403 /* call solving process deinitialization method of cut selector */ 404 if( cutsel->cutselexitsol != NULL ) 405 { 406 /* start timing */ 407 SCIPclockStart(cutsel->setuptime, set); 408 409 SCIP_CALL( cutsel->cutselexitsol(set->scip, cutsel) ); 410 411 /* stop timing */ 412 SCIPclockStop(cutsel->setuptime, set); 413 } 414 415 return SCIP_OKAY; 416 } 417 418 /** gets user data of cut selector */ 419 SCIP_CUTSELDATA* SCIPcutselGetData( 420 SCIP_CUTSEL* cutsel /**< cut selector */ 421 ) 422 { 423 assert(cutsel != NULL); 424 425 return cutsel->cutseldata; 426 } 427 428 /** sets user data of cut selector; user has to free old data in advance! */ 429 void SCIPcutselSetData( 430 SCIP_CUTSEL* cutsel, /**< cut selector */ 431 SCIP_CUTSELDATA* cutseldata /**< new cut selector user data */ 432 ) 433 { 434 assert(cutsel != NULL); 435 436 cutsel->cutseldata = cutseldata; 437 } 438 439 /** gets priority of cut selector */ 440 int SCIPcutselGetPriority( 441 SCIP_CUTSEL* cutsel /**< cut selector */ 442 ) 443 { 444 assert(cutsel != NULL); 445 446 return cutsel->priority; 447 } 448 449 /** enables or disables all clocks of @p cutsel, depending on the value of the flag */ 450 void SCIPcutselEnableOrDisableClocks( 451 SCIP_CUTSEL* cutsel, /**< the cut selector for which all clocks should be enabled or disabled */ 452 SCIP_Bool enable /**< should the clocks of the cut selector be enabled? */ 453 ) 454 { 455 assert(cutsel != NULL); 456 457 SCIPclockEnableOrDisable(cutsel->setuptime, enable); 458 SCIPclockEnableOrDisable(cutsel->cutseltime, enable); 459 } 460 461 462 /* new callback/method setter methods */ 463 464 /** sets copy method of cut selector */ 465 void SCIPcutselSetCopy( 466 SCIP_CUTSEL* cutsel, /**< cut selector */ 467 SCIP_DECL_CUTSELCOPY ((*cutselcopy)) /**< copy method of cut selector or NULL if you don't want to copy your plugin into sub-SCIPs */ 468 ) 469 { 470 assert(cutsel != NULL); 471 472 cutsel->cutselcopy = cutselcopy; 473 } 474 475 /** sets destructor method of cut selector */ 476 void SCIPcutselSetFree( 477 SCIP_CUTSEL* cutsel, /**< cut selector */ 478 SCIP_DECL_CUTSELFREE ((*cutselfree)) /**< destructor of cut selector */ 479 ) 480 { 481 assert(cutsel != NULL); 482 483 cutsel->cutselfree = cutselfree; 484 } 485 486 /** sets initialization method of cut selector */ 487 void SCIPcutselSetInit( 488 SCIP_CUTSEL* cutsel, /**< cut selector */ 489 SCIP_DECL_CUTSELINIT ((*cutselinit)) /**< initialize cut selector */ 490 ) 491 { 492 assert(cutsel != NULL); 493 494 cutsel->cutselinit = cutselinit; 495 } 496 497 /** sets deinitialization method of cut selector */ 498 void SCIPcutselSetExit( 499 SCIP_CUTSEL* cutsel, /**< cut selector */ 500 SCIP_DECL_CUTSELEXIT ((*cutselexit)) /**< deinitialize cut selector */ 501 ) 502 { 503 assert(cutsel != NULL); 504 505 cutsel->cutselexit = cutselexit; 506 } 507 508 /** sets solving process initialization method of cut selector */ 509 void SCIPcutselSetInitsol( 510 SCIP_CUTSEL* cutsel, /**< cut selector */ 511 SCIP_DECL_CUTSELINITSOL ((*cutselinitsol))/**< solving process initialization method of cut selector */ 512 ) 513 { 514 assert(cutsel != NULL); 515 516 cutsel->cutselinitsol = cutselinitsol; 517 } 518 519 /** sets solving process deinitialization method of cut selector */ 520 void SCIPcutselSetExitsol( 521 SCIP_CUTSEL* cutsel, /**< cut selector */ 522 SCIP_DECL_CUTSELEXITSOL ((*cutselexitsol))/**< solving process deinitialization method of cut selector */ 523 ) 524 { 525 assert(cutsel != NULL); 526 527 cutsel->cutselexitsol = cutselexitsol; 528 } 529 530 /** sets priority of cut selector */ 531 void SCIPcutselSetPriority( 532 SCIP_CUTSEL* cutsel, /**< cut selector */ 533 SCIP_SET* set, /**< global SCIP settings */ 534 int priority /**< new priority of the cut selector */ 535 ) 536 { 537 assert(cutsel != NULL); 538 assert(set != NULL); 539 540 cutsel->priority = priority; 541 set->cutselssorted = FALSE; 542 } 543 544 /** is cut selector initialized? */ 545 SCIP_Bool SCIPcutselIsInitialized( 546 SCIP_CUTSEL* cutsel /**< cut selector */ 547 ) 548 { 549 assert(cutsel != NULL); 550 551 return cutsel->initialized; 552 } 553 554 /** gets time in seconds used in this cut selector for setting up for next stages */ 555 SCIP_Real SCIPcutselGetSetupTime( 556 SCIP_CUTSEL* cutsel /**< cut selector */ 557 ) 558 { 559 assert(cutsel != NULL); 560 561 return SCIPclockGetTime(cutsel->setuptime); 562 } 563 564 /** gets time in seconds used in this cut selector */ 565 SCIP_Real SCIPcutselGetTime( 566 SCIP_CUTSEL* cutsel /**< cut selector */ 567 ) 568 { 569 assert(cutsel != NULL); 570 571 return SCIPclockGetTime(cutsel->cutseltime); 572 } 573 574 /** get number of times the cutselector was called */ 575 SCIP_Longint SCIPcutselGetNCalls( 576 SCIP_CUTSEL* cutsel /**< cut selector */ 577 ) 578 { 579 assert(cutsel != NULL); 580 581 return cutsel->ncalls; 582 } 583 584 /** get number of times the cutselector was called at the root */ 585 SCIP_Longint SCIPcutselGetNRootCalls( 586 SCIP_CUTSEL* cutsel /**< cut selector */ 587 ) 588 { 589 assert(cutsel != NULL); 590 591 return cutsel->nrootcalls; 592 } 593 594 /** get total number of cuts that were selected at the root */ 595 SCIP_Longint SCIPcutselGetNRootCuts( 596 SCIP_CUTSEL* cutsel /**< cut selector */ 597 ) 598 { 599 assert(cutsel != NULL); 600 601 return cutsel->nrootcutsselected; 602 } 603 604 /** get total number of forced cuts that were selected at the root */ 605 SCIP_Longint SCIPcutselGetNRootForcedCuts( 606 SCIP_CUTSEL* cutsel /**< cut selector */ 607 ) 608 { 609 assert(cutsel != NULL); 610 611 return cutsel->nrootcutsforced; 612 } 613 614 /** get total number of root cuts that were filtered */ 615 SCIP_Longint SCIPcutselGetNRootCutsFiltered( 616 SCIP_CUTSEL* cutsel /**< cut selector */ 617 ) 618 { 619 assert(cutsel != NULL); 620 621 return cutsel->nrootcutsfiltered; 622 } 623 624 /** get total number of local cuts that were selected */ 625 SCIP_Longint SCIPcutselGetNLocalCuts( 626 SCIP_CUTSEL* cutsel /**< cut selector */ 627 ) 628 { 629 assert(cutsel != NULL); 630 631 return cutsel->nlocalcutsselected; 632 } 633 634 /** get total number of forced local cuts that were selected */ 635 SCIP_Longint SCIPcutselGetNLocalForcedCuts( 636 SCIP_CUTSEL* cutsel /**< cut selector */ 637 ) 638 { 639 assert(cutsel != NULL); 640 641 return cutsel->nlocalcutsforced; 642 } 643 644 /** get total number of local cuts that were filtered */ 645 SCIP_Longint SCIPcutselGetNLocalCutsFiltered( 646 SCIP_CUTSEL* cutsel /**< cut selector */ 647 ) 648 { 649 assert(cutsel != NULL); 650 651 return cutsel->nlocalcutsfiltered; 652 } 653 654 /** compares two cut selectors w. r. to their priority */ 655 SCIP_DECL_SORTPTRCOMP(SCIPcutselComp) 656 { /*lint --e{715}*/ 657 return ((SCIP_CUTSEL*)elem2)->priority - ((SCIP_CUTSEL*)elem1)->priority; 658 } 659