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 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"
53 #include "scipParaDiffSubproblem.h"
54 
55 using namespace ParaSCIP;
56 
57 void
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 
120 SCIP_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  {
544  if( !scipParaSolver->isRacingStage() )
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  {
578  && ( !scipParaSolver->isInterrupting() )
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 ) // 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 )
741  && !( !scipParaSolver->isRacingStage()
745  SCIPgetDepth(scip) > scipParaSolver->getAggresivePresolvingDepth() )
746  )
747  {
750  }
751  }
752  }
753 
754  if( scipParaSolver->getNStopSolvingMode() > 0 &&
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  {
793  if( scipParaSolver->getNStopSolvingMode() < 0 ||
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  {
920  changeSearchStrategy(scip);
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  {
937  changeSearchStrategy(scip);
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  {
966  changeSearchStrategy(scip);
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
1005 bool
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 
1228 void
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 
1296 void
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 ) );
1311  originalSelectionStrategy = false;
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 
1324 bool
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 }
bool newParaNodeExists()
check if a new ParaNode was received or not
Definition: bbParaSolver.h:883
void setTightenedVarUb(int i, double v)
ScipParaObjLimitUpdator * scipParaObjLimitUpdator
static const int NumberOfNodesKeepingInRootSolver
int getOriginalIndex(int index)
double getLcBestDualBoundValue()
get LoadCorrdinator best dual bound value
Definition: bbParaSolver.h:746
int getProbIndex(int index)
bool isBreaking()
check if Solver is in racing stage or not
static const int GenerateReducedCheckpointFiles
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
#define DEFAULT_NUM_EPSILON
Definition: paraDef.h:49
bool isAggressivePresolvingSpecified()
check if aggressive presolving is specified
ParaInitialStat extension for SCIP solver.
static const int FinalCheckpointGeneratingTime
Definition: paraParamSet.h:108
Event handlr for communication point.
void countInPrecheckSolvedParaNodes()
count ParaNode solved at root node in pre-check
static const int RootNodeSolvabilityCheck
void setRootNodeSimplexIter(int iter)
set number of simplex iteration at root node
double getGlobalBestIncumbentValue()
get global best incumbent value
Definition: bbParaSolver.h:971
bool isRacingRampUp()
check if this solver is in racing ramp-up or not
int getSubMipDepth()
get depth of sub-MIP root node in global search tree
int getBigDualGapSubtreeHandlingStrategy()
get big dual gap subtree handling strategy
bool isAggressiveCollecting()
check if Solver is in aggressive collecting mode or not
Definition: bbParaSolver.h:903
bool isRacingInterruptRequested()
check if racing interrupt was requested or not
Definition: bbParaSolver.h:834
bool isRootTask()
check if root task or not
Definition: paraTask.h:624
ParaSolution extension for SCIP solver.
int getAggresivePresolvingDepth()
get depth to apply aggressive presolving
static const int ControlCollectingModeOnSolverSide
virtual void iReceiveMessages()
non-blocking receive messages
bool isRacingStage()
check if Solver is in racing stage or not
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
virtual void setRootNodeTime()
set root node computing time
void setNotEnoughGain()
set dual bound gain is not enough
bool isCollecingInterrupt()
check if collecting interrupt (interrupt with collecting all nodes) is requested or not ...
Definition: bbParaSolver.h:844
#define REALABS(x)
Definition: paraDef.h:165
static const int TagLbBoundTightenedBound
Definition: bbParaTagDef.h:63
ParaDeterministicTimer * getDeterministicTimer()
get deterministic timer object
Definition: paraSolver.h:739
double getTightenedVarUb(int i)
virtual void sendAnotherNodeRequest(double bestDualBoundValue)
send another node request
#define PARA_COMM_CALL(paracommcall)
Definition: paraComm.h:47
static const int Deterministic
Definition: paraParamSet.h:76
virtual int getRank()=0
get rank of this process or this thread depending on run-time environment
bool isTerminationRequested()
check if termination was requested or not
Definition: paraSolver.h:589
int getCurrentSolivingNodeMergingStatus()
get current solving node merging status
int getAggresivePresolvingStopDepth()
get depth to stop aggressive presolving
static const int ParaDOUBLE
Definition: paraComm.h:76
double getTargetBound()
get target bound for breaking
virtual double getElapsedTime()=0
getter of the deterministic time
void passToken(int rank)
pass token to the next process
bool isGivenGapReached()
check if given gap is reached or not
static const int NoAlternateSolving
double getRealParamValue(int param)
for real parameters
bool ifFeasibleInOriginalProblem(SCIP *scip, int nNewBranchVars, SCIP_VAR **newBranchVars, SCIP_Real *newBranchBounds)
ParaTask * getCurrentNode()
get current ParaNode object
Definition: bbParaSolver.h:981
bool isRacingWinner()
check if this solver is in racing ramp-up or not
Definition: paraSolver.h:530
virtual void waitMessageIfNecessary()
wait a notification id message if it is needed to synchronize with LoadCoordinaor ...
virtual void sendLocalSolution()
send solution found in this Solver
virtual int getRank()
get rank of this Solver
static const int DualBoundGainBranchRatio
void resetBreakingInfo()
reset breaking information
#define EPSLT(x, y, eps)
Definition: paraDef.h:167
double getPreviousCommTime()
get previous communication time for deterministic execution
Definition: paraSolver.h:828
static const int TagUbBoundTightenedIndex
Definition: bbParaTagDef.h:64
void setPreviousCommTime(double detTime)
set previous communication time for deterministic execution
Definition: paraSolver.h:817
void setTightenedVarLb(int i, double v)
double getCurrentSolvingNodeInitialDualBound()
get initial dual bound of current solving node
bool isInCollectingMode()
check if Solver is in collecting mode or not
Definition: bbParaSolver.h:893
double getTightenedVarLb(int i)
static const int TagAllowToBeInCollectingMode
Definition: bbParaTagDef.h:57
#define THROW_LOGICAL_ERROR2(msg1, msg2)
Definition: paraDef.h:69
double getElapsedTimeOfNodeSolving()
the following functions may be called from callback routines of the target Solver ...
Definition: bbParaSolver.h:726
virtual bool saveIfImprovedSolutionWasFound(ParaSolution *sol)
save improved solution if it was found in this Solver
static const int NoAllBoundChangesTransferInRacing
virtual int getThresholdValue(int nNodes)
get threshold value to send ParaNodes to LoadCoordinator
double getAverageDualBoundGain()
get average dual bound gain
static const int ParaBYTE
Definition: paraComm.h:79
double getBoundGapForCollectingMode()
get bound gap for collecting mode
Definition: bbParaSolver.h:799
class BbParaNode
Definition: bbParaNode.h:61
bool isRampUp()
check if this solver is ramp-up or not
Definition: paraSolver.h:509
static const int NotificationInterval
Definition: paraParamSet.h:105
void processNewSolution(SCIP *scip, SCIP_EVENT *event)
#define EPSGT(x, y, eps)
Definition: paraDef.h:169
static const int AllowableRegressionRatioInMerging
void sendNode(SCIP *scip, SCIP_NODE *node, int depth, int nBranchVars, SCIP_VAR **branchVars, SCIP_Real *branchBounds, SCIP_BOUNDTYPE *boundTypes)
virtual void updatePendingSolution()
update pending solution
Definition: paraSolver.h:759
bool isDualBoundGainTestNeeded()
check if dual bound gain needs to be tested or not
static const int RampUpPhaseProcess
bool isCollectingAllNodes()
check if Solver is sending all nodes to LoadCoordinaor or not
virtual bool notificationIsNecessary()
check if a notification message needs to send or not
static const int CommunicateTighterBoundsInRacing
virtual int send(void *bufer, int count, const int datatypeId, int dest, const int tag)=0
send function for standard ParaData types
static const int TagLbBoundTightenedIndex
Definition: bbParaTagDef.h:62
void setSendBackAllNodes()
set counter and flag to indicate that all nodes are sent to LoadCooordinator
int getNStopSolvingMode()
get number of nodes to stop solving. This number is not used to decide stop solving. It is used a part of conditions.
Definition: bbParaSolver.h:757
static const int TagUbBoundTightenedBound
Definition: bbParaTagDef.h:65
void setNPreviousNodesLeft(long long n)
virtual SCIP_RETCODE scip_exec(SCIP *scip, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENT *event, SCIP_EVENTDATA *eventdata)
#define MINEPSILON
Definition: paraDef.h:50
static const int ParaINT
Definition: paraComm.h:66
bool waitToken(int rank)
wait token for deterministic mode
int getIntParamValue(int param)
for int parameters
virtual void sendSolverState(long long nNodesSolved, int nNodesLeft, double bestDualBoundValue, double detTime)
send Solver state to LoadCoordinator
bool isGlobalIncumbentUpdated()
check if global incumbent value is updated or not
Definition: bbParaSolver.h:815
ParaParamSet * getParaParamSet()
get ParaParamSet object
static const int BreakFirstSubtree
static const int EventWeightedDeterministic
virtual void update(double value)=0
update function of the deterministic time. the deterministic time is a kind of counter ...
virtual void sendParaNode(long long n, int depth, double dualBound, double estimateValue, ParaDiffSubproblem *diffSubproblem)
send a branch-and-bound node as ParaNode to LoadCoordinator
static const int AllBoundChangesTransfer
static const int DualBoundGainTest
bool isAnotherNodeIsRequested()
check if another node is requested or not
int getNSendInCollectingMode()
get number of ParaNodes already sent in a collecting mode
static const int KeepNodesDepth
bool isManyNodesCollectionRequested()
check if many nodes collection was requested or not
Definition: bbParaSolver.h:913
#define DEF_SCIP_PARA_COMM(scip_para_comm, comm)
bool isEnoughGainObtained()
check if dual bound gains enough or not
bool getBoolParamValue(int param)
for bool parameters
bool isTransferLimitReached()
check if the number of ParaNodes sent is reached to transfer limit specified