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_event.c 26 * @ingroup OTHER_CFILES 27 * @brief public methods for event handler plugins and event handlers 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 "scip/debug.h" 46 #include "scip/event.h" 47 #include "scip/lp.h" 48 #include "scip/pub_message.h" 49 #include "scip/pub_var.h" 50 #include "scip/scip_event.h" 51 #include "scip/set.h" 52 #include "scip/struct_mem.h" 53 #include "scip/struct_scip.h" 54 #include "scip/struct_set.h" 55 #include "scip/var.h" 56 57 /** creates an event handler and includes it in SCIP 58 * 59 * @note method has all event handler callbacks as arguments and is thus changed every time a new 60 * callback is added in future releases; consider using SCIPincludeEventhdlrBasic() and setter functions 61 * if you seek for a method which is less likely to change in future releases 62 */ 63 SCIP_RETCODE SCIPincludeEventhdlr( 64 SCIP* scip, /**< SCIP data structure */ 65 const char* name, /**< name of event handler */ 66 const char* desc, /**< description of event handler */ 67 SCIP_DECL_EVENTCOPY ((*eventcopy)), /**< copy method of event handler or NULL if you don't want to copy your plugin into sub-SCIPs */ 68 SCIP_DECL_EVENTFREE ((*eventfree)), /**< destructor of event handler */ 69 SCIP_DECL_EVENTINIT ((*eventinit)), /**< initialize event handler */ 70 SCIP_DECL_EVENTEXIT ((*eventexit)), /**< deinitialize event handler */ 71 SCIP_DECL_EVENTINITSOL((*eventinitsol)), /**< solving process initialization method of event handler */ 72 SCIP_DECL_EVENTEXITSOL((*eventexitsol)), /**< solving process deinitialization method of event handler */ 73 SCIP_DECL_EVENTDELETE ((*eventdelete)), /**< free specific event data */ 74 SCIP_DECL_EVENTEXEC ((*eventexec)), /**< execute event handler */ 75 SCIP_EVENTHDLRDATA* eventhdlrdata /**< event handler data */ 76 ) 77 { 78 SCIP_EVENTHDLR* eventhdlr; 79 80 SCIP_CALL( SCIPcheckStage(scip, "SCIPincludeEventhdlr", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) ); 81 82 /* check whether event handler is already present */ 83 if( SCIPfindEventhdlr(scip, name) != NULL ) 84 { 85 SCIPerrorMessage("event handler <%s> already included.\n", name); 86 return SCIP_INVALIDDATA; 87 } 88 89 SCIP_CALL( SCIPeventhdlrCreate(&eventhdlr, scip->set, name, desc, 90 eventcopy, eventfree, eventinit, eventexit, eventinitsol, eventexitsol, eventdelete, eventexec, 91 eventhdlrdata) ); 92 SCIP_CALL( SCIPsetIncludeEventhdlr(scip->set, eventhdlr) ); 93 94 return SCIP_OKAY; 95 } 96 97 /** creates an event handler and includes it in SCIP with all its non-fundamental callbacks set 98 * to NULL; if needed, non-fundamental callbacks can be set afterwards via setter functions 99 * SCIPsetEventhdlrCopy(), SCIPsetEventhdlrFree(), SCIPsetEventhdlrInit(), SCIPsetEventhdlrExit(), 100 * SCIPsetEventhdlrInitsol(), SCIPsetEventhdlrExitsol(), and SCIPsetEventhdlrDelete() 101 * 102 * @note if you want to set all callbacks with a single method call, consider using SCIPincludeEventhdlr() instead 103 */ 104 SCIP_RETCODE SCIPincludeEventhdlrBasic( 105 SCIP* scip, /**< SCIP data structure */ 106 SCIP_EVENTHDLR** eventhdlrptr, /**< reference to an event handler, or NULL */ 107 const char* name, /**< name of event handler */ 108 const char* desc, /**< description of event handler */ 109 SCIP_DECL_EVENTEXEC ((*eventexec)), /**< execute event handler */ 110 SCIP_EVENTHDLRDATA* eventhdlrdata /**< event handler data */ 111 ) 112 { 113 SCIP_EVENTHDLR* eventhdlr; 114 115 SCIP_CALL( SCIPcheckStage(scip, "SCIPincludeEventhdlrBasic", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) ); 116 117 /* check whether event handler is already present */ 118 if( SCIPfindEventhdlr(scip, name) != NULL ) 119 { 120 SCIPerrorMessage("event handler <%s> already included.\n", name); 121 return SCIP_INVALIDDATA; 122 } 123 124 SCIP_CALL( SCIPeventhdlrCreate(&eventhdlr, scip->set, name, desc, 125 NULL, NULL, NULL, NULL, NULL, NULL, NULL, eventexec, 126 eventhdlrdata) ); 127 SCIP_CALL( SCIPsetIncludeEventhdlr(scip->set, eventhdlr) ); 128 129 if( eventhdlrptr != NULL ) 130 *eventhdlrptr = eventhdlr; 131 132 return SCIP_OKAY; 133 } 134 135 /** sets copy callback of the event handler */ 136 SCIP_RETCODE SCIPsetEventhdlrCopy( 137 SCIP* scip, /**< scip instance */ 138 SCIP_EVENTHDLR* eventhdlr, /**< event handler */ 139 SCIP_DECL_EVENTCOPY ((*eventcopy)) /**< copy callback of the event handler */ 140 ) 141 { 142 assert(scip != NULL); 143 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetEventhdlrCopy", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) ); 144 145 SCIPeventhdlrSetCopy(eventhdlr, eventcopy); 146 return SCIP_OKAY; 147 } 148 149 /** sets deinitialization callback of the event handler */ 150 SCIP_RETCODE SCIPsetEventhdlrFree( 151 SCIP* scip, /**< scip instance */ 152 SCIP_EVENTHDLR* eventhdlr, /**< event handler */ 153 SCIP_DECL_EVENTFREE ((*eventfree)) /**< deinitialization callback of the event handler */ 154 ) 155 { 156 assert(scip != NULL); 157 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetEventhdlrFree", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) ); 158 159 SCIPeventhdlrSetFree(eventhdlr, eventfree); 160 return SCIP_OKAY; 161 } 162 163 /** sets initialization callback of the event handler */ 164 SCIP_RETCODE SCIPsetEventhdlrInit( 165 SCIP* scip, /**< scip instance */ 166 SCIP_EVENTHDLR* eventhdlr, /**< event handler */ 167 SCIP_DECL_EVENTINIT ((*eventinit)) /**< initialize event handler */ 168 ) 169 { 170 assert(scip != NULL); 171 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetEventhdlrInit", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) ); 172 173 SCIPeventhdlrSetInit(eventhdlr, eventinit); 174 return SCIP_OKAY; 175 } 176 177 /** sets deinitialization callback of the event handler */ 178 SCIP_RETCODE SCIPsetEventhdlrExit( 179 SCIP* scip, /**< scip instance */ 180 SCIP_EVENTHDLR* eventhdlr, /**< event handler */ 181 SCIP_DECL_EVENTEXIT ((*eventexit)) /**< deinitialize event handler */ 182 ) 183 { 184 assert(scip != NULL); 185 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetEventhdlrExit", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) ); 186 187 SCIPeventhdlrSetExit(eventhdlr, eventexit); 188 return SCIP_OKAY; 189 } 190 191 /** sets solving process initialization callback of the event handler */ 192 SCIP_RETCODE SCIPsetEventhdlrInitsol( 193 SCIP* scip, /**< scip instance */ 194 SCIP_EVENTHDLR* eventhdlr, /**< event handler */ 195 SCIP_DECL_EVENTINITSOL((*eventinitsol)) /**< solving process initialization callback of event handler */ 196 ) 197 { 198 assert(scip != NULL); 199 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetEventhdlrInitsol", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) ); 200 201 SCIPeventhdlrSetInitsol(eventhdlr, eventinitsol); 202 return SCIP_OKAY; 203 } 204 205 /** sets solving process deinitialization callback of the event handler */ 206 SCIP_RETCODE SCIPsetEventhdlrExitsol( 207 SCIP* scip, /**< scip instance */ 208 SCIP_EVENTHDLR* eventhdlr, /**< event handler */ 209 SCIP_DECL_EVENTEXITSOL((*eventexitsol)) /**< solving process deinitialization callback of event handler */ 210 ) 211 { 212 assert(scip != NULL); 213 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetEventhdlrExitsol", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) ); 214 215 SCIPeventhdlrSetExitsol(eventhdlr, eventexitsol); 216 return SCIP_OKAY; 217 } 218 219 /** sets callback of the event handler to free specific event data */ 220 SCIP_RETCODE SCIPsetEventhdlrDelete( 221 SCIP* scip, /**< scip instance */ 222 SCIP_EVENTHDLR* eventhdlr, /**< event handler */ 223 SCIP_DECL_EVENTDELETE ((*eventdelete)) /**< free specific event data */ 224 ) 225 { 226 assert(scip != NULL); 227 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetEventhdlrDelete", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) ); 228 229 SCIPeventhdlrSetDelete(eventhdlr, eventdelete); 230 return SCIP_OKAY; 231 } 232 233 /** returns the event handler of the given name, or NULL if not existing */ 234 SCIP_EVENTHDLR* SCIPfindEventhdlr( 235 SCIP* scip, /**< SCIP data structure */ 236 const char* name /**< name of event handler */ 237 ) 238 { 239 assert(scip != NULL); 240 assert(scip->set != NULL); 241 assert(name != NULL); 242 243 return SCIPsetFindEventhdlr(scip->set, name); 244 } 245 246 /** returns the array of currently available event handlers */ 247 SCIP_EVENTHDLR** SCIPgetEventhdlrs( 248 SCIP* scip /**< SCIP data structure */ 249 ) 250 { 251 assert(scip != NULL); 252 assert(scip->set != NULL); 253 254 return scip->set->eventhdlrs; 255 } 256 257 /** returns the number of currently available event handlers */ 258 int SCIPgetNEventhdlrs( 259 SCIP* scip /**< SCIP data structure */ 260 ) 261 { 262 assert(scip != NULL); 263 assert(scip->set != NULL); 264 265 return scip->set->neventhdlrs; 266 } 267 268 /** catches a global (not variable or row dependent) event 269 * 270 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 271 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 272 * 273 * @pre This method can be called if @p scip is in one of the following stages: 274 * - \ref SCIP_STAGE_TRANSFORMING 275 * - \ref SCIP_STAGE_TRANSFORMED 276 * - \ref SCIP_STAGE_INITPRESOLVE 277 * - \ref SCIP_STAGE_PRESOLVING 278 * - \ref SCIP_STAGE_EXITPRESOLVE 279 * - \ref SCIP_STAGE_PRESOLVED 280 * - \ref SCIP_STAGE_INITSOLVE 281 * - \ref SCIP_STAGE_SOLVING 282 * - \ref SCIP_STAGE_SOLVED 283 * - \ref SCIP_STAGE_EXITSOLVE 284 * - \ref SCIP_STAGE_FREETRANS 285 */ 286 SCIP_RETCODE SCIPcatchEvent( 287 SCIP* scip, /**< SCIP data structure */ 288 SCIP_EVENTTYPE eventtype, /**< event type mask to select events to catch */ 289 SCIP_EVENTHDLR* eventhdlr, /**< event handler to process events with */ 290 SCIP_EVENTDATA* eventdata, /**< event data to pass to the event handler when processing this event */ 291 int* filterpos /**< pointer to store position of event filter entry, or NULL */ 292 ) 293 { 294 SCIP_CALL( SCIPcheckStage(scip, "SCIPcatchEvent", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 295 296 SCIP_CALL( SCIPeventfilterAdd(scip->eventfilter, scip->mem->probmem, scip->set, 297 eventtype, eventhdlr, eventdata, filterpos) ); 298 299 return SCIP_OKAY; 300 } 301 302 /** drops a global event (stops to track event) 303 * 304 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 305 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 306 * 307 * @pre This method can be called if @p scip is in one of the following stages: 308 * - \ref SCIP_STAGE_TRANSFORMING 309 * - \ref SCIP_STAGE_TRANSFORMED 310 * - \ref SCIP_STAGE_INITPRESOLVE 311 * - \ref SCIP_STAGE_PRESOLVING 312 * - \ref SCIP_STAGE_EXITPRESOLVE 313 * - \ref SCIP_STAGE_PRESOLVED 314 * - \ref SCIP_STAGE_INITSOLVE 315 * - \ref SCIP_STAGE_SOLVING 316 * - \ref SCIP_STAGE_SOLVED 317 * - \ref SCIP_STAGE_EXITSOLVE 318 * - \ref SCIP_STAGE_FREETRANS 319 */ 320 SCIP_RETCODE SCIPdropEvent( 321 SCIP* scip, /**< SCIP data structure */ 322 SCIP_EVENTTYPE eventtype, /**< event type mask of dropped event */ 323 SCIP_EVENTHDLR* eventhdlr, /**< event handler to process events with */ 324 SCIP_EVENTDATA* eventdata, /**< event data to pass to the event handler when processing this event */ 325 int filterpos /**< position of event filter entry returned by SCIPcatchEvent(), or -1 */ 326 ) 327 { 328 SCIP_CALL( SCIPcheckStage(scip, "SCIPdropEvent", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 329 330 SCIP_CALL( SCIPeventfilterDel(scip->eventfilter, scip->mem->probmem, scip->set, 331 eventtype, eventhdlr, eventdata, filterpos) ); 332 333 return SCIP_OKAY; 334 } 335 336 /** catches an objective value or domain change event on the given transformed variable 337 * 338 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 339 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 340 * 341 * @pre This method can be called if @p scip is in one of the following stages: 342 * - \ref SCIP_STAGE_TRANSFORMING 343 * - \ref SCIP_STAGE_TRANSFORMED 344 * - \ref SCIP_STAGE_INITPRESOLVE 345 * - \ref SCIP_STAGE_PRESOLVING 346 * - \ref SCIP_STAGE_EXITPRESOLVE 347 * - \ref SCIP_STAGE_PRESOLVED 348 * - \ref SCIP_STAGE_INITSOLVE 349 * - \ref SCIP_STAGE_SOLVING 350 * - \ref SCIP_STAGE_SOLVED 351 * - \ref SCIP_STAGE_EXITSOLVE 352 * - \ref SCIP_STAGE_FREETRANS 353 */ 354 SCIP_RETCODE SCIPcatchVarEvent( 355 SCIP* scip, /**< SCIP data structure */ 356 SCIP_VAR* var, /**< transformed variable to catch event for */ 357 SCIP_EVENTTYPE eventtype, /**< event type mask to select events to catch */ 358 SCIP_EVENTHDLR* eventhdlr, /**< event handler to process events with */ 359 SCIP_EVENTDATA* eventdata, /**< event data to pass to the event handler when processing this event */ 360 int* filterpos /**< pointer to store position of event filter entry, or NULL */ 361 ) 362 { 363 SCIP_CALL( SCIPcheckStage(scip, "SCIPcatchVarEvent", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 364 365 if( (eventtype & SCIP_EVENTTYPE_VARCHANGED) == 0 ) 366 { 367 SCIPerrorMessage("event does not operate on a single variable\n"); 368 return SCIP_INVALIDDATA; 369 } 370 371 if( SCIPvarIsOriginal(var) ) 372 { 373 SCIPerrorMessage("cannot catch events on original variable <%s>\n", SCIPvarGetName(var)); 374 return SCIP_INVALIDDATA; 375 } 376 377 SCIP_CALL( SCIPvarCatchEvent(var, scip->mem->probmem, scip->set, eventtype, eventhdlr, eventdata, filterpos) ); 378 379 return SCIP_OKAY; 380 } 381 382 /** drops an objective value or domain change event (stops to track event) on the given transformed variable 383 * 384 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 385 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 386 * 387 * @pre This method can be called if @p scip is in one of the following stages: 388 * - \ref SCIP_STAGE_TRANSFORMING 389 * - \ref SCIP_STAGE_TRANSFORMED 390 * - \ref SCIP_STAGE_INITPRESOLVE 391 * - \ref SCIP_STAGE_PRESOLVING 392 * - \ref SCIP_STAGE_EXITPRESOLVE 393 * - \ref SCIP_STAGE_PRESOLVED 394 * - \ref SCIP_STAGE_INITSOLVE 395 * - \ref SCIP_STAGE_SOLVING 396 * - \ref SCIP_STAGE_SOLVED 397 * - \ref SCIP_STAGE_EXITSOLVE 398 * - \ref SCIP_STAGE_FREETRANS 399 */ 400 SCIP_RETCODE SCIPdropVarEvent( 401 SCIP* scip, /**< SCIP data structure */ 402 SCIP_VAR* var, /**< transformed variable to drop event for */ 403 SCIP_EVENTTYPE eventtype, /**< event type mask of dropped event */ 404 SCIP_EVENTHDLR* eventhdlr, /**< event handler to process events with */ 405 SCIP_EVENTDATA* eventdata, /**< event data to pass to the event handler when processing this event */ 406 int filterpos /**< position of event filter entry returned by SCIPcatchVarEvent(), or -1 */ 407 ) 408 { 409 SCIP_CALL( SCIPcheckStage(scip, "SCIPdropVarEvent", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 410 411 if( SCIPvarIsOriginal(var) ) 412 { 413 SCIPerrorMessage("cannot drop events on original variable <%s>\n", SCIPvarGetName(var)); 414 return SCIP_INVALIDDATA; 415 } 416 417 SCIP_CALL( SCIPvarDropEvent(var, scip->mem->probmem, scip->set, eventtype, eventhdlr, eventdata, filterpos) ); 418 419 return SCIP_OKAY; 420 } 421 422 /** catches a row coefficient, constant, or side change event on the given row 423 * 424 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 425 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 426 * 427 * @pre This method can be called if @p scip is in one of the following stages: 428 * - \ref SCIP_STAGE_TRANSFORMING 429 * - \ref SCIP_STAGE_TRANSFORMED 430 * - \ref SCIP_STAGE_INITPRESOLVE 431 * - \ref SCIP_STAGE_PRESOLVING 432 * - \ref SCIP_STAGE_EXITPRESOLVE 433 * - \ref SCIP_STAGE_PRESOLVED 434 * - \ref SCIP_STAGE_INITSOLVE 435 * - \ref SCIP_STAGE_SOLVING 436 * - \ref SCIP_STAGE_SOLVED 437 * - \ref SCIP_STAGE_EXITSOLVE 438 * - \ref SCIP_STAGE_FREETRANS 439 */ 440 SCIP_RETCODE SCIPcatchRowEvent( 441 SCIP* scip, /**< SCIP data structure */ 442 SCIP_ROW* row, /**< linear row to catch event for */ 443 SCIP_EVENTTYPE eventtype, /**< event type mask to select events to catch */ 444 SCIP_EVENTHDLR* eventhdlr, /**< event handler to process events with */ 445 SCIP_EVENTDATA* eventdata, /**< event data to pass to the event handler when processing this event */ 446 int* filterpos /**< pointer to store position of event filter entry, or NULL */ 447 ) 448 { 449 SCIP_CALL( SCIPcheckStage(scip, "SCIPcatchRowEvent", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 450 451 if( (eventtype & SCIP_EVENTTYPE_ROWCHANGED) == 0 ) 452 { 453 SCIPerrorMessage("event does not operate on a single row\n"); 454 return SCIP_INVALIDDATA; 455 } 456 457 SCIP_CALL( SCIProwCatchEvent(row, scip->mem->probmem, scip->set, eventtype, eventhdlr, eventdata, filterpos) ); 458 459 return SCIP_OKAY; 460 } 461 462 /** drops a row coefficient, constant, or side change event (stops to track event) on the given row 463 * 464 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 465 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 466 * 467 * @pre This method can be called if @p scip is in one of the following stages: 468 * - \ref SCIP_STAGE_TRANSFORMING 469 * - \ref SCIP_STAGE_TRANSFORMED 470 * - \ref SCIP_STAGE_INITPRESOLVE 471 * - \ref SCIP_STAGE_PRESOLVING 472 * - \ref SCIP_STAGE_EXITPRESOLVE 473 * - \ref SCIP_STAGE_PRESOLVED 474 * - \ref SCIP_STAGE_INITSOLVE 475 * - \ref SCIP_STAGE_SOLVING 476 * - \ref SCIP_STAGE_SOLVED 477 * - \ref SCIP_STAGE_EXITSOLVE 478 * - \ref SCIP_STAGE_FREETRANS 479 */ 480 SCIP_RETCODE SCIPdropRowEvent( 481 SCIP* scip, /**< SCIP data structure */ 482 SCIP_ROW* row, /**< linear row to drop event for */ 483 SCIP_EVENTTYPE eventtype, /**< event type mask of dropped event */ 484 SCIP_EVENTHDLR* eventhdlr, /**< event handler to process events with */ 485 SCIP_EVENTDATA* eventdata, /**< event data to pass to the event handler when processing this event */ 486 int filterpos /**< position of event filter entry returned by SCIPcatchVarEvent(), or -1 */ 487 ) 488 { 489 SCIP_CALL( SCIPcheckStage(scip, "SCIPdropRowEvent", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 490 491 SCIP_CALL( SCIProwDropEvent(row, scip->mem->probmem, scip->set, eventtype, eventhdlr, eventdata, filterpos) ); 492 493 return SCIP_OKAY; 494 } 495