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