Scippy

UG

Ubiquity Generator framework

scipParaObjCommPointHdlr.cpp
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the program and software framework */
4/* UG --- Ubquity Generator Framework */
5/* */
6/* Copyright Written by Yuji Shinano <shinano@zib.de>, */
7/* Copyright (C) 2021-2025 by Zuse Institute Berlin, */
8/* licensed under LGPL version 3 or later. */
9/* Commercial licenses are available through <licenses@zib.de> */
10/* */
11/* This code is free software; you can redistribute it and/or */
12/* modify it under the terms of the GNU Lesser General Public License */
13/* as published by the Free Software Foundation; either version 3 */
14/* of the License, or (at your option) any later version. */
15/* */
16/* This program is distributed in the hope that it will be useful, */
17/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
18/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
19/* GNU Lesser General Public License for more details. */
20/* */
21/* You should have received a copy of the GNU Lesser General Public License */
22/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
23/* */
24/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
25
26/**@file scipParaObjCommPointHdlr.cpp
27 * @brief Event handlr for communication point.
28 * @author Yuji Shinano
29 *
30 *
31 *
32 */
33
34/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
35
36#include <cassert>
37#include <cmath>
38#include <string>
39#include <sstream>
40#include <iostream>
41
43#include "scip/struct_nodesel.h"
44#include "scip/tree.h"
45#ifdef UG_DEBUG_SOLUTION
46#ifndef WITH_DEBUG_SOLUTION
47#define WITH_DEBUG_SOLUTION
48#endif
49#include "scip/debug.h"
50#endif
51
52#include "scipParaSolution.h"
54
55using namespace ParaSCIP;
56
57void
58ScipParaObjCommPointHdlr::processNewSolution(
59 SCIP* scip, /**< SCIP data structure */
60 SCIP_EVENT* event /**< event to process */
61 )
62{
63 SCIP_SOL *sol = SCIPeventGetSol(event);
64 int nVars = SCIPgetNOrigVars(scip);
65 SCIP_VAR **vars = SCIPgetOrigVars(scip);
66 SCIP_Real *vals = new SCIP_Real[nVars];
67 SCIP_CALL_ABORT( SCIPgetSolVals(scip, sol, nVars, vars, vals) );
68
69 // SCIP_CALL_ABORT( SCIPprintSol(scip,sol,NULL, FALSE) );
70 SCIP_Bool feasible;
71 SCIP_CALL_ABORT( SCIPcheckSolOrig(scip,sol,&feasible,1,1 ) );
72
73 DEF_SCIP_PARA_COMM( scipParaComm, paraComm);
74
76 {
77 SCIP_VAR **varsInOrig = new SCIP_VAR*[nVars];
78 SCIP_Real *valsInOrig = new SCIP_Real[nVars]();
79 int nVarsInOrig = 0;
80 for( int i = 0; i < nVars; i++ )
81 {
82 if( scipParaSolver->getOriginalIndex(SCIPvarGetIndex(vars[i])) >= 0 )
83 {
84 varsInOrig[nVarsInOrig] = vars[i];
85 valsInOrig[nVarsInOrig] = vals[i];
86 nVarsInOrig++;
87 }
88 }
89
91 scipParaComm->createScipParaSolution(
93 SCIPgetSolOrigObj(scip, sol),
94 nVarsInOrig,
95 varsInOrig,
96 valsInOrig
97 )
98 );
99 delete [] varsInOrig;
100 delete [] valsInOrig;
101 }
102 else
103 {
105 scipParaComm->createScipParaSolution(
107 SCIPgetSolOrigObj(scip, sol),
108 nVars,
109 vars,
110 vals
111 )
112 );
113 // std::cout << "*** event handler ***" << std::endl;
114 // SCIP_CALL_ABORT( SCIPprintSol(scip, sol, NULL, FALSE) );
115 // scipParaSolver->checkVarsAndIndex("***found solution***",scip);
116 }
117 delete [] vals;
118}
119
120SCIP_RETCODE
122 SCIP* scip, /**< SCIP data structure */
123 SCIP_EVENTHDLR* eventhdlr, /**< the event handler itself */
124 SCIP_EVENT* event, /**< event to process */
125 SCIP_EVENTDATA* eventdata /**< user data for the event */
126 )
127{
128 DEF_SCIP_PARA_COMM( scipParaComm, paraComm);
130 {
131 scipParaComm->lockInterruptMsg();
132 }
133 assert(eventhdlr != NULL);
134 assert(strcmp(SCIPeventhdlrGetName(eventhdlr), "ScipParaObjCommPointHdlr") == 0);
135 assert(event != NULL);
136#ifdef SCIP_EVENTTYPE_COMM
137 assert(SCIPeventGetType(event) &
138 ( SCIP_EVENTTYPE_GBDCHANGED |
139 SCIP_EVENTTYPE_BOUNDTIGHTENED |
140 SCIP_EVENTTYPE_LPEVENT |
141 SCIP_EVENTTYPE_ROWEVENT |
142 // SCIP_EVENTTYPE_NODEFOCUSED |
143 SCIP_EVENTTYPE_NODEEVENT |
144 SCIP_EVENTTYPE_BESTSOLFOUND |
145 SCIP_EVENTTYPE_COMM
146 )
147 );
148#else
149 assert(SCIPeventGetType(event) &
150 ( SCIP_EVENTTYPE_GBDCHANGED |
151 SCIP_EVENTTYPE_BOUNDTIGHTENED |
152 SCIP_EVENTTYPE_LPEVENT |
153 SCIP_EVENTTYPE_ROWEVENT |
154 // SCIP_EVENTTYPE_NODEFOCUSED |
155 SCIP_EVENTTYPE_NODEEVENT |
156 SCIP_EVENTTYPE_BESTSOLFOUND
157 )
158 );
159#endif
160
161#if SCIP_VERSION == 211 && SCIP_SUBVERSION == 0
162 if( SCIPgetStage(scip) >= SCIP_STAGE_FREESOLVE )
163#else
164 if( SCIPgetStage(scip) >= SCIP_STAGE_EXITSOLVE )
165#endif
166 {
168 {
169 scipParaComm->unlockInterruptMsg();
170 }
171 return SCIP_OKAY;
172 }
173
174 double detTime = -1.0;
175 SCIP *subScip = 0;
176 if( cloned )
177 {
178 subScip = scip;
179 scip = originalScip;
180 }
181
183 {
186 {
187 if( SCIPeventGetType(event) == SCIP_EVENTTYPE_FIRSTLPSOLVED )
188 {
189 SCIP_Longint totalLpIter = 0;
190 if( cloned )
191 {
192 totalLpIter = SCIPgetNLPIterations(subScip);
193 }
194 else
195 {
196 totalLpIter = SCIPgetNLPIterations(scip);
197 }
198 SCIP_Longint lpIter = totalLpIter - previousLpIter;
199 if( lpIter < 0 )
200 {
201 lpIter = totalLpIter;
202 }
204 previousLpIter = totalLpIter;
205
206 }
207 else if ( SCIPeventGetType(event) == SCIP_EVENTTYPE_LPSOLVED )
208 {
209 SCIP_Longint totalLpIter = 0;
210 if( cloned )
211 {
212 totalLpIter = SCIPgetNLPIterations(subScip);
213 }
214 else
215 {
216 totalLpIter = SCIPgetNLPIterations(scip);
217 }
218 SCIP_Longint lpIter = totalLpIter - previousLpIter;
219 if( lpIter < 0 )
220 {
221 lpIter = totalLpIter;
222 }
224 previousLpIter = totalLpIter;
225 }
226 else if ( SCIPeventGetType(event) == SCIP_EVENTTYPE_BESTSOLFOUND
227 || SCIPeventGetType(event) == SCIP_EVENTTYPE_NODEFOCUSED )
228 {
229 }
230 else
231 {
233 }
234 }
235 else
236 {
237 if ( SCIPeventGetType(event) != SCIP_EVENTTYPE_BESTSOLFOUND
238 && SCIPeventGetType(event) != SCIP_EVENTTYPE_NODEFOCUSED )
239 {
241 }
242 }
244 if( ( detTime - scipParaSolver->getPreviousCommTime() )
246 {
247 if( SCIPeventGetType(event) == SCIP_EVENTTYPE_BESTSOLFOUND )
248 {
249 if( cloned )
250 {
252 {
253 scipParaComm->unlockInterruptMsg();
254 }
255 return SCIP_OKAY;
256 }
257 else
258 {
259 processNewSolution(scip, event);
260 }
261 }
262 }
263 do
264 {
267 }
268 else
269 {
270 if( SCIPeventGetType(event) == SCIP_EVENTTYPE_BESTSOLFOUND )
271 {
272 if( cloned )
273 {
275 {
276 scipParaComm->unlockInterruptMsg();
277 }
278 return SCIP_OKAY;
279 }
280 else
281 {
282 processNewSolution(scip, event);
283 }
284 }
285 }
286
287 //
288 // the following interrupt routine moved from the inside of the following if clause
289 // and scipParaSolver->iReceiveMessages() before solution sending is also removed (comment out)
290 //
291 /*********************************************************************************************
292 * check if there are messages: this is the first thing to do for communication *
293 ********************************************************************************************/
296 {
297 scipParaComm->unlockInterruptMsg();
298 }
299
302 {
303 return SCIP_OKAY;
304 }
305
307 SCIPgetStage(scip) != SCIP_STAGE_PRESOLVING
308 && SCIPgetStage(scip) != SCIP_STAGE_INITSOLVE )
309 {
310 if( !cloned
311 // && SCIPeventGetType(event) != SCIP_EVENTTYPE_BOUNDTIGHTENED
312 // && SCIPeventGetType(event) != SCIP_EVENTTYPE_ROWDELETEDLP
313 &&
314 ( SCIPeventGetType(event) & (SCIP_EVENTTYPE_NODEEVENT | SCIP_EVENTTYPE_LPEVENT)
315 )
316 )
317 {
318 /** set cutoff value */
319 if( scipParaSolver->getGlobalBestIncumbentValue() < SCIPgetObjlimit(scip) )
320 {
322 // SCIP_CALL_ABORT( SCIPsetObjlimit(scip, scipParaSolver->getGlobalBestIncumbentValue()) );
323 }
324 // scipParaSolver->globalIncumbnetValueIsReflected();
325 // std::cout << "***** R." << scipParaSolver->getRank() << ", in event = " << SCIPeventGetType(event) << std::endl;
326 if( !interrupting && SCIPisObjIntegral(scip) )
327 {
328 if( SCIPfeasCeil(scip, dynamic_cast<UG::BbParaNode *>(scipParaSolver->getCurrentNode())->getDualBoundValue())
330 {
331#ifdef UG_DEBUG_SOLUTION
332 if( SCIPdebugSolIsEnabled(scip) )
333 {
334 throw "Optimal solution going to be lost!";
335 }
336#endif
337 SCIP_CALL_ABORT( SCIPinterruptSolve(scip) );
338 interrupting = true;
339 // std::cout << "***** R." << scipParaSolver->getRank() << "Interrupted!" << std::endl;
340 }
341 }
342 }
343 }
344
347 // && SCIPgetStage(scip) != SCIP_STAGE_PRESOLVING
348 // && SCIPgetStage(scip) != SCIP_STAGE_INITSOLVE
349 && (SCIPeventGetType(event) & SCIP_EVENTTYPE_GBDCHANGED )
350 && (SCIPvarGetStatus(SCIPeventGetVar(event)) != SCIP_VARSTATUS_LOOSE )
351 && (SCIPvarGetStatus(SCIPeventGetVar(event)) != SCIP_VARSTATUS_AGGREGATED )
352 )
353 {
354 // assert( scipParaSolver->getCurrentNode()->isRootTask() ); /// This is fail for racing at restart
355 SCIP_BOUNDTYPE boundtype;
356 SCIP_Var *var = SCIPeventGetVar(event);
357 switch( SCIPeventGetType(event) )
358 {
359 case SCIP_EVENTTYPE_GLBCHANGED:
360 boundtype = SCIP_BOUNDTYPE_LOWER;
361 break;
362 case SCIP_EVENTTYPE_GUBCHANGED:
363 boundtype = SCIP_BOUNDTYPE_UPPER;
364 break;
365 default:
366 SCIPABORT();
367 return SCIP_ERROR;
368 }
369 SCIP_Real newbound = SCIPeventGetNewbound(event);
370 SCIP_Real constant = 0.0;
371 SCIP_Real scalar = 1.0;
372 SCIP_CALL_ABORT( SCIPvarGetOrigvarSum(&var, &scalar, &constant) );
373 if( var != NULL )
374 {
375 assert(SCIPvarIsOriginal(var));
376 int index = SCIPvarGetIndex(var);
377 boundtype = scalar < 0.0 ? (SCIP_BOUNDTYPE)(1 - boundtype) : boundtype;
378 newbound = (newbound - constant) / scalar;
380 {
381 index = scipParaSolver->getProbIndex(index);
382 }
383 if( index < scipParaSolver->getNOrgVars() )
384 {
385 if( boundtype == SCIP_BOUNDTYPE_LOWER )
386 {
387 if( SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS )
388 {
389 assert( SCIPisFeasIntegral(scip, newbound) );
390 newbound = SCIPfeasCeil(scip, newbound);
391 }
392 #ifdef UG_DEBUG_SOLUTION
393 SCIP_Real solvalue = 0.0;
394 SCIP_CALL(SCIPdebugGetSolVal(scip,var, &solvalue));
395 std::cout << "Sender side SolValue: " << SCIPvarGetName(var) << " = " << solvalue << std::endl;
396 std::cout << "Sender side (SCIP_BOUNDTYPE_LOWER): " << SCIPvarGetName(var) << " = " << newbound << std::endl;
397 SCIP_CALL_ABORT( SCIPdebugCheckLbGlobal(scip,var,newbound) );
398 #endif
399 // assert( SCIPisLE(scip,scipParaSolver->getOrgVarLb(index), newbound) &&
400 assert( SCIPisGE(scip,scipParaSolver->getOrgVarUb(index), newbound) );
401 if( SCIPisGT(scip, newbound, scipParaSolver->getTightenedVarLb(index) ) ) // &&
402 // SCIPisLE(scip, newbound, scipParaSolver->getTightenedVarUb(index) ) ) // just for safety
403 {
404 // this assertion may not be hold
405 // assert( SCIPisLE(scip,scipParaSolver->getTightenedVarLb(index), newbound) &&
406 // SCIPisGE(scip,scipParaSolver->getTightenedVarUb(index), newbound) );
407 scipParaSolver->setTightenedVarLb(index, newbound);
408 int orgIndex = SCIPvarGetIndex(var);
410 {
411 orgIndex = scipParaSolver->getOriginalIndex(orgIndex);
412 }
415 orgIndex >= 0 && orgIndex < scipParaSolver->getNOrgVars() ) )
416 {
418 paraComm->send((void *)&orgIndex, 1, UG::ParaINT, 0, UG::TagLbBoundTightenedIndex )
419 );
421 paraComm->send((void *)&newbound, 1, UG::ParaDOUBLE, 0, UG::TagLbBoundTightenedBound )
422 );
423 /*
424 std::cout << "Rank " << paraComm->getRank()
425 << ": send tightened lower bond. idx = " << index
426 << ", bound = " << newbound
427 << ", var status = " << SCIPvarGetStatus(SCIPeventGetVar(event))
428 << std::endl; */
429 }
430 }
431 }
432 else
433 {
434 if( SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS )
435 {
436 assert( SCIPisFeasIntegral(scip, newbound) );
437 newbound = SCIPfeasFloor(scip, newbound);
438 }
439 #ifdef UG_DEBUG_SOLUTION
440 SCIP_Real solvalue = 0.0;
441 SCIP_CALL(SCIPdebugGetSolVal(scip,var, &solvalue));
442 std::cout << "Sender side SolValue: " << SCIPvarGetName(var) << " = " << solvalue << std::endl;
443 std::cout << "Sender side (SCIP_BOUNDTYPE_UPPER): " << SCIPvarGetName(var) << " = " << newbound << std::endl;
444 SCIP_CALL_ABORT( SCIPdebugCheckUbGlobal(scip,var,newbound) );
445 #endif
446 assert( SCIPisLE(scip,scipParaSolver->getOrgVarLb(index), newbound) );
447 // && SCIPisGE(scip,scipParaSolver->getOrgVarUb(index), newbound) );
448 if( SCIPisLT(scip, newbound, scipParaSolver->getTightenedVarUb(index) ) ) // &&
449 // SCIPisGE(scip, newbound, scipParaSolver->getTightenedVarLb(index) ) ) // just for safety
450 {
451 // This asertion may not be hold
452 // assert( SCIPisLE(scip,scipParaSolver->getTightenedVarLb(index), newbound) &&
453 // SCIPisGE(scip,scipParaSolver->getTightenedVarUb(index), newbound) );
454 scipParaSolver->setTightenedVarUb(index, newbound);
455 int orgIndex = SCIPvarGetIndex(var);
457 {
458 orgIndex = scipParaSolver->getOriginalIndex(orgIndex);
459 }
461 paraComm->send((void *)&orgIndex, 1, UG::ParaINT, 0, UG::TagUbBoundTightenedIndex )
462 );
464 paraComm->send((void *)&newbound, 1, UG::ParaDOUBLE, 0, UG::TagUbBoundTightenedBound )
465 );
466 /*
467 std::cout << "Rank " << paraComm->getRank()
468 << ": send tightened upper bond. idx = " << index
469 << ", bound = " << newbound
470 << ", var status = " << SCIPvarGetStatus(SCIPeventGetVar(event))
471 << std::endl; */
472 }
473 }
474 }
475 }
476 }
477
478
479 /*********************************************************************************************
480 * update solution. This have to do right after receiving message *
481 ********************************************************************************************/
482 scipParaSolver->sendLocalSolution(); // if local solution exists, it should be sent right after iReceiveMessages
483 if( !cloned )
484 {
485 // paraComm->lockApp();
487 // paraComm->unlockApp();
488 }
494 )
495 {
496 if( !interrupting )
497 {
498 if( cloned )
499 {
500 if( SCIPgetStage(subScip) != SCIP_STAGE_INITSOLVE )
501 {
502 SCIP_CALL_ABORT( SCIPinterruptSolve(subScip) );
503 interrupting = true;
504 }
505 }
506 else
507 {
508 if( SCIPgetStage(scip) != SCIP_STAGE_INITSOLVE )
509 {
513 {
514 #ifdef UG_DEBUG_SOLUTION
516 {
517 std::cout << "racing stage = " << scipParaSolver->isRacingStage() << ", winner = " << scipParaSolver->isRacingWinner() << std::endl;
518 if( SCIPdebugSolIsEnabled(scip) )
519 {
520 throw "Optimal solution going to be lost!";
521 }
522 }
523 SCIPdebugSolDisable(scip);
524 std::cout << "R." << paraComm->getRank() << ": disable debug, this solver is interrupted." << std::endl;
525 #endif
526 SCIP_CALL_ABORT( SCIPinterruptSolve(scip) );
527 interrupting = true;
528 }
529 }
530 }
531 return SCIP_OKAY;
532 }
535 ( !scipParaSolver->isRampUp() ) )
536 {
537 return SCIP_OKAY;
538 }
539 }
540
541 if( (!cloned ) &&
544 {
545 int maxrestarts = 0;
546 SCIP_CALL( SCIPgetIntParam(scip, "presolving/maxrestarts", &maxrestarts) );
547 if( SCIPgetNRuns( scip ) >= maxrestarts )
548 {
550 {
553 );
554 }
556 }
557 /*
558 else
559 {
560 if( scipParaSolver->isRacingStage() )
561 {
562 return SCIP_OKAY; // during racing stage, just keep running for all restart
563 }
564 }
565 */
566 }
567
568 SCIP_Longint nNodes = 0;
569 if( SCIPgetStage(scip) != SCIP_STAGE_PRESOLVING
570 && SCIPgetStage(scip) != SCIP_STAGE_INITSOLVE
571 && (!scipParaSolver->isCollectingModeProhibited() ) ) // restarting is considered as root node process in ug[SCIP,*])
572 {
573 nNodes = SCIPgetNTotalNodes(scip);
574 }
575
576 if( previousNNodesSolved == nNodes
577 // && (!scipParaSolver->isCollectingModeProhibited() ) ) // setting cutoff value works well
578 || scipParaSolver->isCollectingModeProhibited() ) // setting cutoff value works well
579 {
587 )
588 {
591 }
592
593 return SCIP_OKAY;
594 }
595 previousNNodesSolved = nNodes;
596
597 /** if root node is solved, set root node time */
598 if( nNodes == 2 && SCIPgetNNodes(scip) == 2 )
599 {
600 /** when a problem is solved at root,
601 * its root node process time is set on paraSolver main loop */
606 )
607 {
608 if( ( SCIPgetDualbound(scip) - dynamic_cast<UG::BbParaNode *>(scipParaSolver->getCurrentNode())->getDualBoundValue() )
610 {
612 }
613 }
615 SCIPgetDualbound(scip) <
617 {
618 if( !interrupting )
619 {
620 if( cloned )
621 {
622 SCIP_CALL_ABORT( SCIPinterruptSolve(subScip) );
623 }
624 else
625 {
626 dynamic_cast<UG::BbParaNode *>(scipParaSolver->getCurrentNode())->setMergingStatus(3); // cannot be merged
627 SCIP_CALL_ABORT( SCIPinterruptSolve(scip) );
628 }
629 interrupting = true;
630 }
631 return SCIP_OKAY;
632 }
633 }
634
635 /*****************************************************************************
636 * sends solver state message if it is necessary, that is, *
637 * notification interval time has been passed from the previous notification *
638 *****************************************************************************/
639 double bestDualBoundValue = -SCIPinfinity(scip);
640 if( SCIPgetStage(scip) == SCIP_STAGE_TRANSFORMED ||
641 SCIPgetStage(scip) == SCIP_STAGE_PRESOLVING ||
642 SCIPgetStage(scip) == SCIP_STAGE_INITSOLVE
643 )
644 {
645 bestDualBoundValue = dynamic_cast<UG::BbParaNode *>(scipParaSolver->getCurrentNode())->getDualBoundValue();
646 }
647 else
648 {
649 bestDualBoundValue = std::max(SCIPgetDualbound(scip), dynamic_cast<UG::BbParaNode *>(scipParaSolver->getCurrentNode())->getDualBoundValue());
650 }
651
652 /************************************************************
653 * check if global best incumbent value is updated or not. *
654 * if it is updated, set cutoff value *
655 ************************************************************/
656// if( scipParaSolver->isGlobalIncumbentUpdated() &&
657// SCIPgetStage(scip) != SCIP_STAGE_PRESOLVING
658// && SCIPgetStage(scip) != SCIP_STAGE_INITSOLVE )
659// {
660// if( !cloned
661// && SCIPeventGetType(event) != SCIP_EVENTTYPE_BOUNDTIGHTENED
662// )
663// {
664// /** set cutoff value */
665// // if( scipParaSolver->getGlobalBestIncumbentValue() > bestDualBoundValue )
666// // {
667// SCIP_CALL_ABORT( SCIPsetObjlimit(scip, scipParaSolver->getGlobalBestIncumbentValue()) );
668// // }
669// scipParaSolver->globalIncumbnetValueIsReflected();
670//std::cout << "R." << paraComm->getRank() << " ** UPDATED **" << std::endl;
671// }
672// }
673
674 if( scipParaSolver->getGlobalBestIncumbentValue() < bestDualBoundValue )
675 {
676 if( !interrupting )
677 {
678 if( cloned )
679 {
680 if( SCIPgetStage(subScip) != SCIP_STAGE_INITSOLVE )
681 {
682 SCIP_CALL_ABORT( SCIPinterruptSolve(subScip) );
683 interrupting = true;
684 }
685 }
686 else
687 {
688 if( SCIPgetStage(scip) != SCIP_STAGE_INITSOLVE )
689 {
690#ifdef UG_DEBUG_SOLUTION
692 {
693 std::cout << "racing stage = " << scipParaSolver->isRacingStage() << ", winner = " << scipParaSolver->isRacingWinner() << std::endl;
694 if( SCIPdebugSolIsEnabled(scip) )
695 {
696 throw "Optimal solution going to be lost!";
697 }
698 }
699 SCIPdebugSolDisable(scip);
700 std::cout << "R." << paraComm->getRank() << ": disable debug, this solver is interrupted." << std::endl;
701#endif
702 SCIP_CALL_ABORT( SCIPinterruptSolve(scip) );
703 interrupting = true;
704 }
705 }
706 }
707 return SCIP_OKAY;
708 }
709
710 if( scipParaSolver->isCollectingModeProhibited() || nNodes < 2 ) // do not have to send status to LC yet.
711 {
712 return SCIP_OKAY;
713 }
714
716 {
717 needToSendNode = true;
718 }
719
720 if ( needToSendNode
722 || nNodes == 2
724 {
725 if( bestDualBoundValue >= -1e+10 && (!interrupting) ) // only after some dual bound value is computed, notify its status
726 {
727 int nNodesLeft = 0;
728 if( SCIPgetStage(scip) != SCIP_STAGE_TRANSFORMED &&
729 SCIPgetStage(scip) != SCIP_STAGE_PRESOLVING &&
730 SCIPgetStage(scip) != SCIP_STAGE_INITSOLVE )
731 {
732 nNodesLeft = SCIPgetNNodesLeft(scip);
733 }
734 scipParaSolver->sendSolverState(nNodes, nNodesLeft, bestDualBoundValue, detTime);
737 nNodes > 2 )
738 {
739 dynamic_cast<UG::BbParaNode *>(scipParaSolver->getCurrentNode())->setMergingStatus(3); // cannot be merged: this is a dummy status
740 SCIP_CALL_ABORT( SCIPinterruptSolve(scip) );
741 return SCIP_OKAY;
742 }
744 && ( !needToSendNode )
750 SCIPgetDepth(scip) > scipParaSolver->getAggresivePresolvingDepth() )
751 )
752 {
755 }
756 }
757 }
758
761 ( nNodes < scipParaSolver->getNStopSolvingMode() ) &&
762 ( bestDualBoundValue - scipParaSolver->getLcBestDualBoundValue() ) > 0.0 &&
763 REALABS( ( bestDualBoundValue - std::max(scipParaSolver->getLcBestDualBoundValue(),-SCIPinfinity(scip) ) )
765 {
767 {
771 {
772 scipParaSolver->sendAnotherNodeRequest(bestDualBoundValue); // throw away nodes
773 }
774 }
776 {
778 {
780 }
781 }
782 else
783 {
784 THROW_LOGICAL_ERROR2("Invalid big dual gap handling strategy. startegy = ",
786 }
787 }
788
791 ( bestDualBoundValue - scipParaSolver->getLcBestDualBoundValue() ) > 0.0 &&
792 REALABS( ( bestDualBoundValue - scipParaSolver->getLcBestDualBoundValue() )
795 {
797 {
800 nNodes < scipParaSolver->getNStopSolvingMode() ) )
801 {
802 scipParaSolver->sendAnotherNodeRequest(bestDualBoundValue); // throw away nodes
803 }
804 }
806 {
808 {
810 }
811 }
812 else
813 {
814 THROW_LOGICAL_ERROR2("Invalid big dual gap handling strategy. startegy = ",
816 }
817 }
818 /*******************************************************************
819 * if new ParaNode was received or Interrupt message was received, *
820 * stop solving the current ParaNode *
821 ******************************************************************/
822 if( cloned ||
823 ( SCIPeventGetType(event) != SCIP_EVENTTYPE_NODEFOCUSED
825 {
826 return SCIP_OKAY; // process until SCIP_EVENTTYPE_NODEFOCUSED event
827 }
828
832 )
833 {
835 {
836 return SCIP_OKAY;
837 }
838 else
839 {
841 }
842 }
843
844 /******************************************************************
845 * if node depth is smaller than that specified by parameter,
846 * not to send nodes and keep them.
847 *****************************************************************/
848 if( SCIPnodeGetDepth( SCIPgetCurrentNode( scip ) )
851 {
852 return SCIP_OKAY;
853 }
854
855 /*******************************************************************
856 * if ParaNode transfer has been requested, send a ParaNode *
857 ******************************************************************/
858 if( ( needToSendNode &&
859 (
860 SCIPgetNNodesLeft( scip ) > scipParaSolver->getThresholdValue(SCIPgetNNodes(scip)) ||
862 ( SCIPgetNNodesLeft( scip ) > 1 &&
864 ( !scipParaSolver->isRampUp() &&
865 ( bestDualBoundValue - scipParaSolver->getLcBestDualBoundValue() < 0.0 ||
866 ( ( bestDualBoundValue - scipParaSolver->getLcBestDualBoundValue() ) > 0.0 &&
867 ( REALABS( ( bestDualBoundValue - scipParaSolver->getLcBestDualBoundValue() )
869 )
870 )
871 )
872 )
873 )
874 )
875 )
880 || ( !scipParaSolver->isRacingStage() &&
884 SCIPgetDepth(scip) > scipParaSolver->getAggresivePresolvingDepth() )
885 )
886 {
889 {
891 {
895 ( bestDualBoundValue > scipParaSolver->getTargetBound() ) ) )
896 {
898 }
899 }
900 else
901 {
902 return SCIP_OKAY;
903 }
904
905 }
906 else
907 {
908 assert( nNodes <=2 );
909 return SCIP_OKAY;
910 }
911 }
912
914 {
915 if( !scipParaSolver->isRampUp() )
916 {
917 // if( ( !scipParaSolver->isWarmStarted() ) && scipParaSolver->isRacingRampUp() )
919 {
921 {
923 // if( originalSelectionStrategy && SCIPgetNNodesLeft(scip) > scipParaSolver->getNPreviousNodesLeft() )
924 {
926 }
927 needToSendNode = true;
928 }
929 }
930 else
931 {
933 && paraComm->getRank() == 1 ) ||
934 bestDualBoundValue - scipParaSolver->getLcBestDualBoundValue() < 0.0 ||
935 ( ( bestDualBoundValue - scipParaSolver->getLcBestDualBoundValue() ) > 0.0 &&
936 ( REALABS( ( bestDualBoundValue - scipParaSolver->getLcBestDualBoundValue() )
938 {
940 // if( originalSelectionStrategy && SCIPgetNNodesLeft(scip) > scipParaSolver->getNPreviousNodesLeft() )
941 {
943 }
946 {
947 needToSendNode = true;
948 }
949 else
950 {
951 if( needToSendNode ) needToSendNode = false;
952 else needToSendNode = true;
953 }
954 }
955 else
956 {
957 needToSendNode = false;
958 }
959 }
960 }
961 else
962 {
963 /*********************************************
964 * check if solver is in collecting mode *
965 ********************************************/
967 {
969 // if( originalSelectionStrategy && SCIPgetNNodesLeft(scip) > scipParaSolver->getNPreviousNodesLeft() )
970 {
972 }
974 {
975 needToSendNode = true;
976 }
977 else
978 {
981 {
982 needToSendNode = true;
983 }
984 else
985 {
986 if( needToSendNode ) needToSendNode = false;
987 else needToSendNode = true;
988 }
989 }
990 }
991 else
992 {
994 {
995 SCIP_NODESEL *nodesel = SCIPgetNodesel(scip);
996 SCIP_CALL_ABORT( SCIPsetNodeselStdPriority(scip, nodesel,
999 scipParaSolver->setNPreviousNodesLeft(SCIPgetNNodesLeft(scip));
1000 }
1001 needToSendNode = false; // In iReceive, more than on collecting mode message may be received
1002 }
1003 }
1004 }
1005
1006 return SCIP_OKAY;
1007}
1008
1009// void
1010bool
1012 SCIP* scip
1013 )
1014{
1015 SCIP_NODE* node = SCIPgetCurrentNode( scip );
1016 int depth = SCIPnodeGetDepth( node );
1017 SCIP_VAR **branchVars = new SCIP_VAR*[depth];
1018 SCIP_Real *branchBounds = new SCIP_Real[depth];
1019 SCIP_BOUNDTYPE *boundTypes = new SCIP_BOUNDTYPE[depth];
1020 int nBranchVars;
1021 SCIPnodeGetAncestorBranchings( node, branchVars, branchBounds, boundTypes, &nBranchVars, depth );
1022 if( nBranchVars > depth ) // did not have enough memory, then reallocate
1023 {
1024 delete [] branchVars;
1025 delete [] branchBounds;
1026 delete [] boundTypes;
1027 branchVars = new SCIP_VAR*[nBranchVars];
1028 branchBounds = new SCIP_Real[nBranchVars];
1029 boundTypes = new SCIP_BOUNDTYPE[nBranchVars];
1030 SCIPnodeGetAncestorBranchings( node, branchVars, branchBounds, boundTypes, &nBranchVars, nBranchVars );
1031 }
1032
1036 {
1037 int nVars = SCIPgetNVars(scip);
1038 SCIP_VAR **vars = SCIPgetVars(scip);
1039 int *iBranchVars = new int[nBranchVars];
1040 /* create the variable mapping hash map */
1041 SCIP_HASHMAP* varmapLb;
1042 SCIP_HASHMAP* varmapUb;
1043 SCIP_CALL_ABORT( SCIPhashmapCreate(&varmapLb, SCIPblkmem(scip), nVars) );
1044 SCIP_CALL_ABORT( SCIPhashmapCreate(&varmapUb, SCIPblkmem(scip), nVars) );
1045 for( int i = 0; i < nBranchVars; i++ )
1046 {
1047 iBranchVars[i] = i;
1048 if( boundTypes[i] == SCIP_BOUNDTYPE_LOWER )
1049 {
1050 if( !SCIPhashmapGetImage(varmapLb, branchVars[i]) )
1051 {
1052 SCIP_CALL_ABORT( SCIPhashmapInsert(varmapLb, branchVars[i], &iBranchVars[i] ) );
1053 }
1054 }
1055 else
1056 {
1057 if( !SCIPhashmapGetImage(varmapUb, branchVars[i]) )
1058 {
1059 SCIP_CALL_ABORT( SCIPhashmapInsert(varmapUb, branchVars[i], &iBranchVars[i] ) );
1060 }
1061 }
1062 }
1063 SCIP_VAR **preBranchVars = branchVars;
1064 SCIP_Real *preBranchBounds = branchBounds;
1065 SCIP_BOUNDTYPE *preBboundTypes = boundTypes;
1066 branchVars = new SCIP_VAR*[nBranchVars+nVars*2];
1067 branchBounds = new SCIP_Real[nBranchVars+nVars*2];
1068 boundTypes = new SCIP_BOUNDTYPE[nBranchVars+nVars*2];
1069 for( int i = 0; i < nBranchVars; i++ )
1070 {
1071 branchVars[i] = preBranchVars[i];
1072 branchBounds[i] = preBranchBounds[i];
1073 boundTypes[i] = preBboundTypes[i];
1074 }
1075 int *iBranchVar = NULL;
1076 for( int i = 0; i < nVars; i++ )
1077 {
1080 {
1081 continue;
1082 }
1083 iBranchVar = (int *)SCIPhashmapGetImage(varmapLb, vars[i]);
1084 if( iBranchVar )
1085 {
1086 // assert( EPSGE(preBranchBounds[*iBranchVar], SCIPvarGetLbLocal(vars[i]) ,DEFAULT_NUM_EPSILON ) );
1087 if( EPSLT(preBranchBounds[*iBranchVar], SCIPvarGetLbLocal(vars[i]) ,DEFAULT_NUM_EPSILON ) )
1088 {
1089 branchBounds[*iBranchVar] = SCIPvarGetLbLocal(vars[i]); // node is current node
1090 if ( EPSGT(branchBounds[*iBranchVar], SCIPvarGetUbGlobal(vars[i]), DEFAULT_NUM_EPSILON) ) abort();
1091 }
1092 }
1093 else
1094 {
1095 if( EPSGT( SCIPvarGetLbLocal(vars[i]), SCIPvarGetLbGlobal(vars[i]), MINEPSILON ) )
1096 {
1097 branchVars[nBranchVars] = vars[i];
1098 branchBounds[nBranchVars] = SCIPvarGetLbLocal(vars[i]);
1099 boundTypes[nBranchVars] = SCIP_BOUNDTYPE_LOWER;
1100 if ( EPSGT(branchBounds[nBranchVars], SCIPvarGetUbGlobal(vars[i]), DEFAULT_NUM_EPSILON) ) abort();
1101 nBranchVars++;
1102 }
1103 }
1104 iBranchVar = (int *)SCIPhashmapGetImage(varmapUb, vars[i]);
1105 if( iBranchVar )
1106 {
1107 // assert( EPSLE(preBranchBounds[*iBranchVar], SCIPvarGetUbLocal(vars[i]) ,DEFAULT_NUM_EPSILON ) );
1108 if( EPSGT(preBranchBounds[*iBranchVar], SCIPvarGetUbLocal(vars[i]) ,DEFAULT_NUM_EPSILON ) )
1109 {
1110 branchBounds[*iBranchVar] = SCIPvarGetUbLocal(vars[i]); // node is current node
1111 if ( EPSLT(branchBounds[*iBranchVar], SCIPvarGetLbGlobal(vars[i]),DEFAULT_NUM_EPSILON) ) abort();
1112 }
1113 }
1114 else
1115 {
1116 if( EPSLT( SCIPvarGetUbLocal(vars[i]), SCIPvarGetUbGlobal(vars[i]), MINEPSILON ) )
1117 {
1118 branchVars[nBranchVars] = vars[i];
1119 branchBounds[nBranchVars] = SCIPvarGetUbLocal(vars[i]);
1120 boundTypes[nBranchVars] = SCIP_BOUNDTYPE_UPPER;
1121 if ( EPSLT(branchBounds[nBranchVars], SCIPvarGetLbGlobal(vars[i]),DEFAULT_NUM_EPSILON) ) abort();
1122 nBranchVars++;
1123 }
1124 }
1125 }
1126 SCIPhashmapFree(&varmapLb);
1127 SCIPhashmapFree(&varmapUb);
1128 delete [] preBranchVars;
1129 delete [] preBranchBounds;
1130 delete [] preBboundTypes;
1131 delete [] iBranchVars;
1132 }
1133
1134 /** check root node solvability */
1136 {
1137 SCIP_CALL_ABORT( SCIPtransformProb(scipToCheckRootSolvability) );
1138 SCIP_VAR **copyVars = SCIPgetVars(scipToCheckRootSolvability);
1139 for(int v = 0; v < nBranchVars; v++)
1140 {
1141 int index = SCIPvarGetProbindex(branchVars[v]);
1142 assert(index != -1);
1143 assert(std::string(SCIPvarGetName(branchVars[v]))==std::string(SCIPvarGetName(copyVars[index])));
1144 if( boundTypes[v] == SCIP_BOUNDTYPE_LOWER )
1145 {
1146 SCIP_CALL_ABORT(SCIPchgVarLbGlobal(scipToCheckRootSolvability,copyVars[index], branchBounds[v]));
1147 }
1148 else if (boundTypes[v] == SCIP_BOUNDTYPE_UPPER)
1149 {
1150 SCIP_CALL_ABORT(SCIPchgVarUbGlobal(scipToCheckRootSolvability,copyVars[index], branchBounds[v]));
1151 }
1152 else
1153 {
1154 THROW_LOGICAL_ERROR2("Invalid bound type: type = ", static_cast<int>(boundTypes[v]));
1155 }
1156 }
1157 SCIP_CALL_ABORT(SCIPsetLongintParam(scipToCheckRootSolvability,"limits/nodes", 1));
1158 SCIP_CALL_ABORT(SCIPsetObjlimit(scipToCheckRootSolvability, scipParaSolver->getGlobalBestIncumbentValue()));
1159 SCIP_CALL_ABORT(SCIPsolve(scipToCheckRootSolvability));
1160
1161 SCIP_STATUS status = SCIPgetStatus(scipToCheckRootSolvability);
1162
1163 switch(status)
1164 {
1165 case SCIP_STATUS_OPTIMAL :
1166 {
1167 SCIP_SOL *bestSol = SCIPgetBestSol( scip );
1168 int nVars = SCIPgetNOrigVars(scip);
1169 SCIP_VAR **vars = SCIPgetOrigVars(scip);
1170 SCIP_Real *vals = new SCIP_Real[nVars];
1171 SCIP_CALL_ABORT( SCIPgetSolVals(scip, bestSol, nVars, vars, vals) );
1172 DEF_SCIP_PARA_COMM( scipParaComm, paraComm);
1174 scipParaComm->createScipParaSolution(
1176 SCIPgetSolOrigObj(scip, bestSol),
1177 nVars,
1178 vars,
1179 vals
1180 )
1181 );
1182 delete [] vals;
1183 /** remove the node sent from SCIP environment */
1184 SCIP_CALL_ABORT( SCIPcutoffNode( scip, node) );
1185 needToSendNode = false; // This means that a node is sent in the next time again,
1186 // because this flag is flipped when collecting mode is checked
1188 break;
1189 }
1190 case SCIP_STATUS_INFEASIBLE :
1191 case SCIP_STATUS_INFORUNBD :
1192 {
1193 /** remove the node sent from SCIP environment */
1194 SCIP_CALL_ABORT( SCIPcutoffNode( scip, node ) );
1195 needToSendNode = false; // This means that a node is sent in the next time again,
1196 // because this flag is flipped when collecting mode is checked
1198 break;
1199 }
1200 case SCIP_STATUS_NODELIMIT :
1201 {
1202 sendNode(scip, node, depth, nBranchVars, branchVars, branchBounds, boundTypes);
1203 break;
1204 }
1205 default:
1206 THROW_LOGICAL_ERROR2("Invalid status after root solvability check: status = ", static_cast<int>(status));
1207 }
1208
1209 SCIP_CALL_ABORT( SCIPfreeTransform(scipToCheckRootSolvability) );
1210 }
1211 else
1212 {
1213 if( scipParaSolver->isCopyIncreasedVariables() ) // this may not need, but only for this error occurred so far.
1214 {
1215 if( !ifFeasibleInOriginalProblem(scip, nBranchVars, branchVars, branchBounds) )
1216 {
1217 delete [] branchVars;
1218 delete [] branchBounds;
1219 delete [] boundTypes;
1220 return false;
1221 }
1222 }
1223 sendNode(scip, node, depth, nBranchVars, branchVars, branchBounds, boundTypes);
1224 }
1225
1226 delete [] branchVars;
1227 delete [] branchBounds;
1228 delete [] boundTypes;
1229
1230 return true;
1231}
1232
1233void
1235 SCIP *scip,
1236 SCIP_NODE* node,
1237 int depth,
1238 int nNewBranchVars,
1239 SCIP_VAR **newBranchVars,
1240 SCIP_Real *newBranchBounds,
1241 SCIP_BOUNDTYPE *newBoundTypes
1242 )
1243{
1244
1245 SCIP_CONS** addedcons = 0;
1246 int addedconsssize = SCIPnodeGetNAddedConss(node);
1247 int naddedconss = 0;
1248 if( addedconsssize > 0 )
1249 {
1250 SCIP_CALL_ABORT( SCIPallocBufferArray(scip, &addedcons, addedconsssize) );
1251 SCIPnodeGetAddedConss(node, addedcons, &naddedconss, addedconsssize);
1252 }
1253
1254
1255 DEF_SCIP_PARA_COMM( scipParaComm, paraComm);
1256 ScipParaDiffSubproblem *diffSubproblem = scipParaComm->createScipParaDiffSubproblem(
1257 scip,
1259 nNewBranchVars,
1260 newBranchVars,
1261 newBranchBounds,
1262 newBoundTypes,
1263 naddedconss,
1264 addedcons
1265 );
1266
1267 if( naddedconss )
1268 {
1269 SCIPfreeBufferArray(scip, &addedcons);
1270 }
1271
1272
1273 long long n = SCIPnodeGetNumber( node );
1274 double dualBound = SCIPgetDualbound(scip);
1275 // if( SCIPisObjIntegral(scip) )
1276 // {
1277 // dualBound = ceil(dualBound);
1278 // }
1279 assert(SCIPisFeasGE(scip, SCIPnodeGetLowerbound(node) , SCIPgetLowerbound(scip)));
1280 double estimateValue = SCIPnodeGetEstimate( node );
1281 assert(SCIPisFeasGE(scip, estimateValue, SCIPnodeGetLowerbound(node) ));
1282#ifdef UG_DEBUG_SOLUTION
1283 SCIP_Bool valid = 0;
1284 SCIP_CALL_ABORT( SCIPdebugSolIsValidInSubtree(scip, &valid) );
1285 diffSubproblem->setOptimalSolIndicator(valid);
1286 std::cout << "* R." << scipParaSolver->getRank() << ", debug = " << SCIPdebugSolIsEnabled(scip) << ", valid = " << valid << std::endl;
1287#endif
1288 scipParaSolver->sendParaNode(n, depth, dualBound, estimateValue, diffSubproblem);
1289
1290 /** remove the node sent from SCIP environment */
1291#ifdef UG_DEBUG_SOLUTION
1292 if( valid )
1293 {
1294 SCIPdebugSolDisable(scip);
1295 std::cout << "R." << paraComm->getRank() << ": disable debug, node which contains optmal solution is sent." << std::endl;
1296 }
1297#endif
1298 SCIP_CALL_ABORT( SCIPcutoffNode( scip, node) );
1299}
1300
1301void
1303 SCIP* scip
1304 )
1305{
1306 scipParaSolver->setNPreviousNodesLeft(SCIPgetNNodesLeft(scip));
1307 int numnodesels = SCIPgetNNodesels( scip );
1308 SCIP_NODESEL** nodesels = SCIPgetNodesels( scip );
1309 int i;
1310 for( i = 0; i < numnodesels; ++i )
1311 {
1312 std::string nodeselname(SCIPnodeselGetName(nodesels[i]));
1313 if( std::string(nodeselname) == std::string(changeNodeSelName) )
1314 {
1315 SCIP_CALL_ABORT( SCIPsetNodeselStdPriority(scip, nodesels[i], 536870911 ) );
1317 int maxrestarts;
1318 SCIP_CALL_ABORT( SCIPgetIntParam(scip, "presolving/maxrestarts", &maxrestarts) );
1319 if( maxrestarts != 0 )
1320 {
1321 SCIP_CALL_ABORT( SCIPsetIntParam(scip, "presolving/maxrestarts", 0) );
1322 }
1323 break;
1324 }
1325 }
1326 assert( i != numnodesels );
1327}
1328
1329bool
1331 SCIP *scip,
1332 int nNewBranchVars,
1333 SCIP_VAR **newBranchVars,
1334 SCIP_Real *newBranchBounds)
1335{
1336
1337 bool feasible = true;
1338 SCIP_Real *branchBounds = new SCIP_Real[nNewBranchVars];
1339 for( int v = nNewBranchVars -1 ; v >= 0; --v )
1340 {
1341 SCIP_VAR *transformVar = newBranchVars[v];
1342 SCIP_Real scalar = 1.0;
1343 SCIP_Real constant = 0.0;
1344 SCIP_CALL_ABORT( SCIPvarGetOrigvarSum(&transformVar, &scalar, &constant ) );
1345 if( transformVar == NULL ) continue;
1346 // assert( scalar == 1.0 && constant == 0.0 );
1347 branchBounds[v] = ( newBranchBounds[v] - constant ) / scalar;
1348 if( SCIPvarGetType(transformVar) != SCIP_VARTYPE_CONTINUOUS
1349 && SCIPvarGetProbindex(transformVar) < scipParaSolver->getNOrgVars() )
1350 {
1351 if( !(SCIPisLE(scip,scipParaSolver->getOrgVarLb(SCIPvarGetProbindex(transformVar)), branchBounds[v]) &&
1352 SCIPisGE(scip,scipParaSolver->getOrgVarUb(SCIPvarGetProbindex(transformVar)), branchBounds[v])) )
1353 {
1354 feasible = false;
1355 break;
1356 }
1357 }
1358 }
1359 delete [] branchBounds;
1360
1361 return feasible;
1362}
ScipParaObjLimitUpdator * scipParaObjLimitUpdator
void processNewSolution(SCIP *scip, SCIP_EVENT *event)
void sendNode(SCIP *scip, SCIP_NODE *node, int depth, int nBranchVars, SCIP_VAR **branchVars, SCIP_Real *branchBounds, SCIP_BOUNDTYPE *boundTypes)
bool ifFeasibleInOriginalProblem(SCIP *scip, int nNewBranchVars, SCIP_VAR **newBranchVars, SCIP_Real *newBranchBounds)
virtual SCIP_RETCODE scip_exec(SCIP *scip, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENT *event, SCIP_EVENTDATA *eventdata)
int getOriginalIndex(int index)
void setNPreviousNodesLeft(long long n)
double getTightenedVarUb(int i)
void setTightenedVarUb(int i, double v)
void setTightenedVarLb(int i, double v)
double getTightenedVarLb(int i)
int getProbIndex(int index)
class BbParaNode
Definition: bbParaNode.h:62
double getDualBoundValue()
getter of dual bound value
Definition: bbParaNode.h:303
virtual void sendSolverState(long long nNodesSolved, int nNodesLeft, double bestDualBoundValue, double detTime)
send Solver state to LoadCoordinator
virtual int getRank()
get rank of this Solver
double getCurrentSolvingNodeInitialDualBound()
get initial dual bound of current solving node
bool isAggressivePresolvingSpecified()
check if aggressive presolving is specified
double getElapsedTimeOfNodeSolving()
the following functions may be called from callback routines of the target Solver
Definition: bbParaSolver.h:726
bool isRacingRampUp()
check if this solver is in racing ramp-up or not
bool isManyNodesCollectionRequested()
check if many nodes collection was requested or not
Definition: bbParaSolver.h:913
bool isRacingInterruptRequested()
check if racing interrupt was requested or not
Definition: bbParaSolver.h:834
bool isCollectingAllNodes()
check if Solver is sending all nodes to LoadCoordinaor or not
ParaTask * getCurrentNode()
get current ParaNode object
Definition: bbParaSolver.h:981
bool isTransferLimitReached()
check if the number of ParaNodes sent is reached to transfer limit specified
bool isAggressiveCollecting()
check if Solver is in aggressive collecting mode or not
Definition: bbParaSolver.h:903
bool isCollecingInterrupt()
check if collecting interrupt (interrupt with collecting all nodes) is requested or not
Definition: bbParaSolver.h:844
virtual void waitMessageIfNecessary()
wait a notification id message if it is needed to synchronize with LoadCoordinaor
bool newParaNodeExists()
check if a new ParaNode was received or not
Definition: bbParaSolver.h:883
ParaParamSet * getParaParamSet()
get ParaParamSet object
void setRootNodeSimplexIter(int iter)
set number of simplex iteration at root node
void setNotEnoughGain()
set dual bound gain is not enough
void resetBreakingInfo()
reset breaking information
void setSendBackAllNodes()
set counter and flag to indicate that all nodes are sent to LoadCooordinator
int getCurrentSolivingNodeMergingStatus()
get current solving node merging status
int getNStopSolvingMode()
get number of nodes to stop solving. This number is not used to decide stop solving....
Definition: bbParaSolver.h:757
void passToken(int rank)
pass token to the next process
virtual void sendLocalSolution()
send solution found in this Solver
bool isAnotherNodeIsRequested()
check if another node is requested or not
double getGlobalBestIncumbentValue()
get global best incumbent value
Definition: bbParaSolver.h:971
bool isGivenGapReached()
check if given gap is reached or not
virtual void iReceiveMessages()
non-blocking receive messages
double getTimeStopSolvingMode()
get time to stop solving. This value is not used to decide stop solving. It is used a part of conditi...
Definition: bbParaSolver.h:768
bool isDualBoundGainTestNeeded()
check if dual bound gain needs to be tested or not
double getAverageDualBoundGain()
get average dual bound gain
virtual void sendParaNode(long long n, int depth, double dualBound, double estimateValue, ParaDiffSubproblem *diffSubproblem)
send a branch-and-bound node as ParaNode to LoadCoordinator
int getBigDualGapSubtreeHandlingStrategy()
get big dual gap subtree handling strategy
virtual void sendAnotherNodeRequest(double bestDualBoundValue)
send another node request
bool isBreaking()
check if Solver is in racing stage or not
double getBoundGapForCollectingMode()
get bound gap for collecting mode
Definition: bbParaSolver.h:799
bool isInCollectingMode()
check if Solver is in collecting mode or not
Definition: bbParaSolver.h:893
bool isGlobalIncumbentUpdated()
check if global incumbent value is updated or not
Definition: bbParaSolver.h:815
bool isRacingStage()
check if Solver is in racing stage or not
int getSubMipDepth()
get depth of sub-MIP root node in global search tree
virtual void setRootNodeTime()
set root node computing time
bool isEnoughGainObtained()
check if dual bound gains enough or not
double getTargetBound()
get target bound for breaking
int getAggresivePresolvingStopDepth()
get depth to stop aggressive presolving
double getLcBestDualBoundValue()
get LoadCorrdinator best dual bound value
Definition: bbParaSolver.h:746
virtual bool saveIfImprovedSolutionWasFound(ParaSolution *sol)
save improved solution if it was found in this Solver
virtual int getThresholdValue(int nNodes)
get threshold value to send ParaNodes to LoadCoordinator
void countInPrecheckSolvedParaNodes()
count ParaNode solved at root node in pre-check
virtual bool notificationIsNecessary()
check if a notification message needs to send or not
int getAggresivePresolvingDepth()
get depth to apply aggressive presolving
double getBoundGapForStopSolving()
get bound gap for stop solving. This value is not used to decide stop solving. It is used a part of c...
Definition: bbParaSolver.h:789
int getNSendInCollectingMode()
get number of ParaNodes already sent in a collecting mode
bool waitToken(int rank)
wait token for deterministic mode
virtual int send(void *bufer, int count, const int datatypeId, int dest, const int tag)=0
send function for standard ParaData types
virtual int getRank()=0
get rank of this process or this thread depending on run-time environment
virtual void update(double value)=0
update function of the deterministic time. the deterministic time is a kind of counter
virtual double getElapsedTime()=0
getter of the deterministic time
bool getBoolParamValue(int param)
get bool parameter value
double getRealParamValue(int param)
get real parameter value
int getIntParamValue(int param)
get int parameter value
virtual void updatePendingSolution()
update pending solution
Definition: paraSolver.h:759
void setPreviousCommTime(double detTime)
set previous communication time for deterministic execution
Definition: paraSolver.h:817
bool isRampUp()
check if this solver is ramp-up or not
Definition: paraSolver.h:509
ParaDeterministicTimer * getDeterministicTimer()
get deterministic timer object
Definition: paraSolver.h:739
bool isRacingWinner()
check if this solver is in racing ramp-up or not
Definition: paraSolver.h:530
bool isTerminationRequested()
check if termination was requested or not
Definition: paraSolver.h:589
double getPreviousCommTime()
get previous communication time for deterministic execution
Definition: paraSolver.h:828
bool isRootTask()
check if root task or not
Definition: paraTask.h:624
static const int RootNodeSolvabilityCheck
static const int BreakFirstSubtree
static const int NoAllBoundChangesTransferInRacing
static const int DualBoundGainTest
static const int TagLbBoundTightenedBound
Definition: bbParaTagDef.h:63
static const int NumberOfNodesKeepingInRootSolver
static const int TagAllowToBeInCollectingMode
Definition: bbParaTagDef.h:57
static const int FinalCheckpointGeneratingTime
Definition: paraParamSet.h:108
static const int EventWeightedDeterministic
static const int NotificationInterval
Definition: paraParamSet.h:105
static const int TagLbBoundTightenedIndex
Definition: bbParaTagDef.h:62
static const int ParaINT
Definition: paraComm.h:66
static const int TagUbBoundTightenedIndex
Definition: bbParaTagDef.h:64
static const int ParaBYTE
Definition: paraComm.h:79
static const int ControlCollectingModeOnSolverSide
static const int NoAlternateSolving
static const int GenerateReducedCheckpointFiles
static const int Deterministic
Definition: paraParamSet.h:76
static const int RampUpPhaseProcess
static const int TagUbBoundTightenedBound
Definition: bbParaTagDef.h:65
static const int DualBoundGainBranchRatio
static const int AllBoundChangesTransfer
static const int KeepNodesDepth
static const int AllowableRegressionRatioInMerging
static const int ParaDOUBLE
Definition: paraComm.h:76
static const int CommunicateTighterBoundsInRacing
#define PARA_COMM_CALL(paracommcall)
Definition: paraComm.h:47
#define THROW_LOGICAL_ERROR2(msg1, msg2)
Definition: paraDef.h:69
#define DEFAULT_NUM_EPSILON
Definition: paraDef.h:49
#define EPSLT(x, y, eps)
Definition: paraDef.h:167
#define MINEPSILON
Definition: paraDef.h:50
#define REALABS(x)
Definition: paraDef.h:165
#define EPSGT(x, y, eps)
Definition: paraDef.h:169
#define DEF_SCIP_PARA_COMM(scip_para_comm, comm)
ParaInitialStat extension for SCIP solver.
Event handlr for communication point.
ParaSolution extension for SCIP solver.