Scippy

UG

Ubiquity Generator framework

scipParaInitiator.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 scipParaInitiator.cpp
27  * @brief ParaInitiator extension for SCIP solver.
28  * @author Yuji Shinano
29  *
30  *
31  *
32  */
33 
34 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
35 
36 // #define UG_SCIP_SOL_FEASIBILITY_CHECK_IN_LC
37 
38 #include <cctype>
39 #include <sstream>
40 #include "scipParaInstance.h"
41 #include "scipParaInitiator.h"
42 #include "scipParaObjMessageHdlr.h"
43 #include "scipParaInitialStat.h"
44 #include "scipParaParamSet.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 #ifdef __linux__
52 #include "stdlib.h"
53 #include "stdio.h"
54 #include "string.h"
55 #endif
56 
57 // #define UG_SCIP_SOL_FEASIBILITY_CHECK_IN_LC
58 
59 using namespace UG;
60 using namespace ParaSCIP;
61 
62 #if ( defined(_COMM_PTH) || defined(_COMM_CPP11) )
63 extern long long virtualMemUsedAtLc;
64 extern double memoryLimitOfSolverSCIP;
65 #ifdef __linux__
66 static int parseLine(char* line){
67  // This assumes that a digit will be found and the line ends in " Kb".
68  int i = strlen(line);
69  const char* p = line;
70  while (*p <'0' || *p > '9') p++;
71  line[i-3] = '\0';
72  i = atoi(p);
73  return i;
74 }
75 
76 static long long getVmSize(){
77  FILE* file = fopen("/proc/self/status", "r");
78  long long result = -1;
79  char line[128];
80 
81  while (fgets(line, 128, file) != NULL){
82  if (strncmp(line, "VmSize:", 7) == 0){
83  result = parseLine(line);
84  break;
85  }
86  }
87  fclose(file);
88  return result*1024; // result value is in KB
89 }
90 #endif
91 #endif
92 
93 bool
94 ScipParaInitiator::addRootNodeCuts(
95  )
96 {
97  SCIP_Longint originalLimitsNodes;
98  SCIP_CALL_ABORT( SCIPgetLongintParam(scip, "limits/nodes", &originalLimitsNodes) );
99  SCIP_CALL_ABORT( SCIPsetLongintParam(scip, "limits/nodes", 1) );
100  if( scipDiffParamSetRoot ) scipDiffParamSetRoot->setParametersInScip(scip);
101  if( paraParams->getRealParamValue(UG::TimeLimit) > 0.0 )
102  {
103  double timeRemains = std::max( 0.0, (paraParams->getRealParamValue(UG::TimeLimit) - timer->getElapsedTime()) );
104  // SCIP_CALL_ABORT( SCIPsetIntParam(scip,"timing/clocktype", 2) );
105  SCIP_CALL_ABORT( SCIPsetRealParam(scip,"limits/time", timeRemains) );
106  }
107  SCIP_RETCODE ret = SCIPsolve(scip);
108  if( ret != SCIP_OKAY )
109  {
110 #ifndef SCIP_THREADSAFE_MESSAGEHDLRS
111  SCIPprintError(ret, NULL);
112 #else
113  SCIPprintError(ret);
114 #endif
115  abort();
116  }
117 
118  /* reset LC parameter settings */
119  SCIP_CALL_ABORT( SCIPresetParams(scip) );
120  if( paraParams->getBoolParamValue(NoPreprocessingInLC) )
121  {
122  SCIP_CALL_ABORT( SCIPsetIntParam(scip, "presolving/maxrounds", 0));
123  }
124  else
125  {
126  if( settingsNameLC )
127  {
128  SCIP_CALL_ABORT( SCIPreadParams(scip, settingsNameLC) );
129  }
130  }
131 
132  /* don't catch control+c */
133  SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "misc/catchctrlc", FALSE) );
134  // Then, solver status should be checked
135  SCIP_STATUS status = SCIPgetStatus(scip);
136  if( status == SCIP_STATUS_OPTIMAL ) // when sub-MIP is solved at root node, the solution may not be saved
137  {
138  return false;
139  }
140  else
141  {
142  if( status == SCIP_STATUS_MEMLIMIT )
143  {
144  std::cout << "Warning: SCIP was interrupted because the memory limit was reached" << std::endl;
145  return false;
146  }
147  if( paraParams->getRealParamValue(UG::TimeLimit) > 0.0 &&
148  timer->getElapsedTime() > paraParams->getRealParamValue(UG::TimeLimit) )
149  {
150  return true; // pretended to add cuts, anyway, timelimit.
151  }
152  }
153 
154  SCIP_CUT** cuts;
155  int ncuts;
156  int ncutsadded;
157 
158  ncutsadded = 0;
159  cuts = SCIPgetPoolCuts(scip);
160  ncuts = SCIPgetNPoolCuts(scip);
161  for( int c = 0; c < ncuts; ++c )
162  {
163  SCIP_ROW* row;
164 
165  row = SCIPcutGetRow(cuts[c]);
166  assert(!SCIProwIsLocal(row));
167  assert(!SCIProwIsModifiable(row));
168  if( SCIPcutGetAge(cuts[c]) == 0 && SCIProwIsInLP(row) )
169  {
170  char name[SCIP_MAXSTRLEN];
171  SCIP_CONS* cons;
172  SCIP_COL** cols;
173  SCIP_VAR** vars;
174  int ncols;
175  int i;
176 
177  /* create a linear constraint out of the cut */
178  cols = SCIProwGetCols(row);
179  ncols = SCIProwGetNNonz(row);
180 
181  SCIP_CALL_ABORT( SCIPallocBufferArray(scip, &vars, ncols) );
182  for( i = 0; i < ncols; ++i )
183  vars[i] = SCIPcolGetVar(cols[i]);
184 
185  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_%d", SCIProwGetName(row), SCIPgetNRuns(scip));
186  SCIP_CALL_ABORT( SCIPcreateConsLinear(scip, &cons, name, ncols, vars, SCIProwGetVals(row),
187  SCIProwGetLhs(row) - SCIProwGetConstant(row), SCIProwGetRhs(row) - SCIProwGetConstant(row),
188  TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE) );
189  SCIP_CALL_ABORT( SCIPaddCons(scip, cons) );
190  SCIP_CALL_ABORT( SCIPreleaseCons(scip, &cons) );
191 
192  SCIPfreeBufferArray(scip, &vars);
193 
194  ncutsadded++;
195  }
196  }
197 
198  // SCIP_CALL_ABORT( SCIPsetLongintParam(scip, "limits/nodes", originalLimitsNodes) );
199 
200  return true;
201 }
202 
203 /** init function */
204 int
205 ScipParaInitiator::init(
206  ParaParamSet *inParaParams,
207  int argc,
208  char** argv
209  )
210 {
211  int i;
212  bool quiet = false;
213 #if ( defined(_COMM_PTH) || defined(_COMM_CPP11) )
214  bool noUpgrade = false;
215 #endif
216  paraParams = inParaParams;
217 
218  probname = argv[2];
219 
220  /********************
221  * Parse parameters *
222  ********************/
223  if( std::string(paraParams->getStringParamValue(SolverSettingsForInitialPresolving)) != "" )
224  {
225  settingsNameLC = const_cast<char*> (paraParams->getStringParamValue(SolverSettingsForInitialPresolving));
226  }
227  if( std::string(paraParams->getStringParamValue(SolverSettingsAtRootNode)) != "" )
228  {
229  settingsNameRoot = const_cast<char*> (paraParams->getStringParamValue(SolverSettingsAtRootNode));
230  }
231  if( std::string(paraParams->getStringParamValue(SolverSettingsExceptRootNode)) != "" )
232  {
233  settingsName = const_cast<char*> (paraParams->getStringParamValue(SolverSettingsExceptRootNode));
234  }
235  if( std::string(paraParams->getStringParamValue(SolverSettingsAtRacing)) != "" )
236  {
237  racingSettingsName = const_cast<char*> (paraParams->getStringParamValue(SolverSettingsAtRacing));
238  }
239  for( i = 3; i < argc; ++i ) /** the first argument is runtime parameter file for ParaSCIP */
240  /** the second argument is problem file name */
241  {
242  if( strcmp(argv[i], "-l") == 0 )
243  {
244  i++;
245  if( i < argc )
246  logname = argv[i];
247  else
248  {
249  std::cerr << "missing log filename after parameter '-l'" << std::endl;
250  exit(1);
251  }
252  }
253  else if( strcmp(argv[i], "-q") == 0 )
254  quiet = true;
255  else if( strcmp(argv[i], "-s") == 0 )
256  {
257  i++;
258  if( i < argc )
259  settingsName = argv[i];
260  else
261  {
262  std::cerr << "missing settings filename after parameter '-s'" << std::endl;
263  exit(1);
264  }
265  }
266  else if( strcmp(argv[i], "-sr") == 0 )
267  {
268  i++;
269  if( i < argc )
270  settingsNameRoot = argv[i];
271  else
272  {
273  std::cerr << "missing settings filename after parameter '-sr'" << std::endl;
274  exit(1);
275  }
276  }
277  else if( strcmp(argv[i], "-sl") == 0 )
278  {
279  i++;
280  if( i < argc )
281  settingsNameLC = argv[i];
282  else
283  {
284  std::cerr << "missing settings filename after parameter '-sl'" << std::endl;
285  exit(1);
286  }
287  }
288  else if( strcmp(argv[i], "-w") == 0)
289  {
290 #ifdef UG_WITH_ZLIB
291  i++;
292  if( i < argc )
293  {
294  prefixWarm = argv[i];
295  char nodesFileName[SCIP_MAXSTRLEN];
296  (void) SCIPsnprintf(nodesFileName, SCIP_MAXSTRLEN, "%s_nodes_LC0.gz", prefixWarm);
297  checkpointTasksStream.open(nodesFileName, std::ios::in | std::ios::binary);
298  if( !checkpointTasksStream.good() ){
299  std::cerr << "ERROR: Opening file `" << nodesFileName << "' failed.\n";
300  exit(1);
301  }
302  }
303  else
304  {
305  std::cerr << "missing settings filename after parameter '-w'" << std::endl;
306  exit(1);
307  }
308 #else
309  std::cerr << "Cannot work with parameter '-w' compiling without zlib" << std::endl;
310  exit(1);
311 #endif
312  }
313  else if( strcmp(argv[i], "-racing") == 0 )
314  {
315  i++;
316  if( i < argc )
317  {
318  racingSettingsName = argv[i];
319  }
320  else
321  {
322  std::cerr << "missing settings filename after parameter '-racing'" << std::endl;
323  exit(1);
324  }
325  }
326  else if ( strcmp(argv[i], "-isol") == 0 )
327  {
328  i++;
329  if( i < argc )
330  {
331  isolname = argv[i];
332  }
333  else
334  {
335  std::cerr << "missing settings filename after parameter '-isol'" << std::endl;
336  exit(1);
337  }
338  }
339  else if( strcmp(argv[i], "-objlimit") == 0 )
340  {
341  i++;
342  if( i < argc )
343  {
344  objlimit = atof(argv[i]);
345  }
346  else
347  {
348  std::cerr << "missing objective limit after parameter '-objlimit'" << std::endl;
349  exit(1);
350  }
351  }
352  else if ( strcmp(argv[i], "-sth") == 0 )
353  {
354  i++; // just omit this parameter and the following number.
355  }
356  else if ( strcmp(argv[i], "-fsol" ) == 0 )
357  {
358  i++;
359  if( i < argc )
360  {
361  solutionFileName = argv[i];
362  }
363  else
364  {
365  std::cerr << "missing solution filename after parameter '-fsol'" << std::endl;
366  exit(1);
367  }
368  }
369 #if ( defined(_COMM_PTH) || defined(_COMM_CPP11) )
370  else if ( strcmp(argv[i], "-nou" ) == 0 )
371  {
372  noUpgrade = true;
373  }
374 #endif
375 #ifdef UG_WITH_UGS
376  else if( strcmp(argv[i], "-ugsc") == 0 )
377  {
378  i++;
379  }
380 #endif
381  else if ( strcmp(argv[i], "-omit1" ) == 0 ) /// to omit this parameter
382  {
383  }
384  else if ( strcmp(argv[i], "-omit2" ) == 0 ) /// to omit this parameter and the following value
385  {
386  i++;
387  }
388  else
389  {
390  THROW_LOGICAL_ERROR3("invalid parameter <", argv[i], ">");
391  }
392  }
393 
394  /*********
395  * Setup *
396  *********/
397  /* initialize SCIP */
398  SCIP_CALL( SCIPcreate(&scip) );
399 
400  /********************
401  * Setup clock type *
402  ********************/
403  SCIP_CALL_ABORT( SCIPsetIntParam(scip,"timing/clocktype", 2) ); // always use wall clock time
404  if( paraParams->getRealParamValue(UG::TimeLimit) > 0.0 )
405  {
406  double timeRemains = std::max( 0.0, (paraParams->getRealParamValue(UG::TimeLimit) - timer->getElapsedTime()) );
407  SCIP_CALL_ABORT( SCIPsetRealParam(scip,"limits/time", timeRemains) );
408  }
409 
410  /*******************
411  * Install plugins *
412  *******************/
413  /* include default SCIP plugins */
414  SCIP_CALL( SCIPincludeDefaultPlugins(scip) );
415  /** user include plugins */
416  includeUserPlugins(scip); // user plugin must set later, since it also sets user parameters
417  // We should include here
418 
419  /* initialize finalDual bound */
420  finalDualBound = -SCIPinfinity(scip);
421  /* output solver version */
422  printSolverVersion(NULL);
423 
424  /* Make sure that copying of symmetry handling constraints works. This is a workaround: Symmetry constraints are
425  * usually not copied, but then we cannot proceed here. Thus, copying is forced. This is correct, but slows down the
426  * sequential SCIP version a little. This solution is here until a better solution has been found. */
427  SCIP_RETCODE paramretcode = SCIPsetBoolParam(scip, "constraints/orbisack/forceconscopy", TRUE);
428  if( paramretcode != SCIP_OKAY && paramretcode != SCIP_PARAMETERUNKNOWN )
429  {
430  SCIP_CALL_ABORT( paramretcode );
431  }
432  paramretcode = SCIPsetBoolParam(scip, "constraints/orbitope/forceconscopy", TRUE);
433  if( paramretcode != SCIP_OKAY && paramretcode != SCIP_PARAMETERUNKNOWN )
434  {
435  SCIP_CALL_ABORT( paramretcode );
436  }
437  paramretcode = SCIPsetBoolParam(scip, "constraints/symresack/forceconscopy", TRUE);
438  if( paramretcode != SCIP_OKAY && paramretcode != SCIP_PARAMETERUNKNOWN )
439  {
440  SCIP_CALL_ABORT( paramretcode );
441  }
442 
443  /*************************************************
444  * set quiet message handler, if it is necessary *
445  *************************************************/
446  messagehdlr = NULL;
447  if( paraParams->getBoolParamValue(Quiet) )
448  {
449  ScipParaObjMessageHdlr* objmessagehdlr = new ScipParaObjMessageHdlr(paraComm, NULL, TRUE, FALSE);
450  SCIP_CALL_ABORT( SCIPcreateObjMessagehdlr(&messagehdlr, objmessagehdlr, TRUE) );
451 #ifndef SCIP_THREADSAFE_MESSAGEHDLRS
452  SCIP_CALL_ABORT( SCIPsetMessagehdlr(messagehdlr) );
453 #else
454  SCIP_CALL_ABORT( SCIPsetMessagehdlr(scip, messagehdlr) );
455  SCIP_CALL_ABORT( SCIPmessagehdlrRelease(&messagehdlr));
456 #endif
457  SCIPmessageSetErrorPrinting(ParaSCIP::scip_errorfunction, (void*) objmessagehdlr);
458  }
459  else
460  {
461  if( logname != NULL || quiet )
462  {
463  if( logname != NULL )
464  {
465  std::ostringstream os;
466  os << logname << paraComm->getRank();
467  logfile = fopen(os.str().c_str(), "a"); // append to log file */
468  if( logfile == NULL )
469  {
470  THROW_LOGICAL_ERROR3("cannot open log file <", logname, "> for writing");
471  }
472  }
473 
474  ScipParaObjMessageHdlr* objmessagehdlr = new ScipParaObjMessageHdlr(paraComm, logfile, quiet, FALSE);
475  SCIP_CALL_ABORT( SCIPcreateObjMessagehdlr(&messagehdlr, objmessagehdlr, TRUE) );
476 #ifndef SCIP_THREADSAFE_MESSAGEHDLRS
477  SCIP_CALL_ABORT( SCIPsetMessagehdlr(messagehdlr) );
478 #else
479  SCIP_CALL_ABORT( SCIPsetMessagehdlr(scip, messagehdlr) );
480  SCIP_CALL_ABORT( SCIPmessagehdlrRelease(&messagehdlr));
481 #endif
482  SCIPmessageSetErrorPrinting(ParaSCIP::scip_errorfunction, (void*) objmessagehdlr);
483  }
484  }
485 
486  if( probname != NULL )
487  {
488  /***********************
489  * Version information *
490  ***********************/
491 #ifndef SCIP_THREADSAFE_MESSAGEHDLRS
492  SCIPprintVersion(NULL);
493 #else
494  SCIPprintVersion(scip, NULL);
495 #endif
496  SCIPinfoMessage(scip, NULL, "\n");
497  /*****************
498  * Load settings *
499  *****************/
500  DEF_SCIP_PARA_COMM( scipParaComm, paraComm );
501  SCIP *paramScip = 0;
502  if( !(settingsName == NULL && settingsNameRoot == NULL && settingsNameLC == NULL ) )
503  {
504  /* initialize SCIP to get diff params */
505  SCIP_CALL( SCIPcreate(&paramScip) );
506  /* include default SCIP plugins */
507  SCIP_CALL( SCIPincludeDefaultPlugins(paramScip) );
508  /** user include plugins */
509  includeUserPlugins(paramScip); // need to install user parameters
510  }
511 
512  if( settingsName != NULL )
513  {
514  SCIP_CALL_ABORT( SCIPreadParams(paramScip, settingsName) );
515  scipDiffParamSet = scipParaComm->createScipDiffParamSet(paramScip);
516  }
517  else
518  {
519  scipDiffParamSet = scipParaComm->createScipDiffParamSet(scip);
520  }
521 
522  if( settingsNameRoot != NULL )
523  {
524  SCIP_CALL_ABORT( SCIPreadParams(scip, settingsNameRoot) );
525  // SCIP_CALL( SCIPresetParams(paramScip) );
526  SCIP_CALL_ABORT( SCIPreadParams(paramScip, settingsNameRoot) );
527  scipDiffParamSetRoot = scipParaComm->createScipDiffParamSet(paramScip);
528  // Root settings are used for LC. They should be a part of root process.
529  // SCIP_CALL( SCIPresetParams(scip) );
530  }
531  else
532  {
533  scipDiffParamSetRoot = scipParaComm->createScipDiffParamSet(scip);
534  }
535 
536  if( settingsNameLC != NULL )
537  {
538  // SCIP_CALL( SCIPresetParams(scip) );
539  SCIP_CALL_ABORT( SCIPreadParams(scip, settingsNameLC) );
540  std::cout << "** applied absolute gap = " << getAbsgapValue() << std::endl;
541  std::cout << "** applied relative gap = " << getGapValue() << std::endl;
542  if( getAbsgapValue() > MINEPSILON || getGapValue() > MINEPSILON )
543  {
544  if( paraParams->getIntParamValue(RampUpPhaseProcess) == 2 )
545  {
546  paraParams->setIntParamValue(RampUpPhaseProcess, 1);
547  std::cout << "** RampUpPhaseProcess is switched to 1, since gap is specified" << std::endl;
548  }
549  }
550  }
551 
552 
553  if( paramScip )
554  {
555  SCIP_CALL_ABORT( SCIPfree(&paramScip) );
556  paramScip = 0;
557  }
558 
559 
560  /**************
561  * Start SCIP *
562  **************/
563  /** user include plugins */
564  // includeUserPlugins(scip); // need to set user plugins: should be set
565 
566  // Problem Creation
567 
568  SCIP_RETCODE retcode = SCIPreadProb(scip, probname, NULL);
569  if( retcode != SCIP_OKAY )
570  {
571  std::cout << "error reading file <" << probname << ">" << std::endl;
572  SCIP_CALL( SCIPfreeProb(scip) );
573  exit(1);
574  }
575 
576  /* transform the problem */
577  SCIP_CALL_ABORT( SCIPtransformProb(scip));
578 
579  /* read initail solution, if it is specified */
580  if( isolname )
581  {
582  // NOTE:
583  // When CPLEX license file cannot find, SCIPtransformProb(scip) may fail
584  // SCIP_CALL_ABORT( SCIPreadSol(scip, isolname) );
585  SCIP_CALL_ABORT( SCIPreadProb(scip, isolname, 0) );
586  }
587 
588  /* change problem name */
589  char *probNameFromFileName;
590  char *temp = new char[strlen(probname)+1];
591  (void) strcpy(temp, probname);
592  SCIPsplitFilename(temp, NULL, &probNameFromFileName, NULL, NULL);
593  SCIP_CALL_ABORT( SCIPsetProbName(scip, probNameFromFileName));
594  delete [] temp;
595 
596  /* presolve problem */
597  if( paraParams->getBoolParamValue(NoPreprocessingInLC) )
598  {
599  if( SCIPfindConshdlr(scip, "pseudoboolean") == NULL || SCIPconshdlrGetNConss(SCIPfindConshdlr(scip, "pseudoboolean")) == 0 ) // this is workaround for a bug.
600  {
601  SCIP_CALL_ABORT( SCIPsetIntParam(scip, "presolving/maxrounds", 0) );
602  std::cout << "No LC presolving is specified." << std::endl;
603  }
604  else
605  {
606  std::cout << "Default LC presolving (default)." << std::endl;
607  }
608  }
609  else
610  {
611  if( settingsNameLC )
612  {
613  SCIP_CALL_ABORT( SCIPreadParams(scip, settingsNameLC) );
614  std::cout << "LC presolving settings file is specified." << std::endl;
615  }
616  else
617  {
618  // SCIP_CALL_ABORT( SCIPsetPresolving(scip, SCIP_PARAMSETTING_FAST, TRUE) );
619  std::cout << "Default LC presolving (default)." << std::endl;
620  }
621  }
622  // SCIP_CALL_ABORT( SCIPsetIntParam(scip, "constraints/quadratic/replacebinaryprod", 0));
623  // SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/nonlinear/reformulate", FALSE));
624 
625  /* don't catch control+c */
626  SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "misc/catchctrlc", FALSE) );
627 
628  /* objlimit is specified */
629  if( EPSLT( objlimit, DBL_MAX, MINEPSILON ) )
630  {
631  SCIP_CALL_ABORT( SCIPsetObjlimit(scip, objlimit) );
632  }
633 
634 
635 // #ifdef _COMM_PTH
636 // SCIP_CALL( SCIPsetBoolParam(scip, "misc/catchctrlc", FALSE) );
637 // #endif
638 
639  SCIP_Bool originalUpgradeKnapsack;
640  SCIP_Bool originalUpgradeLogicor;
641  SCIP_Bool originalUpgradeSetppc;
642  SCIP_Bool originalUpgradeVarbound;
643  bool onlyLinearConss = onlyLinearConsHandler();
644 #ifdef _COMM_MPI_WORLD
645  if( onlyLinearConss )
646  {
647  std::cout << "** Original problem has only linear constraints" << std::endl;
648  }
649  else
650  {
651  std::cout << "** Original problem has non-linear constraints" << std::endl;
652  }
653  if( paraParams->getIntParamValue(UG::InstanceTransferMethod) == 1 )
654  {
655  if( onlyLinearConss )
656  {
657  SCIP_CALL_ABORT( SCIPgetBoolParam(scip, "constraints/linear/upgrade/knapsack", &originalUpgradeKnapsack));
658  SCIP_CALL_ABORT( SCIPgetBoolParam(scip, "constraints/linear/upgrade/logicor", &originalUpgradeLogicor));
659  SCIP_CALL_ABORT( SCIPgetBoolParam(scip, "constraints/linear/upgrade/setppc", &originalUpgradeSetppc));
660  SCIP_CALL_ABORT( SCIPgetBoolParam(scip, "constraints/linear/upgrade/varbound", &originalUpgradeVarbound));
661  SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/knapsack", FALSE));
662  SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/logicor", FALSE));
663  SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/setppc", FALSE));
664  SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/varbound", FALSE));
665  }
666  }
667 #else
668  if( noUpgrade )
669  {
670  SCIP_CALL_ABORT( SCIPgetBoolParam(scip, "constraints/linear/upgrade/knapsack", &originalUpgradeKnapsack));
671  SCIP_CALL_ABORT( SCIPgetBoolParam(scip, "constraints/linear/upgrade/logicor", &originalUpgradeLogicor));
672  SCIP_CALL_ABORT( SCIPgetBoolParam(scip, "constraints/linear/upgrade/setppc", &originalUpgradeSetppc));
673  SCIP_CALL_ABORT( SCIPgetBoolParam(scip, "constraints/linear/upgrade/varbound", &originalUpgradeVarbound));
674  SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/knapsack", FALSE));
675  SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/logicor", FALSE));
676  SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/setppc", FALSE));
677  SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/varbound", FALSE));
678  }
679 #endif
680 
681 #ifdef UG_DEBUG_SOLUTION
682  SCIPdebugSolDisable(scip);
683 #endif
684 
685  // instance = new PARA_INSTANCE_TYPE(scip, paraParams->getIntParamValue(InstanceTransferMethod));
686  /** instance needs to be generated befor presolving **/
687  instance = scipParaComm->createScipParaInstance(scip, paraParams->getIntParamValue(InstanceTransferMethod));
688 
689  std::ostringstream os;
690  if( solutionFileName )
691  {
692  os << solutionFileName;
693  }
694  else
695  {
696  os << paraParams->getStringParamValue(SolutionFilePath);
697  os << instance->getProbName() << ".sol";
698  }
699  solutionFile = fopen(os.str().c_str(), "a"); // if solution file exists, append
700  if( solutionFile == NULL )
701  {
702  THROW_LOGICAL_ERROR3("cannot open solution file <", os.str(), "> for writing");
703  }
704 
705 #if defined(_COMM_PTH) || defined (_COMM_CPP11)
706 #ifdef __linux__
707  long long vmSizeBeforePresolving = getVmSize();
708  virtualMemUsedAtLc = std::max(vmSizeBeforePresolving, (SCIPgetMemTotal(scip) + SCIPgetMemExternEstim(scip)));
709  std::cout << "** Before presolving: virtualMemUsedAtLc = " << virtualMemUsedAtLc << ", getVmSize() = " << getVmSize() << ", SCIPgetMemUsed() = " << SCIPgetMemUsed(scip) << ", SCIPgetMemTotal() = " << SCIPgetMemTotal(scip) << ", SCIPgetMemExternEstim() = " << SCIPgetMemExternEstim(scip) << std::endl;
710 #else
711  virtualMemUsedAtLc = SCIPgetMemTotal(scip) + SCIPgetMemExternEstim(scip);
712  std::cout << "** Before presolving: virtualMemUsedAtLc = " << virtualMemUsedAtLc << ", SCIPgetMemUsed() = " << SCIPgetMemUsed(scip) << ", SCIPgetMemTotal() = " << SCIPgetMemTotal(scip) << ", SCIPgetMemExternEstim() = " << SCIPgetMemExternEstim(scip) << std::endl;
713 #endif
714  // if( (dynamic_cast<ScipParaParamSet *>(paraParams)->getRealParamValue(MemoryLimit) - (virtualMemUsedAtLc*SCIP_FIXED_MEMORY_FACTOR))/(paraComm->getSize()-1) > virtualMemUsedAtLc*SCIP_FIXED_MEMORY_FACTOR )
715  if( dynamic_cast<ScipParaParamSet *>(paraParams)->getRealParamValue(MemoryLimit) > virtualMemUsedAtLc*SCIP_FIXED_MEMORY_FACTOR*paraComm->getSize() )
716  {
717  // SCIP_CALL_ABORT( SCIPsetRealParam(scip, "limits/memory", (dynamic_cast<ScipParaParamSet *>(paraParams)->getRealParamValue(MemoryLimit) - (virtualMemUsedAtLc*SCIP_FIXED_MEMORY_FACTOR))/(paraComm->getSize()-1))); // LC has SCIP env.
718  SCIP_CALL_ABORT( SCIPsetRealParam(scip, "limits/memory", dynamic_cast<ScipParaParamSet *>(paraParams)->getRealParamValue(MemoryLimit) - virtualMemUsedAtLc*SCIP_FIXED_MEMORY_FACTOR*paraComm->getSize()) ); // LC has SCIP env.
719  }
720  else
721  {
722  SCIP_CALL_ABORT( SCIPsetIntParam(scip, "presolving/maxrounds", 0) );
723  std::cout << "** No LC presolving is applied, since memory limit becomes "
724  // << (dynamic_cast<ScipParaParamSet *>(paraParams)->getRealParamValue(MemoryLimit) - (virtualMemUsedAtLc*SCIP_FIXED_MEMORY_FACTOR))/(paraComm->getSize()-1)
725  << dynamic_cast<ScipParaParamSet *>(paraParams)->getRealParamValue(MemoryLimit)
726  << " < "
727  // << virtualMemUsedAtLc*SCIP_FIXED_MEMORY_FACTOR
728  << virtualMemUsedAtLc*SCIP_FIXED_MEMORY_FACTOR*paraComm->getSize()
729  << std::endl;
730  SCIP_CALL( SCIPpresolve(scip) );
731  solvedAtInit = true;
732  setFinalSolverStatus(MemoryLimitIsReached);
733  // finalDualBound = SCIPgetDualbound(scip);
734  std::cout << "=== solved at Init ===" << std::endl;
735  finalDualBound = instance->convertToInternalValue(SCIPgetDualbound(scip));
736  writeSolution("Final Solution");
737  return 1;
738  }
739  // std::cout << "** set memory limit for presolving in LC to " << dynamic_cast<ScipParaParamSet *>(paraParams)->getRealParamValue(MemoryLimit)/(paraComm->getSize()*SCIP_MEMORY_COPY_FACTOR) << " for SCIP **" << std::endl;
740  std::cout << "** set memory limit for presolving in LC to " << dynamic_cast<ScipParaParamSet *>(paraParams)->getRealParamValue(MemoryLimit) - virtualMemUsedAtLc*SCIP_MEMORY_COPY_FACTOR*paraComm->getSize() << " for SCIP **" << std::endl;
741 #else
742  SCIP_CALL_ABORT( SCIPsetRealParam(scip, "limits/memory", dynamic_cast<ScipParaParamSet *>(paraParams)->getRealParamValue(MemoryLimit)) );
743  std::cout << "** set memory limit for presolving in LC and solvers to " << dynamic_cast<ScipParaParamSet *>(paraParams)->getRealParamValue(MemoryLimit) << " for each SCIP **" << std::endl;
744 #endif
745 
746 #if SCIP_APIVERSION >= 101
747  if( SCIPfindPresol(scip, "milp") != NULL )
748  {
749 #ifdef _COMM_MPI_WORLD
750  SCIP_CALL_ABORT( SCIPsetIntParam(scip, "presolving/milp/threads", 0) );
751 #else
752  SCIP_CALL_ABORT( SCIPsetIntParam(scip, "presolving/milp/threads", (paraComm->getSize() - 1)) );
753 #endif
754  }
755 #endif
756 
757  if( paraParams->getRealParamValue(UG::TimeLimit) > 0.0 )
758  {
759  double timeRemains = std::max( 0.0, (paraParams->getRealParamValue(UG::TimeLimit) - timer->getElapsedTime()) );
760  SCIP_CALL_ABORT( SCIPsetIntParam(scip,"timing/clocktype", 2) ); // to confirm this for the scip environment actually to work
761  SCIP_CALL_ABORT( SCIPsetRealParam(scip,"limits/time", timeRemains) );
762  }
763 
764  SCIP_CALL( SCIPpresolve(scip) );
765  SCIP_STATUS scipStatus = SCIPgetStatus(scip);
766 
767  if( scipStatus == SCIP_STATUS_OPTIMAL ||
768  scipStatus == SCIP_STATUS_INFEASIBLE ) // when sub-MIP is solved at root node, the solution may not be saved
769  {
770  solvedAtInit = true;
771  setFinalSolverStatus(ProblemWasSolved);
772  // finalDualBound = SCIPgetDualbound(scip);
773  std::cout << "=== solved at Init ===" << std::endl;
774  finalDualBound = instance->convertToInternalValue(SCIPgetDualbound(scip));
775  writeSolution("Final Solution");
776  return 1;
777  }
778  else if( scipStatus == SCIP_STATUS_MEMLIMIT )
779  {
780  solvedAtInit = true;
781  setFinalSolverStatus(MemoryLimitIsReached);
782  // finalDualBound = SCIPgetDualbound(scip);
783  std::cout << "=== solved at Init ===" << std::endl;
784  finalDualBound = instance->convertToInternalValue(SCIPgetDualbound(scip));
785  writeSolution("Final Solution");
786  return 1;
787  }
788  else
789  {
790  if( scipStatus == SCIP_STATUS_TIMELIMIT )
791  {
792  solvedAtInit = true;
793  setFinalSolverStatus(HardTimeLimitIsReached);
794  // finalDualBound = SCIPgetDualbound(scip);
795  std::cout << "=== solved at Init ===" << std::endl;
796  finalDualBound = instance->convertToInternalValue(SCIPgetDualbound(scip));
797  writeSolution("Final Solution");
798  return 1;
799  }
800  else
801  {
802  /* adding root node cuts, if necessary */
803  if( paraParams->getBoolParamValue(UseRootNodeCuts) )
804  {
805  if( !addRootNodeCuts() )
806  {
807  solvedAtInit = true;
808  setFinalSolverStatus(ProblemWasSolved);
809  // finalDualBound = SCIPgetDualbound(scip);
810  std::cout << "=== solved at Init ===" << std::endl;
811  finalDualBound = instance->convertToInternalValue(SCIPgetDualbound(scip));
812  writeSolution("Final Solution");
813  return 1;
814  }
815  else
816  {
817  if( paraParams->getRealParamValue(UG::TimeLimit) > 0.0 &&
818  timer->getElapsedTime() > paraParams->getRealParamValue(UG::TimeLimit) )
819  {
820  solvedAtInit = true;
821  setFinalSolverStatus(HardTimeLimitIsReached);
822  // finalDualBound = SCIPgetDualbound(scip);
823  std::cout << "=== solved at Init ===" << std::endl;
824  finalDualBound = instance->convertToInternalValue(SCIPgetDualbound(scip));
825  writeSolution("Final Solution");
826  return 1;
827  }
828  }
829  }
830  }
831  }
832 
833 #if defined(_COMM_PTH) || defined (_COMM_CPP11)
834 #ifdef __linux__
835  // int nCores = sysconf(_SC_NPROCESSORS_CONF);
836  long long vmSize = getVmSize();
837  long long vmSizeForSolver = (vmSize - vmSizeBeforePresolving)/paraComm->getSize() + vmSizeBeforePresolving;
838  virtualMemUsedAtLc = std::max(vmSizeForSolver, (SCIPgetMemTotal(scip) + SCIPgetMemExternEstim(scip)))/SCIP_PRESOLVIG_MEMORY_FACTOR; /// in genral, it looks over estimated
839  std::cout << "** Estimated virtualMemUsedAtSolver = " << virtualMemUsedAtLc << ", getVmSize() = " << vmSize << ", SCIPgetMemUsed() = " << SCIPgetMemUsed(scip) << ", SCIPgetMemTotal() = " << SCIPgetMemTotal(scip) << ", SCIPgetMemExternEstim() = " << SCIPgetMemExternEstim(scip) << std::endl;
840 #else
841  virtualMemUsedAtLc = SCIPgetMemTotal(scip) + SCIPgetMemExternEstim(scip);
842  std::cout << "** Estimated virtualMemUsedAtSolver = " << virtualMemUsedAtLc << ", SCIPgetMemUsed() = " << SCIPgetMemUsed(scip) << ", SCIPgetMemTotal() = " << SCIPgetMemTotal(scip) << ", SCIPgetMemExternEstim() = " << SCIPgetMemExternEstim(scip) << std::endl;
843 #endif
844  // memoryLimitOfSolverSCIP = (dynamic_cast<ScipParaParamSet *>(paraParams)->getRealParamValue(MemoryLimit) - (virtualMemUsedAtLc*SCIP_FIXED_MEMORY_FACTOR))/((paraComm->getSize()-1)*SCIP_MEMORY_COPY_FACTOR);
845  memoryLimitOfSolverSCIP = dynamic_cast<ScipParaParamSet *>(paraParams)->getRealParamValue(MemoryLimit)/paraComm->getSize() - virtualMemUsedAtLc*SCIP_FIXED_MEMORY_FACTOR*paraComm->getSize()*SCIP_MEMORY_COPY_FACTOR;
846  std::cout << "** set memory limit for solvers to " << memoryLimitOfSolverSCIP << " for each SCIP **" << std::endl;
848  {
849  solvedAtInit = true;
850  setFinalSolverStatus(MemoryLimitIsReached);
851  // finalDualBound = SCIPgetDualbound(scip);
852  std::cout << "=== solved at Init ===" << std::endl;
853  finalDualBound = instance->convertToInternalValue(SCIPgetDualbound(scip));
854  writeSolution("Final Solution");
855  return 1;
856  }
857 #endif
858 
859  // output presolved instance information
860  int nNonLinearConsHdlrs = 0;
861  outputProblemInfo(&nNonLinearConsHdlrs);
862 #ifdef _COMM_MPI_WORLD
863  if( SCIPgetNActiveBenders(scip) > 0 ) nNonLinearConsHdlrs++;
865  paraComm->bcast( &nNonLinearConsHdlrs, 1, ParaINT, 0 )
866  );
867  if( nNonLinearConsHdlrs > 0 )
868  {
869  paraParams->setIntParamValue(InstanceTransferMethod,2);
870  }
871 #endif
872  std::cout << "** Instance transfer method used: " << paraParams->getIntParamValue(InstanceTransferMethod) << std::endl;
873 
874  if( SCIPgetNVars(scip) == 0 ) // all variables were fixed in presolve
875  {
876  SCIP_CALL( SCIPsolve(scip) );
877  solvedAtInit = true;
878  setFinalSolverStatus(ProblemWasSolved);
879  // finalDualBound = SCIPgetDualbound(scip);
880  std::cout << "=== solved at Init ===" << std::endl;
881  finalDualBound = instance->convertToInternalValue(SCIPgetDualbound(scip));
882  writeSolution("Final Solution");
883  return 1;
884  }
885 
886  /** check if feasible solution is found or not. If it was found, then generate paraSolution */
887  SCIP_SOL *sol = SCIPgetBestSol(scip);
888  // std::cout << "solobj = " << SCIPgetSolOrigObj(scip, sol) << ", objlimit = " << SCIPgetObjlimit(scip) << std::endl;
889  if( sol )
890  {
891  if( EPSLT( objlimit, DBL_MAX, MINEPSILON ) )
892  {
893  if( ( SCIPgetObjsense(scip) == SCIP_OBJSENSE_MINIMIZE && SCIPgetSolOrigObj(scip, sol) < objlimit ) ||
894  ( SCIPgetObjsense(scip) == SCIP_OBJSENSE_MAXIMIZE && SCIPgetSolOrigObj(scip, sol) > objlimit ) )
895  {
896  int nVars = SCIPgetNVars(scip);
897  SCIP_VAR **vars = SCIPgetVars(scip);
898  SCIP_Real *vals = new SCIP_Real[nVars];
899  SCIP_CALL_ABORT( SCIPgetSolVals(scip, sol, nVars, vars, vals) );
900  solution = scipParaComm->createScipParaSolution(
901  0,
902  SCIPgetSolTransObj(scip, sol), // Only this value may be used
903  nVars,
904  vars,
905  vals
906  );
907  delete [] vals;
908  }
909  else
910  {
911  solution = scipParaComm->createScipParaSolution(
912  0,
913  ( ( objlimit / ( SCIPgetTransObjscale(scip) * SCIPgetObjsense(scip) ) ) - SCIPgetTransObjoffset(scip) ), // Only this value may be used
914  0,
915  (SCIP_VAR **)0,
916  0
917  );
918  }
919  }
920  else
921  {
922  int nVars = SCIPgetNVars(scip);
923  SCIP_VAR **vars = SCIPgetVars(scip);
924  SCIP_Real *vals = new SCIP_Real[nVars];
925  SCIP_CALL_ABORT( SCIPgetSolVals(scip, sol, nVars, vars, vals) );
926  solution = scipParaComm->createScipParaSolution(
927  0,
928  SCIPgetSolTransObj(scip, sol), // Only this value may be used
929  0,
930  (SCIP_VAR **)0,
931  0
932  );
933  delete [] vals;
934  }
935  }
936  else
937  {
938  if( EPSLT( objlimit, DBL_MAX, MINEPSILON ) )
939  {
940  solution = scipParaComm->createScipParaSolution(
941  0,
942  ( ( objlimit / ( SCIPgetTransObjscale(scip) * SCIPgetObjsense(scip) ) ) - SCIPgetTransObjoffset(scip) ), // Only this value may be used
943  0,
944  (SCIP_VAR **)0,
945  0
946  );
947  }
948  }
949 
950 
951 
952  // instance = new PARA_INSTANCE_TYPE(scip, paraParams->getIntParamValue(InstanceTransferMethod));
953  #ifdef _COMM_MPI_WORLD
954  /** In ParaSCIP case, instance have to provided for the presolved instance **/
955  delete instance;
956  instance = scipParaComm->createScipParaInstance(scip, paraParams->getIntParamValue(InstanceTransferMethod));
957  #endif
958  // instance = scipParaComm->createScipParaInstance(scip, paraParams->getIntParamValue(InstanceTransferMethod));
959 
960  /* for debugging
961  std::string subcipprefix("presolved_");
962  std::string subcipfilename;
963  std::ostringstream oss;
964  oss << subcipprefix;
965  oss << instance->getProbName();
966  subcipfilename = oss.str();
967  subcipfilename += ".lp";
968  if( SCIPgetStage(scip) >= SCIP_STAGE_TRANSFORMED )
969  {
970  SCIP_CALL_ABORT( SCIPwriteTransProblem(scip, subcipfilename.c_str(), "lp", FALSE) );
971  }
972  ************************/
973 
974 #ifdef _COMM_MPI_WORLD
975  if( onlyLinearConss && paraParams->getIntParamValue(UG::InstanceTransferMethod) != 2 )
976  {
977  // restore original parameters
978  SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/knapsack", originalUpgradeKnapsack));
979  SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/logicor", originalUpgradeLogicor));
980  SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/setppc", originalUpgradeSetppc));
981  SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/varbound", originalUpgradeVarbound));
982  }
983 #else
984  if( noUpgrade )
985  {
986  SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/knapsack", originalUpgradeKnapsack));
987  SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/logicor", originalUpgradeLogicor));
988  SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/setppc", originalUpgradeSetppc));
989  SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/varbound", originalUpgradeVarbound));
990  }
991 #endif
992 
993  int maxrounds = 0;
994  SCIP_CALL_ABORT( SCIPgetIntParam(scip, "presolving/maxrounds", &maxrounds));
995  if( !paraParams->getBoolParamValue(Quiet) && maxrounds != 0 )
996  {
997  os << ".trans";
998  transSolutionFile = fopen(os.str().c_str(), "a"); // if trans. solution file exists, append
999  if( transSolutionFile == NULL )
1000  {
1001  THROW_LOGICAL_ERROR3("cannot open solution file <", os.str(), "> for writing");
1002  }
1003  }
1004  if( paraParams->getBoolParamValue(UG::OutputPresolvedInstance) )
1005  {
1006  std::ostringstream os2;
1007  os2 << paraParams->getStringParamValue(UG::LogSolvingStatusFilePath);
1008  if( onlyLinearConss )
1009  {
1010  os2 << instance->getProbName() << "_presolved.lp";
1011  }
1012  else
1013  {
1014  os2 << instance->getProbName() << "_presolved.cip";
1015  }
1016  SCIP_CALL_ABORT( SCIPwriteTransProblem(scip, os2.str().c_str(), NULL, FALSE));
1017  }
1018  }
1019  else
1020  {
1021  std::cout << std::endl;
1022  std::cout << "syntax: " << argv[0] << "#solvers ppscip_param_file problem_file_name "
1023  << "[-l <logfile>] [-q] [-sl <settings>] [-s <settings>] [-sr <root_settings>] [-w <prefix_warm>] [-sth <number>]" << std::endl;
1024  std::cout << " -l <logfile> : copy output into log file" << std::endl;
1025  std::cout << " -q : suppress screen messages" << std::endl;
1026  std::cout << " -sl <settings> : load parameter settings (.set) file for LC presolving" << std::endl;
1027  std::cout << " -s <settings> : load parameter settings (.set) file for solvers" << std::endl;
1028  std::cout << " -sr <root_settings> : load parameter settings (.set) file for root" << std::endl;
1029  std::cout << " -w <prefix_warm> : warm start file prefix ( prefix_warm_nodes.gz and prefix_warm_solution.txt are read )" << std::endl;
1030  std::cout << " -sth <number> : the number of solver threads used(FiberSCIP)" << std::endl;
1031  THROW_LOGICAL_ERROR1("invalid parameter");
1032  }
1033 
1034  if( solution )
1035  {
1036  if( !paraParams->getBoolParamValue(Quiet) )
1037  {
1038  writeSolution("");
1039  }
1040  else
1041  {
1042  writeSolution("Updated");
1043  }
1044  }
1045 
1046  return 0;
1047 }
1048 
1049 /** reInit function */
1050 int
1051 ScipParaInitiator::reInit(
1052  int nRestartedRacing
1053  )
1054 {
1055  /** save incumbent solution */
1056  char initSolFileName[SCIP_MAXSTRLEN];
1057 
1058  if( isolname )
1059  {
1060  (void) SCIPsnprintf(initSolFileName, SCIP_MAXSTRLEN, "%s.%d", isolname, nRestartedRacing);
1061  if( !rename( isolname, initSolFileName ) )
1062  {
1063  std::cout << "Warning: initial solution file name cannot rename: " << isolname << ", " << nRestartedRacing << "'th restarted file." << std::endl;
1064  // perror("cannot rename");
1065  // THROW_LOGICAL_ERROR1("cannot rename solution file");
1066  }
1067  if( !generatedIsolname )
1068  {
1069  (void) SCIPsnprintf(initSolFileName, SCIP_MAXSTRLEN, "%s", isolname);
1070  generatedIsolname = new char[strlen(initSolFileName)+1];
1071  (void) strcpy(generatedIsolname, initSolFileName);
1072  }
1073  }
1074  else
1075  {
1076  if( !generatedIsolname )
1077  {
1078  (void) SCIPsnprintf(initSolFileName, SCIP_MAXSTRLEN, "i_%s.sol", instance->getProbName());
1079  generatedIsolname = new char[strlen(initSolFileName)+1];
1080  (void) strcpy(generatedIsolname, initSolFileName);
1081  }
1082  }
1083 
1084  FILE *fp = fopen(generatedIsolname, "w");
1085  if( !fp )
1086  {
1087  std::cout << "Could not open " << generatedIsolname << " file to reinitialize for restart." << std::endl;
1088  abort();
1089  }
1090  assert( SCIPgetBestSol(scip) );
1091  SCIP_CALL_ABORT( SCIPprintBestSol( scip, fp, FALSE) );
1092  (void) fclose(fp);
1093 
1094  // Problem Creation
1095  SCIP_RETCODE retcode = SCIPreadProb(scip, probname, NULL);
1096  if( retcode != SCIP_OKAY )
1097  {
1098  std::cout << "error reading file <" << probname << ">" << std::endl;
1099  SCIP_CALL( SCIPfreeProb(scip) );
1100  exit(1);
1101  }
1102 
1103  // std::cout << "problem name in initiator ' " << SCIPgetProbName(scip) << std::endl;
1104 
1105  SCIP_CALL_ABORT( SCIPtransformProb(scip));
1106  // NOTE:
1107  // When CPLEX license file cannot find, SCIPtransformProb(scip) may fail
1108  SCIP_CALL_ABORT( SCIPreadSol(scip, generatedIsolname) );
1109 
1110  /* change problem name */
1111  char *probNameFromFileName;
1112  char *temp = new char[strlen(probname)+1];
1113  (void) strcpy(temp, probname);
1114  SCIPsplitFilename(temp, NULL, &probNameFromFileName, NULL, NULL);
1115  SCIP_CALL_ABORT( SCIPsetProbName(scip, probNameFromFileName));
1116  delete [] temp;
1117 
1118 #if ( defined(_COMM_PTH) || defined(_COMM_CPP11) )
1119  SCIP_CALL( SCIPsetBoolParam(scip, "misc/catchctrlc", FALSE) );
1120 #endif
1121 
1122 #ifdef _COMM_MPI_WORLD
1123  SCIP_Bool originalUpgradeKnapsack;
1124  SCIP_Bool originalUpgradeLogicor;
1125  SCIP_Bool originalUpgradeSetppc;
1126  SCIP_Bool originalUpgradeVarbound;
1127  bool onlyLinearConss = onlyLinearConsHandler();
1128  if( onlyLinearConss )
1129  {
1130  SCIP_CALL_ABORT( SCIPgetBoolParam(scip, "constraints/linear/upgrade/knapsack", &originalUpgradeKnapsack));
1131  SCIP_CALL_ABORT( SCIPgetBoolParam(scip, "constraints/linear/upgrade/logicor", &originalUpgradeLogicor));
1132  SCIP_CALL_ABORT( SCIPgetBoolParam(scip, "constraints/linear/upgrade/setppc", &originalUpgradeSetppc));
1133  SCIP_CALL_ABORT( SCIPgetBoolParam(scip, "constraints/linear/upgrade/varbound", &originalUpgradeVarbound));
1134  SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/knapsack", FALSE));
1135  SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/logicor", FALSE));
1136  SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/setppc", FALSE));
1137  SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/varbound", FALSE));
1138  }
1139 #endif
1140 
1141  SCIP_CALL( SCIPpresolve(scip) );
1142  SCIP_STATUS scipStatus = SCIPgetStatus(scip);
1143 
1144  // output presolved instance information
1145  int nNonLinearConsHdlrs = 0;
1146  outputProblemInfo(&nNonLinearConsHdlrs);
1147 
1148  if( scipStatus == SCIP_STATUS_OPTIMAL ||
1149  scipStatus == SCIP_STATUS_INFEASIBLE ) // when sub-MIP is solved at root node, the solution may not be saved
1150  {
1151  solvedAtReInit = true;
1152  setFinalSolverStatus(ProblemWasSolved);
1153  // finalDualBound = SCIPgetDualbound(scip);
1154  std::cout << "=== solved at reInit ===" << std::endl;
1155  finalDualBound = instance->convertToInternalValue(SCIPgetDualbound(scip));
1156  writeSolution("Final Solution");
1157  return 1;
1158  }
1159  else
1160  {
1161  /* adding root node cuts, if necessary */
1162  if( paraParams->getBoolParamValue(UseRootNodeCuts) )
1163  {
1164  if( !addRootNodeCuts() )
1165  {
1166  solvedAtReInit = true;
1167  setFinalSolverStatus(ProblemWasSolved);
1168  // finalDualBound = SCIPgetDualbound(scip);
1169  std::cout << "=== solved at reInit ===" << std::endl;
1170  finalDualBound = instance->convertToInternalValue(SCIPgetDualbound(scip));
1171  writeSolution("Final Solution");
1172  return 1;
1173  }
1174  }
1175  }
1176 
1177  if( SCIPgetNVars(scip) == 0 ) // all variables were fixed in presolve
1178  {
1179  SCIP_CALL( SCIPsolve(scip) );
1180  solvedAtReInit = true;
1181  setFinalSolverStatus(ProblemWasSolved);
1182  // finalDualBound = SCIPgetDualbound(scip);
1183  std::cout << "=== solved at reInit ===" << std::endl;
1184  finalDualBound = instance->convertToInternalValue(SCIPgetDualbound(scip));
1185  writeSolution("Final Solution");
1186  return 1;
1187  }
1188 
1189  DEF_SCIP_PARA_COMM( scipParaComm, paraComm );
1190  /** check if feasible solution is found or not. If it was found, then generate paraSolution */
1191  SCIP_SOL *sol = SCIPgetBestSol(scip);
1192  assert(sol);
1193  int nVars = SCIPgetNVars(scip);
1194  SCIP_VAR **vars = SCIPgetVars(scip);
1195  SCIP_Real *vals = new SCIP_Real[nVars];
1196  SCIP_CALL_ABORT( SCIPgetSolVals(scip, sol, nVars, vars, vals) );
1197  assert(solution);
1198  delete solution;
1199  solution = scipParaComm->createScipParaSolution(
1200  0,
1201  SCIPgetSolTransObj(scip, sol), // Only this value may be used
1202  nVars,
1203  vars,
1204  vals
1205  );
1206  if( !paraParams->getBoolParamValue(Quiet) )
1207  {
1208  writeSolution("[Reinitialize]");
1209  }
1210  delete [] vals;
1211  // instance = new PARA_INSTANCE_TYPE(scip, paraParams->getIntParamValue(InstanceTransferMethod));
1212  assert(instance);
1213  delete instance;
1214  instance = scipParaComm->createScipParaInstance(scip, paraParams->getIntParamValue(InstanceTransferMethod));
1215 
1216  /* for debugging
1217  std::string subcipprefix("presolved_");
1218  std::string subcipfilename;
1219  std::ostringstream oss;
1220  oss << instance->getProbName();
1221  subcipfilename = oss.str();
1222  subcipfilename += ".lp";
1223  if( SCIPgetStage(scip) >= SCIP_STAGE_TRANSFORMED )
1224  {
1225  SCIP_CALL_ABORT( SCIPwriteTransProblem(scip, subcipfilename.c_str(), "lp", FALSE) );
1226  }
1227  ************************/
1228 
1229 #ifdef _COMM_MPI_WORLD
1230  if( onlyLinearConss )
1231  {
1232  // restore original parameters
1233  SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/knapsack", originalUpgradeKnapsack));
1234  SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/logicor", originalUpgradeLogicor));
1235  SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/setppc", originalUpgradeSetppc));
1236  SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/varbound", originalUpgradeVarbound));
1237  }
1238 #endif
1239 
1240  return 0;
1241 
1242 }
1243 
1244 bool
1245 ScipParaInitiator::tryToSetIncumbentSolution(
1246  BbParaSolution *sol,
1247  bool checksol
1248  )
1249 {
1250  ScipParaSolution *tempSol = dynamic_cast< ScipParaSolution * >(sol);
1251 
1252  if( tempSol->getNVars() == 0 )
1253  {
1254  delete tempSol;
1255  return false;
1256  }
1257 
1258  /* If there is an active Benders' decomposition plugin, the stored solutions are not valid for the original problem.
1259  * This is due to the auxiliary variable not being present in the original problem. Thus, it is not possible to set
1260  * the incumbent solution
1261  */
1262  if( checksol && SCIPgetNActiveBenders(scip) > 0 )
1263  {
1264  delete tempSol;
1265  return false;
1266  }
1267 
1268  SCIP_SOL* newsol; /* solution to be created for the original problem */
1269 
1270  paraComm->lockApp(); /* lock is necessary, if Solver runs as thread */
1271 
1272  /* the solution from the working node should have at least as many variables as we have in the load coordinator scip
1273  * it may be more if inactive variable had to be copied, i.e.,
1274  * SCIPgetNVars(scip) is the number of active variables in the load coordinator scip
1275  * tempSol->getNVars() is the number of original variables in the working node scip (scipParaSolver)
1276  */
1277  SCIP_VAR** vars = 0;
1278  ScipParaInstance *scipInstance = dynamic_cast<ScipParaInstance *>(instance);
1279  /*
1280  int maxrounds = 0;
1281  SCIP_CALL_ABORT( SCIPgetIntParam(scip, "presolving/maxrounds", &maxrounds));
1282  // if( paraParams->getIntParamValue(InstanceTransferMethod) == 2 // original file read
1283  if( maxrounds == 0 ) // nopreprocessing
1284  {
1285  //assert(SCIPgetNVars(scip) <= tempSol->getNVars());
1286  // create new solution for the original problem
1287  SCIP_CALL_ABORT( SCIPcreateOrigSol(scip, &newsol, 0) );
1288  vars = SCIPgetOrigVars(scip);
1289  }
1290  else
1291  {
1292  */
1293  if( checksol && SCIPgetNVars(scip) > tempSol->getNVars() )
1294  {
1295  std::cout << "*** You should check the solution! ***" << std::endl;
1296  std::cout << "checksol = " << checksol << std::endl;
1297  std::cout << "SCIPgetNVars(scip) = " << SCIPgetNVars(scip) << ", " << tempSol->getNVars() << std::endl;
1298  delete tempSol;
1299  return false;
1300  }
1301  assert(SCIPgetNVars(scip) <= tempSol->getNVars());
1302  SCIP_CALL_ABORT( SCIPcreateSol(scip, &newsol, 0) );
1303  vars = SCIPgetVars(scip);
1304  // }
1305 
1306  int i;
1307  if( scipInstance->isOriginalIndeciesMap() )
1308  {
1309  int n = SCIPgetNVars(scip);
1310  SCIP_Real *orgSolValues = new SCIP_Real[tempSol->getNVars()];
1311  scipInstance->getSolValuesForOriginalProblem(tempSol, orgSolValues);
1312  // for( i = 0; i < n; i++ )
1313  // assert(SCIPgetNVars(scip) == tempSol->getNVars());
1314  for( i = 0; i < n; i++ )
1315  // for( i = 0; i < scipInstance->getVarIndexRange(); i++ )
1316  {
1317  SCIP_CALL_ABORT( SCIPsetSolVal(scip, newsol, vars[i], orgSolValues[i]) );
1318  // SCIP_CALL_ABORT( SCIPsetSolVal(scip, newsol, vars[tempSol->indexAmongSolvers(i)], orgSolValues[i]) );
1319  // int probindex = scipInstance->getOrigProbIndex(tempSol->indexAmongSolvers(i));
1320  // int probindex = scipInstance->getOrigProbIndex(tempSol->indexAmongSolvers(i));
1321  // int probindex = scipInstance->getOrigProbIndex(tempSol->indexAmongSolvers(i));
1322  /* skip inactive variable */
1323  // if( probindex < 0 ) continue;
1324  // assert(i == probindex); /* this is just a temporory assert, maybe this holds... */
1325  // SCIP_CALL_ABORT( SCIPsetSolVal(scip, newsol, vars[probindex], orgSolValues[i]) );
1326  // SCIP_CALL_ABORT( SCIPsetSolVal(scip, newsol, vars[i], orgSolValues[i]) );
1327  }
1328  delete [] orgSolValues;
1329  }
1330  else
1331  {
1332  // assert( SCIPgetNVars(scip) == tempSol->getNVars() );
1333  assert( SCIPgetNVars(scip) <= tempSol->getNVars() );
1334 
1335  // for( i = 0; i < tempSol->getNVars(); i++ )
1336  // {
1337  // if( EPSGT(tempSol->getValues()[i],0.0, MINEPSILON) )
1338  // {
1339  // std::cout << "inex[" << i << "] = " << tempSol->indexAmongSolvers(i) << " = " << tempSol->getValues()[i] << std::endl;
1340  // }
1341  // }
1342 
1343  for( i = 0; i < tempSol->getNVars(); i++ )
1344  {
1345  /* if index is larger-equal than number of active vars, then it's probably an inactive variable which had to be copied via SCIPcopy
1346  * so we just ignore its value
1347  */
1348  // if( tempSol->indexAmongSolvers(i) >= SCIPgetNVars(scip) ) continue;
1349  // if( tempSol->indexAmongSolvers(i) > ( tempSol->getNVars() - 1 ) ) break;
1350  // if( scipInstance->isOriginalIndeciesMap() )
1351  // {
1352  // int probindex = scipInstance->getOrigProbIndex(tempSol->indexAmongSolvers(i));
1353  // SCIP_CALL_ABORT( SCIPsetSolVal(scip, newsol, vars[probindex], tempSol->getValues()[i]) );
1354  // }
1355  // else
1356  // {
1357  // SCIP_CALL_ABORT( SCIPsetSolVal(scip, newsol, vars[tempSol->indexAmongSolvers(i)], tempSol->getValues()[i]) );
1358  if ( tempSol->indexAmongSolvers(i) >= 0 )
1359  {
1360  SCIP_CALL_ABORT( SCIPsetSolVal(scip, newsol, vars[tempSol->indexAmongSolvers(i)], tempSol->getValues()[i]) );
1361  // SCIP_CALL_ABORT( SCIPsetSolVal(scip, newsol, vars[i], tempSol->getValues()[i]) );
1362  // }
1363  }
1364  /*
1365  if( scipInstance->isOriginalIndeciesMap() )
1366  {
1367  if( scipInstance->getOrigProbIndex(tempSol->indexAmongSolvers(i)) >= 0 && scipInstance->getOrigProbIndex(tempSol->indexAmongSolvers(i)) < SCIPgetNVars(scip) )
1368  {
1369  SCIP_CALL_ABORT( SCIPsetSolVal(scip, newsol, vars[scipInstance->getOrigProbIndex(tempSol->indexAmongSolvers(i))], tempSol->getValues()[i]) );
1370  }
1371  }
1372  else
1373  {
1374  SCIP_CALL_ABORT( SCIPsetSolVal(scip, newsol, vars[tempSol->indexAmongSolvers(i)], tempSol->getValues()[i]) );
1375  }
1376  */
1377  }
1378  // if( i != tempSol->getNVars() )
1379  // {
1380  // /** the given solution should be generated in original space,
1381  // * therefore the solution values cannot use for ParaSCIP
1382  // */
1383  // SCIP_CALL_ABORT( SCIPfreeSol(scip, &newsol) );
1384  // delete tempSol;
1385  // std::cout << "solution size mismatch! Call Yuji!" << std::endl;
1386  // return false;
1387  // }
1388  }
1389 
1390  SCIP_Bool success;
1391  // checksol = true;
1392 
1393  bool primalValueUpdated = false;
1394 
1395  if( paraParams->getBoolParamValue(CheckFeasibilityInLC) == false )
1396  {
1397  if( checksol ) // checksol == true only when this routine is called to add solution from checkpoint file.
1398  // therefore, no need to lock.
1399  {
1400 #if (SCIP_VERSION < 321 || ( SCIP_VERSION == 321 && SCIP_SUBVERSION < 2) )
1401  SCIP_CALL_ABORT( SCIPtrySolFree(scip, &newsol, FALSE, TRUE, TRUE, TRUE, &success) );
1402 #else
1403  SCIP_CALL_ABORT( SCIPtrySolFree(scip, &newsol, FALSE, TRUE, TRUE, TRUE, TRUE, &success) );
1404 #endif
1405  }
1406  else
1407  {
1408  if( SCIPisTransformed(scip) && SCIPgetNSols(scip) > 0 )
1409  {
1410  double prevValue = SCIPgetPrimalbound(scip);
1411  SCIP_CALL_ABORT( SCIPaddSolFree(scip, &newsol, &success) );
1412  // if( EPSLT( SCIPgetPrimalbound(scip), prevValue, getEpsilon() ) )
1413  if( !EPSEQ( SCIPgetPrimalbound(scip), prevValue, getEpsilon() ) ) // I found increase case of this
1414  {
1415  primalValueUpdated = true;
1416  }
1417  }
1418  else
1419  {
1420  SCIP_CALL_ABORT( SCIPaddSolFree(scip, &newsol, &success) );
1421  primalValueUpdated = true;
1422  }
1423  // SCIP_CALL_ABORT( SCIPaddSolFree(scip, &newsol, &success) );
1424  // primalValueUpdated = true;
1425  }
1426 
1427  // std::cout << "** 2 ** success = " << success << std::endl;
1428 
1429  paraComm->unlockApp();
1430 
1431  if( success && primalValueUpdated )
1432  {
1433  if( solution )
1434  {
1435  delete solution;
1436  }
1437  solution = tempSol;
1438  if( !paraParams->getBoolParamValue(Quiet) )
1439  {
1440  writeSolution("");
1441  }
1442  else
1443  {
1444  writeSolution("Updated");
1445  }
1446  /// relax tolerance, since very small difference raised the following assertion
1447  // if( !EPSEQ( SCIPgetUpperbound(scip), solution->getObjectiveFunctionValue(), (SCIPfeastol(scip) )*100.0) )
1448  if( !EPSEQ( SCIPgetUpperbound(scip), solution->getObjectiveFunctionValue(), SCIPfeastol(scip) ) )
1449  {
1450  std::cout << "*** A new solution generated in a Solver does not match with the upperbound in LC ***" << std::endl;
1451  std::cout << "SCIPgetUpperbound(scip) = " << SCIPgetUpperbound(scip) << std::endl;
1452  std::cout << "solution->getObjectiveFunctionValue() = " << solution->getObjectiveFunctionValue() << std::endl;
1453  std::cout << "Difference = " << (SCIPgetUpperbound(scip) - solution->getObjectiveFunctionValue())
1454  << ", SCIPfeastol(scip) = " << SCIPfeastol(scip) << std::endl;
1455  }
1456  return true;
1457  }
1458  else
1459  {
1460  if( checksol )
1461  {
1462  SCIP_CALL_ABORT( SCIPcreateOrigSol(scip, &newsol, 0) );
1463  vars = SCIPgetOrigVars(scip);
1464  if( scipInstance->isOriginalIndeciesMap() )
1465  {
1466  for( i = 0; i < tempSol->getNVars(); i++ )
1467  {
1468  int probindex = scipInstance->getOrigProbIndex(tempSol->indexAmongSolvers(i));
1469 
1470  /* skip inactive variable */
1471  if( probindex < 0 ) continue;
1472 
1473  // assert(i == probindex); /* this is just a temporory assert, maybe this holds... */
1474 
1475  SCIP_CALL_ABORT( SCIPsetSolVal(scip, newsol, vars[probindex], tempSol->getValues()[i]) );
1476  }
1477  }
1478  else
1479  {
1480  for( i = 0; i < tempSol->getNVars(); i++ )
1481  {
1482  // SCIP_CALL_ABORT( SCIPsetSolVal(scip, newsol, vars[tempSol->indexAmongSolvers(i)], tempSol->getValues()[i]) );
1483  SCIP_CALL_ABORT( SCIPsetSolVal(scip, newsol, vars[i], tempSol->getValues()[i]) );
1484  }
1485  }
1486 
1487  // if( i != tempSol->getNVars() ) /* this should not happen */
1488  // {
1489  // /** the given solution should be generated in original space,
1490  // * therefore the solution values cannot use for ParaSCIP
1491  // */
1492  // SCIP_CALL_ABORT( SCIPfreeSol(scip, &newsol) );
1493  // delete tempSol;
1494  // std::cout << "solution size mismatch! Call Yuji!" << std::endl;
1495  // return false;
1496  //}
1497 #if (SCIP_VERSION < 321 || ( SCIP_VERSION == 321 && SCIP_SUBVERSION < 2) )
1498  SCIP_CALL_ABORT( SCIPtrySolFree(scip, &newsol, FALSE, TRUE, TRUE, TRUE, &success) );
1499 #else
1500  SCIP_CALL_ABORT( SCIPtrySolFree(scip, &newsol, FALSE, TRUE, TRUE, TRUE, TRUE, &success) );
1501 #endif
1502  // std::cout << "** 3 ** success = " << success << std::endl;
1503  if( success )
1504  {
1505  if( solution )
1506  {
1507  delete solution;
1508  }
1509  solution = tempSol;
1510  if( !paraParams->getBoolParamValue(Quiet) )
1511  {
1512  writeSolution("");
1513  }
1514  else
1515  {
1516  writeSolution("Updated");
1517  }
1518  assert( EPSEQ( SCIPgetUpperbound(scip), solution->getObjectiveFunctionValue(), SCIPfeastol(scip) ) );
1519  return true;
1520  }
1521  }
1522  delete tempSol;
1523  return false;
1524  }
1525  }
1526  else
1527  {
1528  //
1529  // The following routine is not tested yet.
1530  //
1531  // std::cout << "Print sol. orig" << std::endl;
1532  // SCIP_CALL_ABORT( SCIPprintSol(scip, newsol, NULL, FALSE) );
1533  // std::cout << "Print sol. trans" << std::endl;
1534  // SCIP_CALL_ABORT( SCIPprintTransSol(scip, newsol, NULL, FALSE) );
1535  // int nVars = SCIPgetNVars(scip);
1536  // for( int i = 0; i < nVars; i ++)
1537  // {
1538  // std::cout << i << ": " << SCIPvarGetName(vars[tempSol->indexAmongSolvers(i)]) << std::endl;
1539  // std::cout << i << ": " << SCIPvarGetName(vars[i]) << std::endl;
1540  // }
1541 
1542 #if (SCIP_VERSION < 321 || ( SCIP_VERSION == 321 && SCIP_SUBVERSION < 2) )
1543  SCIP_CALL_ABORT( SCIPtrySolFree(scip, &newsol, FALSE, TRUE, TRUE, TRUE, &success) );
1544 #else
1545  SCIP_CALL_ABORT( SCIPtrySolFree(scip, &newsol, FALSE, TRUE, TRUE, TRUE, TRUE, &success) );
1546 #endif
1547  assert(success);
1548  if( success )
1549  {
1550  // SCIP_CALL_ABORT( SCIPfreeSol(scip, &newsol) );
1551  if( solution )
1552  {
1553  delete solution;
1554  }
1555  solution = tempSol;
1556  if( !paraParams->getBoolParamValue(Quiet) )
1557  {
1558  writeSolution("");
1559  }
1560  else
1561  {
1562  writeSolution("Updated");
1563  }
1564  paraComm->unlockApp();
1565  assert( EPSEQ( SCIPgetUpperbound(scip), solution->getObjectiveFunctionValue(), SCIPfeastol(scip) ) );
1566  return true;
1567  }
1568  else
1569  {
1570  SCIP_VAR* var = 0;
1571  for( i = 0; i < tempSol->getNVars(); i++ )
1572  {
1573  int probindex = scipInstance->getOrigProbIndex(tempSol->indexAmongSolvers(i));
1574 
1575  /* skip inactive variable */
1576  if( probindex < 0 ) continue;
1577 
1578  assert(i == probindex); /* this is just a temporory assert, maybe this holds... */
1579 
1580  var = vars[probindex];
1581 
1582  if( SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS ) continue;
1583  if( tempSol->getValues()[i] > 0.0 )
1584  {
1585  tempSol->setValue(i, SCIPfeasFloor(scip,tempSol->getValues()[i]));
1586  }
1587  else
1588  {
1589  tempSol->setValue(i, SCIPfeasCeil(scip, tempSol->getValues()[i]) );
1590  }
1591  SCIP_CALL_ABORT( SCIPsetSolVal(scip, newsol, var, tempSol->getValues()[i]) );
1592  }
1593 
1594 #if (SCIP_VERSION < 321 || ( SCIP_VERSION == 321 && SCIP_SUBVERSION < 2) )
1595  SCIP_CALL_ABORT( SCIPtrySol(scip, newsol, FALSE, TRUE, TRUE, TRUE, &success) );
1596 #else
1597  SCIP_CALL_ABORT( SCIPtrySol(scip, newsol, FALSE, TRUE, TRUE, TRUE, TRUE, &success) );
1598 #endif
1599  if( success )
1600  {
1601  tempSol->setObjectiveFuntionValue(convertToInternalValue(SCIPsolGetOrigObj(newsol)));
1602  SCIP_CALL_ABORT( SCIPfreeSol(scip, &newsol) );
1603  if( solution )
1604  {
1605  delete solution;
1606  }
1607  solution = tempSol;
1608  if( !paraParams->getBoolParamValue(Quiet) )
1609  {
1610  writeSolution("");
1611  }
1612  else
1613  {
1614  writeSolution("Updated");
1615  }
1616  paraComm->unlockApp();
1617  assert( EPSEQ( SCIPgetUpperbound(scip), solution->getObjectiveFunctionValue(), SCIPfeastol(scip) ) );
1618  return true;
1619  }
1620  else
1621  {
1622  fprintf(solutionFile, "*** Rejected Solution ***\n");
1623  SCIP_CALL_ABORT(SCIPprintSol(scip, newsol, solutionFile, FALSE));
1624  if( transSolutionFile )
1625  {
1626  fprintf(transSolutionFile, "*** Rejected Solution ***\n");
1627  SCIP_CALL_ABORT(SCIPprintTransSol(scip, newsol, transSolutionFile, FALSE));
1628  }
1629 
1630  if( SCIPisFeasLT( scip, convertToExternalValue(tempSol->getObjectiveFunctionValue()), SCIPgetPrimalbound(scip) ) )
1631  {
1632  // paraComm->lockApp();
1633  std::cout << "Current scip primal value = " << SCIPgetPrimalbound(scip) << std::endl;
1634  std::cout << "Objective value = " << convertToExternalValue(tempSol->getObjectiveFunctionValue()) << std::endl;
1635  std::cout << "Initiator did not accept solution!" << std::endl;
1636  // paraComm->unlockApp();
1637  }
1638  SCIP_CALL_ABORT( SCIPfreeSol(scip, &newsol) );
1639  delete tempSol;
1640  paraComm->unlockApp();
1641  return false;
1642  }
1643  }
1644  }
1645 }
1646 
1647 void
1648 ScipParaInitiator::sendSolverInitializationMessage(
1649  )
1650 {
1651  assert(scipDiffParamSetRoot && scipDiffParamSet);
1652  scipDiffParamSetRoot->bcast(paraComm, 0);
1653  scipDiffParamSet->bcast(paraComm, 0);
1654  int warmStarted = 0;
1655  if( isWarmStarted() )
1656  {
1657  warmStarted = 1;
1658  }
1659  paraComm->bcast(&warmStarted,1, ParaINT, 0);
1660  double incumbentValue;
1661  if( solution )
1662  {
1663  incumbentValue = solution->getObjectiveFunctionValue();
1664  }
1665  else
1666  {
1667  SCIP_SOL *sol = SCIPgetBestSol(scip);
1668  if ( sol )
1669  {
1670  int nVars = SCIPgetNVars(scip);
1671  SCIP_VAR **vars = SCIPgetVars(scip);
1672  SCIP_Real *vals = new SCIP_Real[nVars];
1673  SCIP_CALL_ABORT( SCIPgetSolVals(scip, sol, nVars, vars, vals) );
1674  DEF_SCIP_PARA_COMM( scipParaComm, paraComm);
1675  solution = scipParaComm->createScipParaSolution(
1676  0,
1677  SCIPgetSolTransObj(scip,sol),
1678  nVars,
1679  vars,
1680  vals
1681  );
1682  delete [] vals;
1683  incumbentValue = solution->getObjectiveFunctionValue();
1684  }
1685  else
1686  {
1687  incumbentValue = DBL_MAX;
1688  }
1689  }
1690  paraComm->bcast(&incumbentValue, 1, ParaDOUBLE, 0);
1691 
1692  if( paraParams->getBoolParamValue(NoUpperBoundTransferInRacing) )
1693  {
1694  int solutionExists = 0;
1695  paraComm->bcast(&solutionExists, 1, ParaINT, 0);
1696  }
1697  else
1698  {
1699  /** if a feasible solution exists, broadcast the solution */
1700  if( paraParams->getBoolParamValue(DistributeBestPrimalSolution) )
1701  {
1702  /* bcast solution if it is necessary */
1703  int solutionExists = 0;
1704  if( solution )
1705  {
1706  solutionExists = 1;
1707  paraComm->bcast(&solutionExists, 1, ParaINT, 0);
1708  solution->bcast(paraComm, 0);
1709  }
1710  else
1711  {
1712  paraComm->bcast(&solutionExists, 1, ParaINT, 0);
1713  }
1714  }
1715  }
1716 
1717  // allocate here, since the number of variables is fixed when the instance data are sent
1718  if( ( paraParams->getIntParamValue(UG::RampUpPhaseProcess) == 1 ||
1719  paraParams->getIntParamValue(UG::RampUpPhaseProcess) == 2 ) &&
1720  paraParams->getBoolParamValue(UG::CommunicateTighterBoundsInRacing) )
1721  {
1722  assert( instance->getNVars() > 0 );
1723  assert( instance->getVarIndexRange() > 0 );
1724  // IndexRange must be bigger than NVars
1725  tightenedVarLbs = new double[instance->getVarIndexRange()];
1726  tightenedVarUbs = new double[instance->getVarIndexRange()];
1727  for( int i = 0; i < instance->getVarIndexRange(); i++ )
1728  {
1729  tightenedVarLbs[i] = -DBL_MAX;
1730  tightenedVarUbs[i] = DBL_MAX;
1731  }
1732  }
1733 
1734 }
1735 
1736 /** get gap */
1737 double
1738 ScipParaInitiator::getAbsgap(
1739  double dualBoundValue
1740  )
1741 {
1742  if( !solution ) return SCIPinfinity(scip);
1743  SCIP_Real primalbound = instance->convertToExternalValue(solution->getObjectiveFunctionValue());
1744  SCIP_Real dualbound = instance->convertToExternalValue(dualBoundValue);
1745  return REALABS((primalbound - dualbound));
1746 }
1747 
1748 /** get gap */
1749 double
1750 ScipParaInitiator::getGap(
1751  double dualBoundValue
1752  )
1753 {
1754  if( !solution ) return SCIPinfinity(scip);
1755  SCIP_Real primalbound = instance->convertToExternalValue(solution->getObjectiveFunctionValue());
1756  SCIP_Real dualbound = instance->convertToExternalValue(dualBoundValue);
1757 
1758  if( SCIPisEQ(scip, primalbound, dualbound) )
1759  return 0.0;
1760  else if( SCIPisZero(scip, dualbound)
1761  || SCIPisZero(scip, primalbound)
1762  || SCIPisInfinity(scip, REALABS(primalbound))
1763  || SCIPisInfinity(scip, REALABS(dualbound))
1764  || primalbound * dualbound < 0.0 )
1765  return SCIPinfinity(scip);
1766  else
1767  return REALABS((primalbound - dualbound)/MIN(REALABS(dualbound),REALABS(primalbound)));
1768 }
1769 
1770 /** get epsilon */
1771 double
1772 ScipParaInitiator::getEpsilon(
1773  )
1774 {
1775  SCIP_Real epsilon;
1776  SCIP_CALL_ABORT( SCIPgetRealParam(scip, "numerics/epsilon", &epsilon));
1777  return epsilon;
1778 }
1779 
1780 void
1781 ScipParaInitiator::writeSolution(
1782  const std::string& message
1783  )
1784 {
1785  std::ostringstream osold;
1786  if( message == "Final Solution" )
1787  {
1788 #ifndef SCIP_THREADSAFE_MESSAGEHDLRS
1789  if( paraParams->getBoolParamValue(Quiet) )
1790  {
1791  SCIPmessageSetDefaultHandler(); // If no message handler is set, it cannot write solution,too.
1792  }
1793 #endif
1794  if( solvedAtInit || (!paraParams->getBoolParamValue(Quiet)) ) // when solutionFileName is specified, it is always updated
1795  {
1796  fprintf(solutionFile, "[ Final Solution ]\n");
1797  }
1798  if( transSolutionFile )
1799  {
1800  fprintf(transSolutionFile, "[ Final Solution ]\n");
1801  }
1802  }
1803  else if ( message == "Updated" )
1804  {
1805  assert( solutionFileName || (paraParams->getBoolParamValue(Quiet) && !solutionFileName ) );
1806  fclose(solutionFile);
1807  std::ostringstream os;
1808  if( solutionFileName )
1809  {
1810  osold << solutionFileName << ".old";
1811  os << solutionFileName;
1812  }
1813  else
1814  {
1815  osold << paraParams->getStringParamValue(SolutionFilePath);
1816  osold << instance->getProbName() << ".sol.old";
1817  os << paraParams->getStringParamValue(SolutionFilePath);
1818  os << instance->getProbName() << ".sol";
1819  }
1820  // std::cout << "File Name: " << os.str().c_str() << " to " << osold.str().c_str() << std::endl;
1821  if( rename(os.str().c_str(), osold.str().c_str()) )
1822  {
1823  std::cerr << "Rename falied from " << "File Name: " << os.str().c_str() << " to " << osold.str().c_str() << std::endl;
1824  exit(1);
1825  }
1826  solutionFile = fopen(os.str().c_str(), "a"); // if solution file exists, append
1827  fprintf(solutionFile, "[ Final Solution ]\n");
1828  }
1829  else
1830  {
1831  fprintf(solutionFile,"%s\n",message.c_str());
1832  if( transSolutionFile )
1833  {
1834  fprintf(transSolutionFile,"%s\n", message.c_str());
1835  }
1836  }
1837  SCIP_SOL* sol = SCIPgetBestSol(scip);
1838  if( sol )
1839  {
1840  if( solvedAtInit || (!(message == "Final Solution")) || (!paraParams->getBoolParamValue(Quiet)) ) // when solutionFileName is specified, it is always updated
1841  {
1842  SCIP_CALL_ABORT( SCIPprintBestSol( scip, solutionFile, FALSE) );
1843  }
1844  if( transSolutionFile )
1845  {
1846  if( SCIPsolGetOrigin(sol) != SCIP_SOLORIGIN_ORIGINAL )
1847  {
1848  ScipParaInstance *scipInstance = dynamic_cast<ScipParaInstance *>(instance);
1849  if( scipInstance->isOriginalIndeciesMap() )
1850  {
1851  SCIP_CALL_ABORT( SCIPprintBestSol( scipInstance->getParaInstanceScip(), transSolutionFile, FALSE) );
1852  }
1853  else
1854  {
1855  SCIP_CALL_ABORT( SCIPprintBestTransSol( scip, transSolutionFile, FALSE) );
1856  }
1857  }
1858  else
1859  {
1860  fprintf(transSolutionFile, "best solution is defined in original space - cannot print it as transformed solution\n");
1861  }
1862  }
1863  /*
1864  if( userPlugins )
1865  {
1866  userPlugins->writeUserSolution(scip);
1867  }
1868  */
1869  }
1870  else
1871  {
1872  fprintf(solutionFile, "No Solution\n");
1873  if( transSolutionFile )
1874  {
1875  fprintf(transSolutionFile, "No Solution\n");
1876  }
1877  }
1878  if ( message == "Updated" )
1879  {
1880  remove(osold.str().c_str());
1881  }
1882 }
1883 
1884 void
1885 ScipParaInitiator::writeParaInstance(
1886  const std::string& filename
1887  )
1888 {
1889  FILE *file = fopen(filename.c_str(),"a");
1890  if( !file )
1891  {
1892  std::cout << "file : " << filename << "cannot open." << std::endl;
1893  exit(1);
1894  }
1895  ScipParaInstance *scipInstance = dynamic_cast<ScipParaInstance *>(instance);
1896  if( scipInstance->isOriginalIndeciesMap() )
1897  {
1898  SCIP_CALL_ABORT( SCIPprintOrigProblem(scipInstance->getParaInstanceScip(), file, "lp", FALSE) );
1899  }
1900  else
1901  {
1902  SCIP_CALL_ABORT( SCIPprintTransProblem(scip, file, "lp", FALSE) );
1903  }
1904 }
1905 
1906 /** write solver runtime parameters */
1907 void
1908 ScipParaInitiator::writeSolverParameters(
1909  std::ostream *os
1910  )
1911 {
1912  if( scipDiffParamSetRoot->nDiffParams() == 0 )
1913  {
1914  *os << "[ SCIP parameters for root Solver are all default values ]" << std::endl;
1915  }
1916  else
1917  {
1918  *os << "[ Not default SCIP parameters for root Solver are as follows ]" << std::endl;
1919  *os << scipDiffParamSetRoot->toString();
1920  }
1921 
1922  if( scipDiffParamSet->nDiffParams() == 0 )
1923  {
1924  *os << "[ SCIP parameters for NOT root Solvers are all default values ]" << std::endl;
1925  }
1926  else
1927  {
1928  *os << "[ Not default SCIP parameters for NOT root Solvers are as follows ]" << std::endl;
1929  *os << scipDiffParamSet->toString();
1930  }
1931 
1932 }
1933 
1934 #ifdef UG_WITH_ZLIB
1935 /** write checkpoint solution */
1936 void
1937 ScipParaInitiator::writeCheckpointSolution(
1938  const std::string& filename
1939  )
1940 {
1941  gzstream::ogzstream checkpointSolutionStream;
1942  checkpointSolutionStream.open(filename.c_str(), std::ios::out | std::ios::binary);
1943  if( !checkpointSolutionStream )
1944  {
1945  std::cout << "Checkpoint file for solution cannot open. file name = " << filename << std::endl;
1946  exit(1);
1947  }
1948  if( solution )
1949  solution->write(checkpointSolutionStream);
1950  checkpointSolutionStream.close(); /** empty solution file is necessary,
1951  * because it is removed next at the next checkpoint */
1952 }
1953 
1954 /** read solution from checkpoint file */
1955 double
1956 ScipParaInitiator::readSolutionFromCheckpointFile(
1957  char *afterCheckpointingSolutionFileName
1958  )
1959 {
1960  char tempSolutionFileName[SCIP_MAXSTRLEN];
1961  (void) SCIPsnprintf(tempSolutionFileName, SCIP_MAXSTRLEN, "%s_solution.gz", prefixWarm);
1962  gzstream::igzstream checkpointSolutionStream;
1963  checkpointSolutionStream.open(tempSolutionFileName, std::ios::in | std::ios::binary);
1964  if( !checkpointSolutionStream )
1965  {
1966  std::cout << "checkpoint solution file cannot open: file name = " << tempSolutionFileName << std::endl;
1967  exit(1);
1968  }
1969  if( solution )
1970  {
1971  ScipParaSolution *sol = dynamic_cast<ScipParaSolution*>(paraComm->createParaSolution());
1972  if( sol->read(paraComm, checkpointSolutionStream) )
1973  {
1974  if( solution->getObjectiveFunctionValue() > sol->getObjectiveFunctionValue() )
1975  {
1976  delete solution;
1977  solution = sol;
1978  }
1979  }
1980  else
1981  {
1982  delete sol;
1983  }
1984  }
1985  else
1986  {
1987  solution = dynamic_cast<ScipParaSolution*>(paraComm->createParaSolution());
1988  if( !solution->read(paraComm, checkpointSolutionStream) )
1989  {
1990  delete solution;
1991  solution = 0;
1992  checkpointSolutionStream.close();
1993  }
1994  }
1995  checkpointSolutionStream.close();
1996  if( solution )
1997  {
1998  if( !tryToSetIncumbentSolution(dynamic_cast<BbParaSolution *>(solution->clone(paraComm)), true) )
1999  {
2000  std::cout << "***** Given solution is wrong! ***************************" << std::endl;
2001  std::cout << "***** If the solution was given from checkpoint file, ***" << std::endl;
2002  std::cout << "***** it might be generated in original problem space **" << std::endl;
2003  std::cout << "***** Only primal value is used. *************************" << std::endl;
2004  std::cout << "***** You should better to use -isol option. ************" << std::endl;
2005  std::cout << "***** Or, better to use no distribute solution option. ***" << std::endl;
2006  }
2007  }
2008 
2009  /** check if after checkpoing solution file exists or not */
2010  checkpointSolutionStream.open(afterCheckpointingSolutionFileName, std::ios::in | std::ios::binary);
2011  if( checkpointSolutionStream )
2012  {
2013  /** set up from after checkpointing solution file */
2014  ScipParaSolution *sol = dynamic_cast<ScipParaSolution*>(paraComm->createParaSolution());
2015  if( sol->read(paraComm, checkpointSolutionStream) )
2016  {
2017  if( !solution )
2018  {
2019  solution = sol;
2020  if( tryToSetIncumbentSolution(dynamic_cast<BbParaSolution *>(solution->clone(paraComm)), true) )
2021  {
2022  std::cout << "***** After checkpoint solution is RIGHT! ****************" << std::endl;
2023  }
2024  }
2025  else
2026  {
2027  if( solution->getObjectiveFunctionValue() > sol->getObjectiveFunctionValue() )
2028  {
2029  delete solution;
2030  solution = sol;
2031  if( tryToSetIncumbentSolution(dynamic_cast<BbParaSolution *>(solution->clone(paraComm)), true) )
2032  {
2033  std::cout << "***** After checkpoint solution is RIGHT! ****************" << std::endl;
2034  }
2035  }
2036  }
2037  }
2038  else
2039  {
2040  delete sol;
2041  }
2042  checkpointSolutionStream.close();
2043  }
2044 
2045  if( solution )
2046  {
2047  return solution->getObjectiveFunctionValue();
2048  }
2049  else
2050  {
2051  return DBL_MAX;
2052  }
2053 }
2054 #endif
2055 
2056 /** generate racing ramp-up parameter sets */
2057 void
2058 ScipParaInitiator::generateRacingRampUpParameterSets(
2059  int nParamSets,
2060  ParaRacingRampUpParamSet **racingRampUpParamSets
2061  )
2062 {
2063  ScipDiffParamSet *racingScipDiffParamSet = 0; // assume all default
2064 
2065  if ( std::string(paraParams->getStringParamValue(UG::RacingParamsDirPath)) != std::string("") )
2066  {
2067  DEF_SCIP_PARA_COMM( scipParaComm, paraComm);
2068 
2069  for( int n = 1; n < nParamSets + 1 ; n++ )
2070  {
2071  std::ostringstream oss;
2072  oss << paraParams->getStringParamValue(UG::RacingParamsDirPath)
2073  << "/"
2074  << std::setfill('0') << std::setw(5)
2075  << ( ( (n - 1) % paraParams->getIntParamValue(UG::NMaxRacingBaseParameters) ) + 1 )
2076  << ".set";
2077 
2078  SCIP_CALL_ABORT( SCIPresetParams(scip) );
2079  if( SCIPreadParams(scip, oss.str().c_str()) != SCIP_OKAY )
2080  {
2081  std::cout << "Cannot read racing parameter file = " << oss.str().c_str() << std::endl;
2082  exit(1);
2083  }
2084 
2085  racingScipDiffParamSet = scipParaComm->createScipDiffParamSet(scip);
2086  racingRampUpParamSets[n-1] = scipParaComm->createScipParaRacingRampUpParamSet(
2087  paraParams->getIntParamValue(UG::RacingRampUpTerminationCriteria),
2088  paraParams->getIntParamValue(UG::StopRacingNumberOfNodesLeft),
2089  paraParams->getRealParamValue(UG::StopRacingTimeLimit),
2090  n,
2091  ( (n - 1) % paraParams->getIntParamValue(UG::NMaxRacingBaseParameters)), // the number of variable permutation seed; start from default: 0
2092  0,
2093  racingScipDiffParamSet
2094  );
2095  SCIP_CALL_ABORT( SCIPresetParams(scip) );
2096  }
2097  }
2098  else
2099  {
2100  if( racingSettingsName )
2101  {
2102  SCIP_CALL_ABORT( SCIPresetParams(scip) );
2103  SCIP_CALL_ABORT( SCIPreadParams(scip, racingSettingsName) );
2104  // DEF_SCIP_PARA_COMM( scipParaComm, paraComm );
2105  // racingScipDiffParamSet = scipParaComm->createScipDiffParamSet(scip);
2106  // SCIP_CALL_ABORT( SCIPresetParams(scip) );
2107  }
2108  /*
2109  else
2110  {
2111  racingScipDiffParamSet = 0; // all default
2112  }*/
2113 
2114 
2115  int n = 0; /**< keep the number of generated params */
2116 #if (SCIP_VERSION < 321 || ( SCIP_VERSION == 321 && SCIP_SUBVERSION < 2) )
2117  int npm = -1; /**< keep the number of variable permutation seed; start from default: -1 */
2118 #else
2119  int npm = 0; /**< keep the number of variable permutation seed; start from default: 0 */
2120 #endif
2121  int nbo = 0; /**< keep the number of branching order seed */
2122 
2123  DEF_SCIP_PARA_COMM( scipParaComm, paraComm);
2124 
2125  for(;;)
2126  {
2127  for( int i = 0; i < paraParams->getIntParamValue(MaxNRacingParamSetSeed); i++ )
2128  {
2129 #if (SCIP_VERSION < 321 || ( SCIP_VERSION == 321 && SCIP_SUBVERSION < 2) )
2130  if( npm > ( paraParams->getIntParamValue(TryNVariablegOrderInRacing) - 1 ) ) npm = -1;
2131 #else
2132  if( npm > ( paraParams->getIntParamValue(TryNVariablegOrderInRacing) - 1 ) ) npm = 0;
2133 #endif
2134  if( nbo > paraParams->getIntParamValue(TryNBranchingOrderInRacing) ) nbo = 0;
2135  if( racingSettingsName )
2136  {
2137  racingScipDiffParamSet = scipParaComm->createScipDiffParamSet(scip);
2138  }
2139  racingRampUpParamSets[n] = scipParaComm->createScipParaRacingRampUpParamSet(
2140  paraParams->getIntParamValue(RacingRampUpTerminationCriteria),
2141  paraParams->getIntParamValue(StopRacingNumberOfNodesLeft),
2142  paraParams->getRealParamValue(StopRacingTimeLimit),
2143  i,
2144  npm,
2145  nbo,
2146  racingScipDiffParamSet
2147  );
2148  npm++;
2149  nbo++;
2150  n++;
2151  if( n >= nParamSets ) return;
2152  }
2153  }
2154  if( racingSettingsName )
2155  {
2156  SCIP_CALL_ABORT( SCIPresetParams(scip) );
2157  }
2158  }
2159 }
2160 
2161 /** get solving status string */
2162 std::string
2163 ScipParaInitiator::getStatus(
2164  )
2165 {
2166  SCIP_SOL* sol = SCIPgetBestSol(scip);
2167  if( sol )
2168  {
2169  return std::string("solution found exist");
2170  }
2171  else
2172  {
2173  return std::string("no solution");
2174  }
2175 }
2176 
2177 /** print solver version **/
2178 void
2179 ScipParaInitiator::printSolverVersion(
2180  std::ostream *os /**< output file (or NULL for standard output) */
2181  )
2182 {
2183 #ifndef SCIP_THREADSAFE_MESSAGEHDLRS
2184  SCIPprintVersion( NULL );
2185 #else
2186  SCIPprintVersion( scip, NULL );
2187 #endif
2188 
2189  SCIPprintExternalCodes(scip, NULL);
2190 }
2191 
2192 /** set initial stat on initiator */
2193 void
2194 ScipParaInitiator::accumulateInitialStat(
2195  ParaInitialStat *initialStat
2196  )
2197 {
2198  ScipParaInitialStat *scipInitialStat = dynamic_cast<ScipParaInitialStat *>(initialStat);
2199  ScipParaInstance *scipInstance = dynamic_cast<ScipParaInstance *>(instance);
2200  if( scipInstance->isOriginalIndeciesMap() )
2201  {
2202  scipInitialStat->accumulateOn(scipInstance->getParaInstanceScip());;
2203  }
2204  else
2205  {
2206  scipInitialStat->accumulateOn(scip);
2207  }
2208 }
2209 
2210 /** set initial stat on DiffSubproblem */
2211 void
2212 ScipParaInitiator::setInitialStatOnDiffSubproblem(
2213  int minDepth,
2214  int maxDepth,
2215  BbParaDiffSubproblem *diffSubproblem
2216  )
2217 {
2218  ScipParaDiffSubproblem *scipDiffSubproblem = dynamic_cast<ScipParaDiffSubproblem *>(diffSubproblem);
2219  ScipParaInstance *scipInstance = dynamic_cast<ScipParaInstance *>(instance);
2220  if( scipInstance->isOriginalIndeciesMap() )
2221  {
2222  scipDiffSubproblem->addInitialBranchVarStats(minDepth, maxDepth, scipInstance->getParaInstanceScip());
2223  }
2224  else
2225  {
2226  scipDiffSubproblem->addInitialBranchVarStats(minDepth, maxDepth, scip);
2227  }
2228 }
2229 
2230 /** set final solver status */
2231 void
2232 ScipParaInitiator::setFinalSolverStatus(
2233  FinalSolverState state
2234  )
2235 {
2236  finalState = state;
2237 }
2238 
2239 /** set number of nodes solved */
2240 void
2241 ScipParaInitiator::setNumberOfNodesSolved(
2242  long long n
2243  )
2244 {
2245  nSolved = n;
2246 }
2247 
2248 /** set final dual bound */
2249 void
2250 ScipParaInitiator::setDualBound(
2251  double bound
2252  )
2253 {
2254  if( bound > finalDualBound )
2255  {
2256  finalDualBound = bound;
2257  }
2258 }
2259 
2260 /** output solution status */
2261 void
2262 ScipParaInitiator::outputFinalSolverStatistics(
2263  std::ostream *os,
2264  double time
2265  )
2266 {
2267  if( os == 0 )
2268  {
2269  os = &std::cout;
2270  }
2271 
2272  if( finalState != Aborted )
2273  {
2274  *os << "SCIP Status : ";
2275  }
2276 
2277  switch ( finalState )
2278  {
2279  case InitialNodesGenerated:
2280  *os << "initial nodes were generated" << std::endl;
2281  break;
2282  case Aborted:
2283  *os << std::endl;
2284  break;
2286  *os << "solving was interrupted [hard time limit reached]" << std::endl;
2287  break;
2288  case MemoryLimitIsReached:
2289  *os << "solving was interrupted [memory limit reached]" << std::endl;
2290  break;
2291  case GivenGapIsReached:
2292  *os << "solving was interrupted [given gap reached]" << std::endl;
2293  break;
2295  *os << "solving was interrupted" << std::endl;
2296  break;
2297  case ProblemWasSolved:
2298  if( SCIPgetNSols(scip) > 0 )
2299  {
2300  *os << "problem is solved" << std::endl;
2301  }
2302  else
2303  {
2304  *os << "problem is solved [infeasible]" << std::endl;
2305  }
2306  break;
2308  *os << "requested subproblems are solved" << std::endl;
2309  break;
2310  default:
2311  THROW_LOGICAL_ERROR1("invalid final state");
2312  }
2313 
2314  *os << "Total Time : " << time << std::endl;
2315  *os << " solving : " << time << std::endl;
2316  *os << " presolving : " << SCIPgetPresolvingTime(scip) << " (included in solving)" << std::endl;
2317  *os << "B&B Tree :" << std::endl;
2318  *os << " nodes (total) : " << nSolved << std::endl;
2319  *os << "Solution :" << std::endl;
2320  *os << " Solutions found : " << SCIPgetNSols(scip) << std::endl;
2321  SCIP_Real primalbound = SCIPinfinity(scip);
2322  // std::cout << "** Nsols = " << SCIPgetNSols(scip) << std::endl;
2323  // if( solution )
2324  // {
2325  // std::cout << "*** obj = " << convertToExternalValue(solution->getObjectiveFuntionValue()) << std::endl;
2326  // }
2327  if( SCIPgetNSols(scip) != 0 )
2328  {
2329  primalbound = SCIPgetPrimalbound(scip);
2330  }
2331  else
2332  {
2333  if( solution && solution->getNVars() > 0 )
2334  {
2335  primalbound = solution->getObjectiveFunctionValue(); // This solution should be in original problem space.
2336  // So, do not have to convert to original space.
2337  }
2338  else
2339  {
2340  if( EPSLT( objlimit, DBL_MAX, MINEPSILON ) )
2341  {
2342  primalbound = objlimit;
2343  }
2344  }
2345  }
2346  *os << " Primal Bound : ";
2347  if( SCIPisInfinity(scip, REALABS(primalbound) ) )
2348  {
2349  *os << " -" << std::endl;
2350  }
2351  else
2352  {
2353  (*os).setf(std::ios::showpos);
2354  *os << std::scientific << std::showpoint << std::setprecision(14) << primalbound << std::endl;
2355  (*os).unsetf(std::ios::showpos);
2356  }
2357 
2358  finalDualBound = instance->convertToExternalValue(finalDualBound); // converted to original one
2359  SCIP_Real finalGap = 0.0;
2360  if( SCIPisEQ(scip, primalbound, finalDualBound) )
2361  finalGap = 0.0;
2362  else if( SCIPisZero(scip, finalDualBound)
2363  || SCIPisZero(scip, primalbound)
2364  || SCIPisInfinity(scip, REALABS(primalbound))
2365  || SCIPisInfinity(scip, REALABS(finalDualBound))
2366  || primalbound * finalDualBound < 0.0 )
2367  finalGap = SCIPinfinity(scip);
2368  else
2369  finalGap = REALABS((primalbound - finalDualBound)/MIN(REALABS(finalDualBound),REALABS(primalbound)));
2370 
2371 #if SCIP_VERSION > 302 || ( SCIP_VERSION == 302 && SCIP_SUBVERSION == 1 )
2372  *os << " Dual Bound : ";
2373 #else
2374  *os << "Dual Bound : ";
2375 #endif
2376  if( SCIPisInfinity(scip, REALABS(finalDualBound) ) )
2377  *os << " -" << std::endl;
2378  else
2379  {
2380  (*os).setf(std::ios::showpos);
2381  *os << std::scientific << std::showpoint << std::setprecision(14)
2382  << finalDualBound << std::endl;
2383  (*os).unsetf(std::ios::showpos);
2384  }
2385  *os << "Gap : ";
2386  if( SCIPgetNSols(scip) == 0 )
2387  {
2388  *os << " -" << std::endl;
2389  }
2390  else if( SCIPisInfinity(scip, finalGap ) )
2391  *os << " infinite" << std::endl;
2392  else
2393  {
2394  *os << std::fixed << std::setprecision(5) << 100.0 * finalGap << " %" << std::endl;
2395  }
2396  if( finalGap > SCIPepsilon(scip) && !SCIPisInfinity(scip, REALABS(primalbound) ) )
2397  {
2398  *os << std::scientific << "* Warning: final gap: " << finalGap << " is greater than SCIPepsilon: " << SCIPepsilon(scip) << std::endl;
2399  }
2400 
2401  assert( finalState != ProblemWasSolved ||
2402  ( finalState == ProblemWasSolved && ( SCIPgetNSols(scip) == 0 || ( SCIPgetNSols(scip) != 0 ) ) ) );
2403 
2404  if( userPlugins )
2405  {
2406  userPlugins->writeUserSolution(scip, paraComm->getSize()-1, finalDualBound);
2407  }
2408 }
2409 
2410 void
2411 ScipParaInitiator::outputProblemInfo(
2412  int *nNonLinearConsHdlrs
2413  )
2414 {
2415  std::cout << "Original Problem :" << std::endl;
2416  std::cout << " Problem name : " << SCIPgetProbName(scip) << std::endl;
2417  std::cout << " Variables : " << SCIPgetNOrigVars(scip)
2418  << " (" << SCIPgetNOrigBinVars(scip) << " binary, "
2419  << SCIPgetNOrigIntVars(scip) << " integer, "
2420  << SCIPgetNOrigImplVars(scip) << " implicit integer, "
2421  << SCIPgetNOrigContVars(scip) << " continuous)" << std::endl;
2422  std::cout << " Constraints : " << SCIPgetNOrigConss(scip) << std::endl;
2423  std::cout << " Objective sense : " << (SCIPgetObjsense(scip) == SCIP_OBJSENSE_MINIMIZE ? "minimize" : "maximize") << std::endl;
2424  std::cout << "Presolved Problem :" << std::endl;
2425  std::cout << " Variables : " << SCIPgetNVars(scip)
2426  << " (" << SCIPgetNBinVars(scip) << " binary, "
2427  << SCIPgetNIntVars(scip) << " integer, "
2428  << SCIPgetNImplVars(scip) << " implicit integer, "
2429  << SCIPgetNContVars(scip) << " continuous)" << std::endl;
2430  std::cout << " Constraints : " << SCIPgetNConss(scip) << std::endl;
2431 
2432  std::cout << "Constraints : Number" << std::endl;
2433  for( int i = 0; i < SCIPgetNConshdlrs(scip); ++i )
2434  {
2435  SCIP_CONSHDLR* conshdlr;
2436  int startnactiveconss;
2437  int maxnactiveconss;
2438  conshdlr = SCIPgetConshdlrs(scip)[i];
2439  startnactiveconss = SCIPconshdlrGetStartNActiveConss(conshdlr);
2440  maxnactiveconss = SCIPconshdlrGetMaxNActiveConss(conshdlr);
2441  if( startnactiveconss > 0 )
2442  {
2443  std::cout << " " << std::setw(17) << std::left << SCIPconshdlrGetName(conshdlr) << ": "
2444  << startnactiveconss << ( maxnactiveconss > startnactiveconss ? '+' : ' ') << std::endl;
2445  if ( std::string(SCIPconshdlrGetName(conshdlr)) != std::string("linear") )
2446  {
2447  *nNonLinearConsHdlrs += startnactiveconss;
2448  }
2449  }
2450  }
2451 }
2452 
2453 bool
2454 ScipParaInitiator::onlyLinearConsHandler(
2455  )
2456 {
2457  for( int i = 0; i < SCIPgetNConss(scip); ++i )
2458  {
2459  SCIP_CONS** conss = SCIPgetConss(scip);
2460  SCIP_CONSHDLR* conshdlr = SCIPconsGetHdlr(conss[i]);
2461  if( std::string(SCIPconshdlrGetName(conshdlr)) != std::string("linear") )
2462  {
2463  return false;
2464  }
2465  }
2466  return true;
2467 }
2468 
2469 void
2471  ScipUserPlugins *inUi
2472  )
2473 {
2474  userPlugins = inUi;
2475 }
2476 
2477 #ifdef UG_WITH_UGS
2478 /** read ugs incumbent solution **/
2479 bool
2480 ScipParaInitiator::readUgsIncumbentSolution(
2481  UGS::UgsParaCommMpi *ugsComm,
2482  int source
2483  )
2484 {
2485  UGS::UgsUpdateIncumbent *updateIncumbent = new UGS::UgsUpdateIncumbent();
2486  updateIncumbent->receive(ugsComm->getMyComm(), source);
2487 
2488  if( ( instance->getOrigObjSense() == SCIP_OBJSENSE_MINIMIZE && (convertToExternalValue(solution->getObjectiveFunctionValue()) - updateIncumbent->getObjective() ) > MINEPSILON ) ||
2489  ( instance->getOrigObjSense() == SCIP_OBJSENSE_MAXIMIZE && ( updateIncumbent->getObjective() - convertToExternalValue(solution->getObjectiveFunctionValue()) ) > MINEPSILON ) )
2490  {
2491  // std::cout << "################### SCIP: going to set the incumbnet !!! ##############" << std::endl;
2492  // std::cout << "################### in SCIP = " << convertToExternalValue(solution->getObjectiveFuntionValue()) << ", from outside = " << updateIncumbent->getObjective() << std::endl;
2493  std::ostringstream s;
2494  s << ugsComm->getSolverName(updateIncumbent->getUpdatedSolverId()) << "-" << updateIncumbent->getSeqNumber() << ".sol";
2495  SCIP_SOL *origSol;
2496  SCIP_CALL_ABORT( SCIPcreateOrigSol(scip, &origSol, NULL) );
2497  SCIP_Bool partial = FALSE;
2498  SCIP_Bool error = FALSE;
2499  SCIP_CALL_ABORT( SCIPreadSolFile(scip, s.str().c_str(), origSol, FALSE, &partial, &error ) );
2500 
2501  // std::cout << "################## partial = " << partial << ", error = " << error << " ##############" << std::endl;
2502 
2503  DEF_SCIP_PARA_COMM( scipParaComm, paraComm);
2504 
2505  if( solution ) delete solution;
2506  if( (!partial) && (!error) )
2507  {
2508  SCIP_Bool stored = FALSE;
2509  SCIP_CALL_ABORT( SCIPtrySol(scip, origSol, FALSE, TRUE, TRUE, TRUE, FALSE, &stored) );
2510 
2511  // std::cout << "################## stored = " << stored << " ##############" << std::endl;
2512 
2513  if( stored )
2514  {
2515  SCIP_SOL *sol = SCIPgetBestSol(scip);
2516  int nVars = SCIPgetNVars(scip);
2517  SCIP_VAR **vars = SCIPgetVars(scip);
2518  SCIP_Real *vals = new SCIP_Real[nVars];
2519  SCIP_CALL_ABORT( SCIPgetSolVals(scip, sol, nVars, vars, vals) );
2520  solution = scipParaComm->createScipParaSolution(
2521  0,
2522  SCIPgetSolTransObj(scip, sol), // Only this value may be used
2523  nVars,
2524  vars,
2525  vals
2526  );
2527  delete [] vals;
2528  }
2529  else
2530  {
2531  solution = scipParaComm->createScipParaSolution(
2532  0,
2533  convertToInternalValue(updateIncumbent->getObjective()), // Only this value may be used
2534  0,
2535  (SCIP_VAR **)0,
2536  0
2537  );
2538  }
2539  }
2540  else
2541  {
2542  solution = scipParaComm->createScipParaSolution(
2543  0,
2544  convertToInternalValue(updateIncumbent->getObjective()), // Only this value may be used
2545  0,
2546  (SCIP_VAR **)0,
2547  0
2548  );
2549  }
2550 
2551  SCIP_CALL_ABORT( SCIPfreeSol(scip, &origSol) );
2552 
2553  delete updateIncumbent;
2554 
2555  return true;
2556 
2557  }
2558  else
2559  {
2560  delete updateIncumbent;
2561  return false;
2562  }
2563 }
2564 
2565 /** write ugs incumbent solution **/
2566 void
2567 ScipParaInitiator::writeUgsIncumbentSolution(
2568  UGS::UgsParaCommMpi *ugsComm
2569  )
2570 {
2571  /* Write out the solution */
2572  seqNumber++;
2573  std::ostringstream s;
2574  s << ugsComm->getMySolverName() << "-" << seqNumber << ".sol";
2575  FILE *fp = fopen(s.str().c_str(), "w");
2576  if( fp == NULL )
2577  {
2578  fprintf (stderr, "Cannot open solution file to write. File name = %s\n", s.str().c_str());
2579  exit(1);
2580  }
2581 
2582  SCIP_SOL* sol = SCIPgetBestSol(scip);
2583 
2584  assert(sol);
2585  fprintf( fp, "# ");
2586 
2587  SCIP_CALL_ABORT( SCIPprintSol(scip, sol, fp, TRUE) );
2588 
2589  fclose(fp);
2590 
2591  UGS::UgsUpdateIncumbent *uui = new UGS::UgsUpdateIncumbent(ugsComm->getMySolverId(), seqNumber, convertToExternalValue(solution->getObjectiveFunctionValue()) );
2592  uui->send(ugsComm->getMyComm(),0);
2593  // std::cout << "Rank" << ugsComm->getRank() << " Sent to 0: " << uui->toString() << std::endl;
2594  delete uui;
2595 
2596  return;
2597 }
2598 #endif
initial nodes were generated
#define SCIP_PRESOLVIG_MEMORY_FACTOR
ParaInstance extenstion for SCIP solver.
static const int LogSolvingStatusFilePath
Definition: paraParamSet.h:127
void setObjectiveFuntionValue(SCIP_Real val)
static const int TryNBranchingOrderInRacing
class for solution
static const int RacingParamsDirPath
Definition: paraParamSet.h:131
static const int NMaxRacingBaseParameters
class BbParaParamSet
static const int RacingRampUpTerminationCriteria
static const int SolverSettingsExceptRootNode
static const int TryNVariablegOrderInRacing
void setValue(int i, SCIP_Real val)
#define REALABS(x)
Definition: paraDef.h:165
void getSolValuesForOriginalProblem(ScipParaSolution *sol, SCIP_Real *vals)
requested subproblem was solved
#define PARA_COMM_CALL(paracommcall)
Definition: paraComm.h:47
static const int UseRootNodeCuts
static const int ParaDOUBLE
Definition: paraComm.h:76
static const int SolverSettingsAtRacing
FinalSolverState
Final status of computation.
#define EPSEQ(x, y, eps)
Definition: paraDef.h:166
void setUserPlugins(ParaInitiator *initiator)
#define SCIP_MEMORY_COPY_FACTOR
problem was solved
static const int NoUpperBoundTransferInRacing
hard time limit is reached
#define THROW_LOGICAL_ERROR1(msg1)
Definition: paraDef.h:52
static const int SolutionFilePath
Definition: paraParamSet.h:129
given gap is reached for the computation
long long virtualMemUsedAtLc
Definition: fscip.cpp:70
#define EPSLT(x, y, eps)
Definition: paraDef.h:167
Class for the difference between instance and subproblem.
static const int CheckFeasibilityInLC
memory limit is reached in a solver
class ParaParamSet
Definition: paraParamSet.h:850
static const int MaxNRacingParamSetSeed
void addInitialBranchVarStats(int minDepth, int maxDepth, SCIP *scip)
static const int InstanceTransferMethod
computing was interrupted
static const int DistributeBestPrimalSolution
static const int OutputPresolvedInstance
SCIP message handler for ParaSCIP and FiberSCIP.
static const int MemoryLimit
static const int Quiet
Definition: paraParamSet.h:71
static const int StopRacingNumberOfNodesLeft
#define SCIP_FIXED_MEMORY_FACTOR
static const int StopRacingTimeLimit
class for initial statistics collecting after racing
static const int RampUpPhaseProcess
static const int CommunicateTighterBoundsInRacing
static const int TimeLimit
Definition: paraParamSet.h:106
#define MINEPSILON
Definition: paraDef.h:50
static const int ParaINT
Definition: paraComm.h:66
double memoryLimitOfSolverSCIP
Definition: fscip.cpp:71
ParaInitiator extension for SCIP solver.
class ParaRacingRampUpParamSet (parameter set for racing ramp-up)
static const int SolverSettingsForInitialPresolving
static const int NoPreprocessingInLC
ParaInitialStat extension for SCIP solver.
static const int SolverSettingsAtRootNode
#define DEF_SCIP_PARA_COMM(scip_para_comm, comm)
#define THROW_LOGICAL_ERROR3(msg1, msg2, msg3)
Definition: paraDef.h:86