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-2024 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 }
414 paraComm->send((void *)&orgIndex, 1, UG::ParaINT, 0, UG::TagLbBoundTightenedIndex )
415 );
417 paraComm->send((void *)&newbound, 1, UG::ParaDOUBLE, 0, UG::TagLbBoundTightenedBound )
418 );
419 /*
420 std::cout << "Rank " << paraComm->getRank()
421 << ": send tightened lower bond. idx = " << index
422 << ", bound = " << newbound
423 << ", var status = " << SCIPvarGetStatus(SCIPeventGetVar(event))
424 << std::endl; */
425 }
426 }
427 else
428 {
429 if( SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS )
430 {
431 assert( SCIPisFeasIntegral(scip, newbound) );
432 newbound = SCIPfeasFloor(scip, newbound);
433 }
434 #ifdef UG_DEBUG_SOLUTION
435 SCIP_Real solvalue = 0.0;
436 SCIP_CALL(SCIPdebugGetSolVal(scip,var, &solvalue));
437 std::cout << "Sender side SolValue: " << SCIPvarGetName(var) << " = " << solvalue << std::endl;
438 std::cout << "Sender side (SCIP_BOUNDTYPE_UPPER): " << SCIPvarGetName(var) << " = " << newbound << std::endl;
439 SCIP_CALL_ABORT( SCIPdebugCheckUbGlobal(scip,var,newbound) );
440 #endif
441 assert( SCIPisLE(scip,scipParaSolver->getOrgVarLb(index), newbound) );
442 // && SCIPisGE(scip,scipParaSolver->getOrgVarUb(index), newbound) );
443 if( SCIPisLT(scip, newbound, scipParaSolver->getTightenedVarUb(index) ) ) // &&
444 // SCIPisGE(scip, newbound, scipParaSolver->getTightenedVarLb(index) ) ) // just for safety
445 {
446 // This asertion may not be hold
447 // assert( SCIPisLE(scip,scipParaSolver->getTightenedVarLb(index), newbound) &&
448 // SCIPisGE(scip,scipParaSolver->getTightenedVarUb(index), newbound) );
449 scipParaSolver->setTightenedVarUb(index, newbound);
450 int orgIndex = SCIPvarGetIndex(var);
452 {
453 orgIndex = scipParaSolver->getOriginalIndex(orgIndex);
454 }
456 paraComm->send((void *)&orgIndex, 1, UG::ParaINT, 0, UG::TagUbBoundTightenedIndex )
457 );
459 paraComm->send((void *)&newbound, 1, UG::ParaDOUBLE, 0, UG::TagUbBoundTightenedBound )
460 );
461 /*
462 std::cout << "Rank " << paraComm->getRank()
463 << ": send tightened upper bond. idx = " << index
464 << ", bound = " << newbound
465 << ", var status = " << SCIPvarGetStatus(SCIPeventGetVar(event))
466 << std::endl; */
467 }
468 }
469 }
470 }
471 }
472
473
474 /*********************************************************************************************
475 * update solution. This have to do right after receiving message *
476 ********************************************************************************************/
477 scipParaSolver->sendLocalSolution(); // if local solution exists, it should be sent right after iReceiveMessages
478 if( !cloned )
479 {
480 // paraComm->lockApp();
482 // paraComm->unlockApp();
483 }
489 )
490 {
491 if( !interrupting )
492 {
493 if( cloned )
494 {
495 if( SCIPgetStage(subScip) != SCIP_STAGE_INITSOLVE )
496 {
497 SCIP_CALL_ABORT( SCIPinterruptSolve(subScip) );
498 interrupting = true;
499 }
500 }
501 else
502 {
503 if( SCIPgetStage(scip) != SCIP_STAGE_INITSOLVE )
504 {
508 {
509 #ifdef UG_DEBUG_SOLUTION
511 {
512 std::cout << "racing stage = " << scipParaSolver->isRacingStage() << ", winner = " << scipParaSolver->isRacingWinner() << std::endl;
513 if( SCIPdebugSolIsEnabled(scip) )
514 {
515 throw "Optimal solution going to be lost!";
516 }
517 }
518 SCIPdebugSolDisable(scip);
519 std::cout << "R." << paraComm->getRank() << ": disable debug, this solver is interrupted." << std::endl;
520 #endif
521 SCIP_CALL_ABORT( SCIPinterruptSolve(scip) );
522 interrupting = true;
523 }
524 }
525 }
526 return SCIP_OKAY;
527 }
530 ( !scipParaSolver->isRampUp() ) )
531 {
532 return SCIP_OKAY;
533 }
534 }
535
536 if( (!cloned ) &&
539 {
540 int maxrestarts = 0;
541 SCIP_CALL( SCIPgetIntParam(scip, "presolving/maxrestarts", &maxrestarts) );
542 if( SCIPgetNRuns( scip ) >= maxrestarts )
543 {
545 {
548 );
549 }
551 }
552 /*
553 else
554 {
555 if( scipParaSolver->isRacingStage() )
556 {
557 return SCIP_OKAY; // during racing stage, just keep running for all restart
558 }
559 }
560 */
561 }
562
563 SCIP_Longint nNodes = 0;
564 if( SCIPgetStage(scip) != SCIP_STAGE_PRESOLVING
565 && SCIPgetStage(scip) != SCIP_STAGE_INITSOLVE
566 && (!scipParaSolver->isCollectingModeProhibited() ) ) // restarting is considered as root node process in ug[SCIP,*])
567 {
568 nNodes = SCIPgetNTotalNodes(scip);
569 }
570
571 if( previousNNodesSolved == nNodes
572 // && (!scipParaSolver->isCollectingModeProhibited() ) ) // setting cutoff value works well
573 || scipParaSolver->isCollectingModeProhibited() ) // setting cutoff value works well
574 {
582 )
583 {
586 }
587
588 return SCIP_OKAY;
589 }
590 previousNNodesSolved = nNodes;
591
592 /** if root node is solved, set root node time */
593 if( nNodes == 2 && SCIPgetNNodes(scip) == 2 )
594 {
595 /** when a problem is solved at root,
596 * its root node process time is set on paraSolver main loop */
601 )
602 {
603 if( ( SCIPgetDualbound(scip) - dynamic_cast<UG::BbParaNode *>(scipParaSolver->getCurrentNode())->getDualBoundValue() )
605 {
607 }
608 }
610 SCIPgetDualbound(scip) <
612 {
613 if( !interrupting )
614 {
615 if( cloned )
616 {
617 SCIP_CALL_ABORT( SCIPinterruptSolve(subScip) );
618 }
619 else
620 {
621 dynamic_cast<UG::BbParaNode *>(scipParaSolver->getCurrentNode())->setMergingStatus(3); // cannot be merged
622 SCIP_CALL_ABORT( SCIPinterruptSolve(scip) );
623 }
624 interrupting = true;
625 }
626 return SCIP_OKAY;
627 }
628 }
629
630 /*****************************************************************************
631 * sends solver state message if it is necessary, that is, *
632 * notification interval time has been passed from the previous notification *
633 *****************************************************************************/
634 double bestDualBoundValue = -SCIPinfinity(scip);
635 if( SCIPgetStage(scip) == SCIP_STAGE_TRANSFORMED ||
636 SCIPgetStage(scip) == SCIP_STAGE_PRESOLVING ||
637 SCIPgetStage(scip) == SCIP_STAGE_INITSOLVE
638 )
639 {
640 bestDualBoundValue = dynamic_cast<UG::BbParaNode *>(scipParaSolver->getCurrentNode())->getDualBoundValue();
641 }
642 else
643 {
644 bestDualBoundValue = std::max(SCIPgetDualbound(scip), dynamic_cast<UG::BbParaNode *>(scipParaSolver->getCurrentNode())->getDualBoundValue());
645 }
646
647 /************************************************************
648 * check if global best incumbent value is updated or not. *
649 * if it is updated, set cutoff value *
650 ************************************************************/
651// if( scipParaSolver->isGlobalIncumbentUpdated() &&
652// SCIPgetStage(scip) != SCIP_STAGE_PRESOLVING
653// && SCIPgetStage(scip) != SCIP_STAGE_INITSOLVE )
654// {
655// if( !cloned
656// && SCIPeventGetType(event) != SCIP_EVENTTYPE_BOUNDTIGHTENED
657// )
658// {
659// /** set cutoff value */
660// // if( scipParaSolver->getGlobalBestIncumbentValue() > bestDualBoundValue )
661// // {
662// SCIP_CALL_ABORT( SCIPsetObjlimit(scip, scipParaSolver->getGlobalBestIncumbentValue()) );
663// // }
664// scipParaSolver->globalIncumbnetValueIsReflected();
665//std::cout << "R." << paraComm->getRank() << " ** UPDATED **" << std::endl;
666// }
667// }
668
669 if( scipParaSolver->getGlobalBestIncumbentValue() < bestDualBoundValue )
670 {
671 if( !interrupting )
672 {
673 if( cloned )
674 {
675 if( SCIPgetStage(subScip) != SCIP_STAGE_INITSOLVE )
676 {
677 SCIP_CALL_ABORT( SCIPinterruptSolve(subScip) );
678 interrupting = true;
679 }
680 }
681 else
682 {
683 if( SCIPgetStage(scip) != SCIP_STAGE_INITSOLVE )
684 {
685#ifdef UG_DEBUG_SOLUTION
687 {
688 std::cout << "racing stage = " << scipParaSolver->isRacingStage() << ", winner = " << scipParaSolver->isRacingWinner() << std::endl;
689 if( SCIPdebugSolIsEnabled(scip) )
690 {
691 throw "Optimal solution going to be lost!";
692 }
693 }
694 SCIPdebugSolDisable(scip);
695 std::cout << "R." << paraComm->getRank() << ": disable debug, this solver is interrupted." << std::endl;
696#endif
697 SCIP_CALL_ABORT( SCIPinterruptSolve(scip) );
698 interrupting = true;
699 }
700 }
701 }
702 return SCIP_OKAY;
703 }
704
705 if( scipParaSolver->isCollectingModeProhibited() || nNodes < 2 ) // do not have to send status to LC yet.
706 {
707 return SCIP_OKAY;
708 }
709
711 {
712 needToSendNode = true;
713 }
714
715 if ( needToSendNode
717 || nNodes == 2
719 {
720 if( bestDualBoundValue >= -1e+10 && (!interrupting) ) // only after some dual bound value is computed, notify its status
721 {
722 int nNodesLeft = 0;
723 if( SCIPgetStage(scip) != SCIP_STAGE_TRANSFORMED &&
724 SCIPgetStage(scip) != SCIP_STAGE_PRESOLVING &&
725 SCIPgetStage(scip) != SCIP_STAGE_INITSOLVE )
726 {
727 nNodesLeft = SCIPgetNNodesLeft(scip);
728 }
729 scipParaSolver->sendSolverState(nNodes, nNodesLeft, bestDualBoundValue, detTime);
732 nNodes > 2 )
733 {
734 dynamic_cast<UG::BbParaNode *>(scipParaSolver->getCurrentNode())->setMergingStatus(3); // cannot be merged: this is a dummy status
735 SCIP_CALL_ABORT( SCIPinterruptSolve(scip) );
736 return SCIP_OKAY;
737 }
739 && ( !needToSendNode )
745 SCIPgetDepth(scip) > scipParaSolver->getAggresivePresolvingDepth() )
746 )
747 {
750 }
751 }
752 }
753
756 ( nNodes < scipParaSolver->getNStopSolvingMode() ) &&
757 ( bestDualBoundValue - scipParaSolver->getLcBestDualBoundValue() ) > 0.0 &&
758 REALABS( ( bestDualBoundValue - std::max(scipParaSolver->getLcBestDualBoundValue(),-SCIPinfinity(scip) ) )
760 {
762 {
766 {
767 scipParaSolver->sendAnotherNodeRequest(bestDualBoundValue); // throw away nodes
768 }
769 }
771 {
773 {
775 }
776 }
777 else
778 {
779 THROW_LOGICAL_ERROR2("Invalid big dual gap handling strategy. startegy = ",
781 }
782 }
783
786 ( bestDualBoundValue - scipParaSolver->getLcBestDualBoundValue() ) > 0.0 &&
787 REALABS( ( bestDualBoundValue - scipParaSolver->getLcBestDualBoundValue() )
790 {
792 {
795 nNodes < scipParaSolver->getNStopSolvingMode() ) )
796 {
797 scipParaSolver->sendAnotherNodeRequest(bestDualBoundValue); // throw away nodes
798 }
799 }
801 {
803 {
805 }
806 }
807 else
808 {
809 THROW_LOGICAL_ERROR2("Invalid big dual gap handling strategy. startegy = ",
811 }
812 }
813 /*******************************************************************
814 * if new ParaNode was received or Interrupt message was received, *
815 * stop solving the current ParaNode *
816 ******************************************************************/
817 if( cloned ||
818 ( SCIPeventGetType(event) != SCIP_EVENTTYPE_NODEFOCUSED
820 {
821 return SCIP_OKAY; // process until SCIP_EVENTTYPE_NODEFOCUSED event
822 }
823
827 )
828 {
830 {
831 return SCIP_OKAY;
832 }
833 else
834 {
836 }
837 }
838
839 /******************************************************************
840 * if node depth is smaller than that specified by parameter,
841 * not to send nodes and keep them.
842 *****************************************************************/
843 if( SCIPnodeGetDepth( SCIPgetCurrentNode( scip ) )
846 {
847 return SCIP_OKAY;
848 }
849
850 /*******************************************************************
851 * if ParaNode transfer has been requested, send a ParaNode *
852 ******************************************************************/
853 if( ( needToSendNode &&
854 (
855 SCIPgetNNodesLeft( scip ) > scipParaSolver->getThresholdValue(SCIPgetNNodes(scip)) ||
857 ( SCIPgetNNodesLeft( scip ) > 1 &&
859 ( !scipParaSolver->isRampUp() &&
860 ( bestDualBoundValue - scipParaSolver->getLcBestDualBoundValue() < 0.0 ||
861 ( ( bestDualBoundValue - scipParaSolver->getLcBestDualBoundValue() ) > 0.0 &&
862 ( REALABS( ( bestDualBoundValue - scipParaSolver->getLcBestDualBoundValue() )
864 )
865 )
866 )
867 )
868 )
869 )
870 )
875 || ( !scipParaSolver->isRacingStage() &&
879 SCIPgetDepth(scip) > scipParaSolver->getAggresivePresolvingDepth() )
880 )
881 {
884 {
886 {
890 ( bestDualBoundValue > scipParaSolver->getTargetBound() ) ) )
891 {
893 }
894 }
895 else
896 {
897 return SCIP_OKAY;
898 }
899
900 }
901 else
902 {
903 assert( nNodes <=2 );
904 return SCIP_OKAY;
905 }
906 }
907
909 {
910 if( !scipParaSolver->isRampUp() )
911 {
912 // if( ( !scipParaSolver->isWarmStarted() ) && scipParaSolver->isRacingRampUp() )
914 {
916 {
918 // if( originalSelectionStrategy && SCIPgetNNodesLeft(scip) > scipParaSolver->getNPreviousNodesLeft() )
919 {
921 }
922 needToSendNode = true;
923 }
924 }
925 else
926 {
928 && paraComm->getRank() == 1 ) ||
929 bestDualBoundValue - scipParaSolver->getLcBestDualBoundValue() < 0.0 ||
930 ( ( bestDualBoundValue - scipParaSolver->getLcBestDualBoundValue() ) > 0.0 &&
931 ( REALABS( ( bestDualBoundValue - scipParaSolver->getLcBestDualBoundValue() )
933 {
935 // if( originalSelectionStrategy && SCIPgetNNodesLeft(scip) > scipParaSolver->getNPreviousNodesLeft() )
936 {
938 }
941 {
942 needToSendNode = true;
943 }
944 else
945 {
946 if( needToSendNode ) needToSendNode = false;
947 else needToSendNode = true;
948 }
949 }
950 else
951 {
952 needToSendNode = false;
953 }
954 }
955 }
956 else
957 {
958 /*********************************************
959 * check if solver is in collecting mode *
960 ********************************************/
962 {
964 // if( originalSelectionStrategy && SCIPgetNNodesLeft(scip) > scipParaSolver->getNPreviousNodesLeft() )
965 {
967 }
969 {
970 needToSendNode = true;
971 }
972 else
973 {
976 {
977 needToSendNode = true;
978 }
979 else
980 {
981 if( needToSendNode ) needToSendNode = false;
982 else needToSendNode = true;
983 }
984 }
985 }
986 else
987 {
989 {
990 SCIP_NODESEL *nodesel = SCIPgetNodesel(scip);
991 SCIP_CALL_ABORT( SCIPsetNodeselStdPriority(scip, nodesel,
994 scipParaSolver->setNPreviousNodesLeft(SCIPgetNNodesLeft(scip));
995 }
996 needToSendNode = false; // In iReceive, more than on collecting mode message may be received
997 }
998 }
999 }
1000
1001 return SCIP_OKAY;
1002}
1003
1004// void
1005bool
1007 SCIP* scip
1008 )
1009{
1010 SCIP_NODE* node = SCIPgetCurrentNode( scip );
1011 int depth = SCIPnodeGetDepth( node );
1012 SCIP_VAR **branchVars = new SCIP_VAR*[depth];
1013 SCIP_Real *branchBounds = new SCIP_Real[depth];
1014 SCIP_BOUNDTYPE *boundTypes = new SCIP_BOUNDTYPE[depth];
1015 int nBranchVars;
1016 SCIPnodeGetAncestorBranchings( node, branchVars, branchBounds, boundTypes, &nBranchVars, depth );
1017 if( nBranchVars > depth ) // did not have enough memory, then reallocate
1018 {
1019 delete [] branchVars;
1020 delete [] branchBounds;
1021 delete [] boundTypes;
1022 branchVars = new SCIP_VAR*[nBranchVars];
1023 branchBounds = new SCIP_Real[nBranchVars];
1024 boundTypes = new SCIP_BOUNDTYPE[nBranchVars];
1025 SCIPnodeGetAncestorBranchings( node, branchVars, branchBounds, boundTypes, &nBranchVars, nBranchVars );
1026 }
1027
1031 {
1032 int nVars = SCIPgetNVars(scip);
1033 SCIP_VAR **vars = SCIPgetVars(scip);
1034 int *iBranchVars = new int[nBranchVars];
1035 /* create the variable mapping hash map */
1036 SCIP_HASHMAP* varmapLb;
1037 SCIP_HASHMAP* varmapUb;
1038 SCIP_CALL_ABORT( SCIPhashmapCreate(&varmapLb, SCIPblkmem(scip), nVars) );
1039 SCIP_CALL_ABORT( SCIPhashmapCreate(&varmapUb, SCIPblkmem(scip), nVars) );
1040 for( int i = 0; i < nBranchVars; i++ )
1041 {
1042 iBranchVars[i] = i;
1043 if( boundTypes[i] == SCIP_BOUNDTYPE_LOWER )
1044 {
1045 if( !SCIPhashmapGetImage(varmapLb, branchVars[i]) )
1046 {
1047 SCIP_CALL_ABORT( SCIPhashmapInsert(varmapLb, branchVars[i], &iBranchVars[i] ) );
1048 }
1049 }
1050 else
1051 {
1052 if( !SCIPhashmapGetImage(varmapUb, branchVars[i]) )
1053 {
1054 SCIP_CALL_ABORT( SCIPhashmapInsert(varmapUb, branchVars[i], &iBranchVars[i] ) );
1055 }
1056 }
1057 }
1058 SCIP_VAR **preBranchVars = branchVars;
1059 SCIP_Real *preBranchBounds = branchBounds;
1060 SCIP_BOUNDTYPE *preBboundTypes = boundTypes;
1061 branchVars = new SCIP_VAR*[nBranchVars+nVars*2];
1062 branchBounds = new SCIP_Real[nBranchVars+nVars*2];
1063 boundTypes = new SCIP_BOUNDTYPE[nBranchVars+nVars*2];
1064 for( int i = 0; i < nBranchVars; i++ )
1065 {
1066 branchVars[i] = preBranchVars[i];
1067 branchBounds[i] = preBranchBounds[i];
1068 boundTypes[i] = preBboundTypes[i];
1069 }
1070 int *iBranchVar = NULL;
1071 for( int i = 0; i < nVars; i++ )
1072 {
1075 {
1076 continue;
1077 }
1078 iBranchVar = (int *)SCIPhashmapGetImage(varmapLb, vars[i]);
1079 if( iBranchVar )
1080 {
1081 // assert( EPSGE(preBranchBounds[*iBranchVar], SCIPvarGetLbLocal(vars[i]) ,DEFAULT_NUM_EPSILON ) );
1082 if( EPSLT(preBranchBounds[*iBranchVar], SCIPvarGetLbLocal(vars[i]) ,DEFAULT_NUM_EPSILON ) )
1083 {
1084 branchBounds[*iBranchVar] = SCIPvarGetLbLocal(vars[i]); // node is current node
1085 if ( EPSGT(branchBounds[*iBranchVar], SCIPvarGetUbGlobal(vars[i]), DEFAULT_NUM_EPSILON) ) abort();
1086 }
1087 }
1088 else
1089 {
1090 if( EPSGT( SCIPvarGetLbLocal(vars[i]), SCIPvarGetLbGlobal(vars[i]), MINEPSILON ) )
1091 {
1092 branchVars[nBranchVars] = vars[i];
1093 branchBounds[nBranchVars] = SCIPvarGetLbLocal(vars[i]);
1094 boundTypes[nBranchVars] = SCIP_BOUNDTYPE_LOWER;
1095 if ( EPSGT(branchBounds[nBranchVars], SCIPvarGetUbGlobal(vars[i]), DEFAULT_NUM_EPSILON) ) abort();
1096 nBranchVars++;
1097 }
1098 }
1099 iBranchVar = (int *)SCIPhashmapGetImage(varmapUb, vars[i]);
1100 if( iBranchVar )
1101 {
1102 // assert( EPSLE(preBranchBounds[*iBranchVar], SCIPvarGetUbLocal(vars[i]) ,DEFAULT_NUM_EPSILON ) );
1103 if( EPSGT(preBranchBounds[*iBranchVar], SCIPvarGetUbLocal(vars[i]) ,DEFAULT_NUM_EPSILON ) )
1104 {
1105 branchBounds[*iBranchVar] = SCIPvarGetUbLocal(vars[i]); // node is current node
1106 if ( EPSLT(branchBounds[*iBranchVar], SCIPvarGetLbGlobal(vars[i]),DEFAULT_NUM_EPSILON) ) abort();
1107 }
1108 }
1109 else
1110 {
1111 if( EPSLT( SCIPvarGetUbLocal(vars[i]), SCIPvarGetUbGlobal(vars[i]), MINEPSILON ) )
1112 {
1113 branchVars[nBranchVars] = vars[i];
1114 branchBounds[nBranchVars] = SCIPvarGetUbLocal(vars[i]);
1115 boundTypes[nBranchVars] = SCIP_BOUNDTYPE_UPPER;
1116 if ( EPSLT(branchBounds[nBranchVars], SCIPvarGetLbGlobal(vars[i]),DEFAULT_NUM_EPSILON) ) abort();
1117 nBranchVars++;
1118 }
1119 }
1120 }
1121 SCIPhashmapFree(&varmapLb);
1122 SCIPhashmapFree(&varmapUb);
1123 delete [] preBranchVars;
1124 delete [] preBranchBounds;
1125 delete [] preBboundTypes;
1126 delete [] iBranchVars;
1127 }
1128
1129 /** check root node solvability */
1131 {
1132 SCIP_CALL_ABORT( SCIPtransformProb(scipToCheckRootSolvability) );
1133 SCIP_VAR **copyVars = SCIPgetVars(scipToCheckRootSolvability);
1134 for(int v = 0; v < nBranchVars; v++)
1135 {
1136 int index = SCIPvarGetProbindex(branchVars[v]);
1137 assert(index != -1);
1138 assert(std::string(SCIPvarGetName(branchVars[v]))==std::string(SCIPvarGetName(copyVars[index])));
1139 if( boundTypes[v] == SCIP_BOUNDTYPE_LOWER )
1140 {
1141 SCIP_CALL_ABORT(SCIPchgVarLbGlobal(scipToCheckRootSolvability,copyVars[index], branchBounds[v]));
1142 }
1143 else if (boundTypes[v] == SCIP_BOUNDTYPE_UPPER)
1144 {
1145 SCIP_CALL_ABORT(SCIPchgVarUbGlobal(scipToCheckRootSolvability,copyVars[index], branchBounds[v]));
1146 }
1147 else
1148 {
1149 THROW_LOGICAL_ERROR2("Invalid bound type: type = ", static_cast<int>(boundTypes[v]));
1150 }
1151 }
1152 SCIP_CALL_ABORT(SCIPsetLongintParam(scipToCheckRootSolvability,"limits/nodes", 1));
1153 SCIP_CALL_ABORT(SCIPsetObjlimit(scipToCheckRootSolvability, scipParaSolver->getGlobalBestIncumbentValue()));
1154 SCIP_CALL_ABORT(SCIPsolve(scipToCheckRootSolvability));
1155
1156 SCIP_STATUS status = SCIPgetStatus(scipToCheckRootSolvability);
1157
1158 switch(status)
1159 {
1160 case SCIP_STATUS_OPTIMAL :
1161 {
1162 SCIP_SOL *bestSol = SCIPgetBestSol( scip );
1163 int nVars = SCIPgetNOrigVars(scip);
1164 SCIP_VAR **vars = SCIPgetOrigVars(scip);
1165 SCIP_Real *vals = new SCIP_Real[nVars];
1166 SCIP_CALL_ABORT( SCIPgetSolVals(scip, bestSol, nVars, vars, vals) );
1167 DEF_SCIP_PARA_COMM( scipParaComm, paraComm);
1169 scipParaComm->createScipParaSolution(
1171 SCIPgetSolOrigObj(scip, bestSol),
1172 nVars,
1173 vars,
1174 vals
1175 )
1176 );
1177 delete [] vals;
1178 /** remove the node sent from SCIP environment */
1179 SCIP_CALL_ABORT( SCIPcutoffNode( scip, node) );
1180 needToSendNode = false; // This means that a node is sent in the next time again,
1181 // because this flag is flipped when collecting mode is checked
1183 break;
1184 }
1185 case SCIP_STATUS_INFEASIBLE :
1186 case SCIP_STATUS_INFORUNBD :
1187 {
1188 /** remove the node sent from SCIP environment */
1189 SCIP_CALL_ABORT( SCIPcutoffNode( scip, node ) );
1190 needToSendNode = false; // This means that a node is sent in the next time again,
1191 // because this flag is flipped when collecting mode is checked
1193 break;
1194 }
1195 case SCIP_STATUS_NODELIMIT :
1196 {
1197 sendNode(scip, node, depth, nBranchVars, branchVars, branchBounds, boundTypes);
1198 break;
1199 }
1200 default:
1201 THROW_LOGICAL_ERROR2("Invalid status after root solvability check: status = ", static_cast<int>(status));
1202 }
1203
1204 SCIP_CALL_ABORT( SCIPfreeTransform(scipToCheckRootSolvability) );
1205 }
1206 else
1207 {
1208 if( scipParaSolver->isCopyIncreasedVariables() ) // this may not need, but only for this error occurred so far.
1209 {
1210 if( !ifFeasibleInOriginalProblem(scip, nBranchVars, branchVars, branchBounds) )
1211 {
1212 delete [] branchVars;
1213 delete [] branchBounds;
1214 delete [] boundTypes;
1215 return false;
1216 }
1217 }
1218 sendNode(scip, node, depth, nBranchVars, branchVars, branchBounds, boundTypes);
1219 }
1220
1221 delete [] branchVars;
1222 delete [] branchBounds;
1223 delete [] boundTypes;
1224
1225 return true;
1226}
1227
1228void
1230 SCIP *scip,
1231 SCIP_NODE* node,
1232 int depth,
1233 int nNewBranchVars,
1234 SCIP_VAR **newBranchVars,
1235 SCIP_Real *newBranchBounds,
1236 SCIP_BOUNDTYPE *newBoundTypes
1237 )
1238{
1239
1240 SCIP_CONS** addedcons = 0;
1241 int addedconsssize = SCIPnodeGetNAddedConss(node);
1242 int naddedconss = 0;
1243 if( addedconsssize > 0 )
1244 {
1245 SCIP_CALL_ABORT( SCIPallocBufferArray(scip, &addedcons, addedconsssize) );
1246 SCIPnodeGetAddedConss(node, addedcons, &naddedconss, addedconsssize);
1247 }
1248
1249
1250 DEF_SCIP_PARA_COMM( scipParaComm, paraComm);
1251 ScipParaDiffSubproblem *diffSubproblem = scipParaComm->createScipParaDiffSubproblem(
1252 scip,
1254 nNewBranchVars,
1255 newBranchVars,
1256 newBranchBounds,
1257 newBoundTypes,
1258 naddedconss,
1259 addedcons
1260 );
1261
1262 if( naddedconss )
1263 {
1264 SCIPfreeBufferArray(scip, &addedcons);
1265 }
1266
1267
1268 long long n = SCIPnodeGetNumber( node );
1269 double dualBound = SCIPgetDualbound(scip);
1270 // if( SCIPisObjIntegral(scip) )
1271 // {
1272 // dualBound = ceil(dualBound);
1273 // }
1274 assert(SCIPisFeasGE(scip, SCIPnodeGetLowerbound(node) , SCIPgetLowerbound(scip)));
1275 double estimateValue = SCIPnodeGetEstimate( node );
1276 assert(SCIPisFeasGE(scip, estimateValue, SCIPnodeGetLowerbound(node) ));
1277#ifdef UG_DEBUG_SOLUTION
1278 SCIP_Bool valid = 0;
1279 SCIP_CALL_ABORT( SCIPdebugSolIsValidInSubtree(scip, &valid) );
1280 diffSubproblem->setOptimalSolIndicator(valid);
1281 std::cout << "* R." << scipParaSolver->getRank() << ", debug = " << SCIPdebugSolIsEnabled(scip) << ", valid = " << valid << std::endl;
1282#endif
1283 scipParaSolver->sendParaNode(n, depth, dualBound, estimateValue, diffSubproblem);
1284
1285 /** remove the node sent from SCIP environment */
1286#ifdef UG_DEBUG_SOLUTION
1287 if( valid )
1288 {
1289 SCIPdebugSolDisable(scip);
1290 std::cout << "R." << paraComm->getRank() << ": disable debug, node which contains optmal solution is sent." << std::endl;
1291 }
1292#endif
1293 SCIP_CALL_ABORT( SCIPcutoffNode( scip, node) );
1294}
1295
1296void
1298 SCIP* scip
1299 )
1300{
1301 scipParaSolver->setNPreviousNodesLeft(SCIPgetNNodesLeft(scip));
1302 int numnodesels = SCIPgetNNodesels( scip );
1303 SCIP_NODESEL** nodesels = SCIPgetNodesels( scip );
1304 int i;
1305 for( i = 0; i < numnodesels; ++i )
1306 {
1307 std::string nodeselname(SCIPnodeselGetName(nodesels[i]));
1308 if( std::string(nodeselname) == std::string(changeNodeSelName) )
1309 {
1310 SCIP_CALL_ABORT( SCIPsetNodeselStdPriority(scip, nodesels[i], 536870911 ) );
1312 int maxrestarts;
1313 SCIP_CALL_ABORT( SCIPgetIntParam(scip, "presolving/maxrestarts", &maxrestarts) );
1314 if( maxrestarts != 0 )
1315 {
1316 SCIP_CALL_ABORT( SCIPsetIntParam(scip, "presolving/maxrestarts", 0) );
1317 }
1318 break;
1319 }
1320 }
1321 assert( i != numnodesels );
1322}
1323
1324bool
1326 SCIP *scip,
1327 int nNewBranchVars,
1328 SCIP_VAR **newBranchVars,
1329 SCIP_Real *newBranchBounds)
1330{
1331
1332 bool feasible = true;
1333 SCIP_Real *branchBounds = new SCIP_Real[nNewBranchVars];
1334 for( int v = nNewBranchVars -1 ; v >= 0; --v )
1335 {
1336 SCIP_VAR *transformVar = newBranchVars[v];
1337 SCIP_Real scalar = 1.0;
1338 SCIP_Real constant = 0.0;
1339 SCIP_CALL_ABORT( SCIPvarGetOrigvarSum(&transformVar, &scalar, &constant ) );
1340 if( transformVar == NULL ) continue;
1341 // assert( scalar == 1.0 && constant == 0.0 );
1342 branchBounds[v] = ( newBranchBounds[v] - constant ) / scalar;
1343 if( SCIPvarGetType(transformVar) != SCIP_VARTYPE_CONTINUOUS
1344 && SCIPvarGetProbindex(transformVar) < scipParaSolver->getNOrgVars() )
1345 {
1346 if( !(SCIPisLE(scip,scipParaSolver->getOrgVarLb(SCIPvarGetProbindex(transformVar)), branchBounds[v]) &&
1347 SCIPisGE(scip,scipParaSolver->getOrgVarUb(SCIPvarGetProbindex(transformVar)), branchBounds[v])) )
1348 {
1349 feasible = false;
1350 break;
1351 }
1352 }
1353 }
1354 delete [] branchBounds;
1355
1356 return feasible;
1357}
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.