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-2024 by Zuse Institute Berlin, */
8/* licensed under LGPL version 3 or later. */
9/* Commercial licenses are available through <licenses@zib.de> */
10/* */
11/* This code is free software; you can redistribute it and/or */
12/* modify it under the terms of the GNU Lesser General Public License */
13/* as published by the Free Software Foundation; either version 3 */
14/* of the License, or (at your option) any later version. */
15/* */
16/* This program is distributed in the hope that it will be useful, */
17/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
18/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
19/* GNU Lesser General Public License for more details. */
20/* */
21/* You should have received a copy of the GNU Lesser General Public License */
22/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
23/* */
24/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
25
26/**@file 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 << "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 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 ********************/
224 {
226 }
228 {
230 }
232 {
234 }
235 if( std::string(paraParams->getStringParamValue(SolverSettingsAtRacing)) != "" )
236 {
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
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;
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 if( getAbsgapValue(paramScip) > MINEPSILON || getGapValue(paramScip) > MINEPSILON )
517 {
519 {
521 std::cout << "** RampUpPhaseProcess is switched to 1, since gap for solvers is specified" << std::endl;
522 }
523 }
524 }
525 else
526 {
527 scipDiffParamSet = scipParaComm->createScipDiffParamSet(scip);
529 {
531 {
533 std::cout << "** RampUpPhaseProcess is switched to 1, since gap for solvers is specified" << std::endl;
534 }
535 }
536 }
537
538 if( settingsNameRoot != NULL )
539 {
540 SCIP_CALL_ABORT( SCIPreadParams(scip, settingsNameRoot) );
541 // SCIP_CALL( SCIPresetParams(paramScip) );
542 SCIP_CALL_ABORT( SCIPreadParams(paramScip, settingsNameRoot) );
543 scipDiffParamSetRoot = scipParaComm->createScipDiffParamSet(paramScip);
544 // Root settings are used for LC. They should be a part of root process.
545 // SCIP_CALL( SCIPresetParams(scip) );
546 if( getAbsgapValue(paramScip) > MINEPSILON || getGapValue(paramScip) > MINEPSILON )
547 {
549 {
551 std::cout << "** RampUpPhaseProcess is switched to 1, since gap for root node is specified" << std::endl;
552 }
553 }
554 }
555 else
556 {
557 scipDiffParamSetRoot = scipParaComm->createScipDiffParamSet(scip);
559 {
561 {
563 std::cout << "** RampUpPhaseProcess is switched to 1, since gap for root node is specified" << std::endl;
564 }
565 }
566 }
567
568 if( settingsNameLC != NULL )
569 {
570 // SCIP_CALL( SCIPresetParams(scip) );
571 SCIP_CALL_ABORT( SCIPreadParams(scip, settingsNameLC) );
572 std::cout << "** applied absolute gap = " << getAbsgapValue() << std::endl;
573 std::cout << "** applied relative gap = " << getGapValue() << std::endl;
575 {
577 {
579 std::cout << "** RampUpPhaseProcess is switched to 1, since gap is specified" << std::endl;
580 }
581 }
582 }
583
584
585 if( paramScip )
586 {
587 SCIP_CALL_ABORT( SCIPfree(&paramScip) );
588 paramScip = 0;
589 }
590
591
592 /**************
593 * Start SCIP *
594 **************/
595 /** user include plugins */
596 // includeUserPlugins(scip); // need to set user plugins: should be set
597
598 // Problem Creation
599
600 SCIP_RETCODE retcode = SCIPreadProb(scip, probname, NULL);
601 if( retcode != SCIP_OKAY )
602 {
603 std::cout << "error reading file <" << probname << ">" << std::endl;
604 SCIP_CALL( SCIPfreeProb(scip) );
605 exit(1);
606 }
607
608 /* transform the problem */
609 SCIP_CALL_ABORT( SCIPtransformProb(scip));
610
611 /* read initail solution, if it is specified */
612 if( isolname )
613 {
614 // NOTE:
615 // When CPLEX license file cannot find, SCIPtransformProb(scip) may fail
616 // SCIP_CALL_ABORT( SCIPreadSol(scip, isolname) );
617 SCIP_CALL_ABORT( SCIPreadProb(scip, isolname, 0) );
618 }
619
620 /* change problem name */
621 char *probNameFromFileName;
622 char *temp = new char[strlen(probname)+1];
623 (void) strcpy(temp, probname);
624 SCIPsplitFilename(temp, NULL, &probNameFromFileName, NULL, NULL);
625 SCIP_CALL_ABORT( SCIPsetProbName(scip, probNameFromFileName));
626 delete [] temp;
627
628 /* presolve problem */
630 {
631 if( SCIPfindConshdlr(scip, "pseudoboolean") == NULL || SCIPconshdlrGetNConss(SCIPfindConshdlr(scip, "pseudoboolean")) == 0 ) // this is workaround for a bug.
632 {
633 SCIP_CALL_ABORT( SCIPsetIntParam(scip, "presolving/maxrounds", 0) );
634 std::cout << "No LC presolving is specified." << std::endl;
635 }
636 else
637 {
638 std::cout << "Default LC presolving (default)." << std::endl;
639 }
640 }
641 else
642 {
643 if( settingsNameLC )
644 {
645 SCIP_CALL_ABORT( SCIPreadParams(scip, settingsNameLC) );
646 std::cout << "LC presolving settings file is specified." << std::endl;
647 }
648 else
649 {
650 // SCIP_CALL_ABORT( SCIPsetPresolving(scip, SCIP_PARAMSETTING_FAST, TRUE) );
651 std::cout << "Default LC presolving (default)." << std::endl;
652 }
653 }
654 // SCIP_CALL_ABORT( SCIPsetIntParam(scip, "constraints/quadratic/replacebinaryprod", 0));
655 // SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/nonlinear/reformulate", FALSE));
656
657 /* don't catch control+c */
658 SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "misc/catchctrlc", FALSE) );
659
660 /* objlimit is specified */
661 if( EPSLT( objlimit, DBL_MAX, MINEPSILON ) )
662 {
663 SCIP_CALL_ABORT( SCIPsetObjlimit(scip, objlimit) );
664 }
665
666
667// #ifdef _COMM_PTH
668// SCIP_CALL( SCIPsetBoolParam(scip, "misc/catchctrlc", FALSE) );
669// #endif
670
671 SCIP_Bool originalUpgradeKnapsack;
672 SCIP_Bool originalUpgradeLogicor;
673 SCIP_Bool originalUpgradeSetppc;
674 SCIP_Bool originalUpgradeVarbound;
675 bool onlyLinearConss = onlyLinearConsHandler();
676#ifdef _COMM_MPI_WORLD
677 if( onlyLinearConss )
678 {
679 std::cout << "** Original problem has only linear constraints" << std::endl;
680 }
681 else
682 {
683 std::cout << "** Original problem has non-linear constraints" << std::endl;
684 }
686 {
687 if( onlyLinearConss )
688 {
689 SCIP_CALL_ABORT( SCIPgetBoolParam(scip, "constraints/linear/upgrade/knapsack", &originalUpgradeKnapsack));
690 SCIP_CALL_ABORT( SCIPgetBoolParam(scip, "constraints/linear/upgrade/logicor", &originalUpgradeLogicor));
691 SCIP_CALL_ABORT( SCIPgetBoolParam(scip, "constraints/linear/upgrade/setppc", &originalUpgradeSetppc));
692 SCIP_CALL_ABORT( SCIPgetBoolParam(scip, "constraints/linear/upgrade/varbound", &originalUpgradeVarbound));
693 SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/knapsack", FALSE));
694 SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/logicor", FALSE));
695 SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/setppc", FALSE));
696 SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/varbound", FALSE));
697 }
698 }
699#else
700 if( noUpgrade )
701 {
702 SCIP_CALL_ABORT( SCIPgetBoolParam(scip, "constraints/linear/upgrade/knapsack", &originalUpgradeKnapsack));
703 SCIP_CALL_ABORT( SCIPgetBoolParam(scip, "constraints/linear/upgrade/logicor", &originalUpgradeLogicor));
704 SCIP_CALL_ABORT( SCIPgetBoolParam(scip, "constraints/linear/upgrade/setppc", &originalUpgradeSetppc));
705 SCIP_CALL_ABORT( SCIPgetBoolParam(scip, "constraints/linear/upgrade/varbound", &originalUpgradeVarbound));
706 SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/knapsack", FALSE));
707 SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/logicor", FALSE));
708 SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/setppc", FALSE));
709 SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/varbound", FALSE));
710 }
711#endif
712
713#ifdef UG_DEBUG_SOLUTION
714 SCIPdebugSolDisable(scip);
715#endif
716
717 // instance = new PARA_INSTANCE_TYPE(scip, paraParams->getIntParamValue(InstanceTransferMethod));
718 /** instance needs to be generated befor presolving **/
719 instance = scipParaComm->createScipParaInstance(scip, paraParams->getIntParamValue(InstanceTransferMethod));
720
721 std::ostringstream os;
722
723 if( !qsol )
724 {
725 if( solutionFileName )
726 {
727 os << solutionFileName;
728 }
729 else
730 {
732 os << instance->getProbName() << ".sol";
733 }
734 solutionFile = fopen(os.str().c_str(), "a"); // if solution file exists, append
735 if( solutionFile == NULL )
736 {
737 THROW_LOGICAL_ERROR3("cannot open solution file <", os.str(), "> for writing");
738 }
739 }
740
741#if defined(_COMM_PTH) || defined (_COMM_CPP11)
742#ifdef __linux__
743 long long vmSizeBeforePresolving = getVmSize();
744 virtualMemUsedAtLc = std::max(vmSizeBeforePresolving, (SCIPgetMemTotal(scip) + SCIPgetMemExternEstim(scip)));
745 std::cout << "** Before presolving: virtualMemUsedAtLc = " << virtualMemUsedAtLc << ", getVmSize() = " << getVmSize() << ", SCIPgetMemUsed() = " << SCIPgetMemUsed(scip) << ", SCIPgetMemTotal() = " << SCIPgetMemTotal(scip) << ", SCIPgetMemExternEstim() = " << SCIPgetMemExternEstim(scip) << std::endl;
746#else
747 virtualMemUsedAtLc = SCIPgetMemTotal(scip) + SCIPgetMemExternEstim(scip);
748 std::cout << "** Before presolving: virtualMemUsedAtLc = " << virtualMemUsedAtLc << ", SCIPgetMemUsed() = " << SCIPgetMemUsed(scip) << ", SCIPgetMemTotal() = " << SCIPgetMemTotal(scip) << ", SCIPgetMemExternEstim() = " << SCIPgetMemExternEstim(scip) << std::endl;
749#endif
750 // if( (dynamic_cast<ScipParaParamSet *>(paraParams)->getRealParamValue(MemoryLimit) - (virtualMemUsedAtLc*SCIP_FIXED_MEMORY_FACTOR))/(paraComm->getSize()-1) > virtualMemUsedAtLc*SCIP_FIXED_MEMORY_FACTOR )
752 {
753 // 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.
754 SCIP_CALL_ABORT( SCIPsetRealParam(scip, "limits/memory", dynamic_cast<ScipParaParamSet *>(paraParams)->getRealParamValue(MemoryLimit) - virtualMemUsedAtLc*SCIP_FIXED_MEMORY_FACTOR*paraComm->getSize()) ); // LC has SCIP env.
755 }
756 else
757 {
758 SCIP_CALL_ABORT( SCIPsetIntParam(scip, "presolving/maxrounds", 0) );
759 std::cout << "** No LC presolving is applied, since memory limit becomes "
760 // << (dynamic_cast<ScipParaParamSet *>(paraParams)->getRealParamValue(MemoryLimit) - (virtualMemUsedAtLc*SCIP_FIXED_MEMORY_FACTOR))/(paraComm->getSize()-1)
761 << dynamic_cast<ScipParaParamSet *>(paraParams)->getRealParamValue(MemoryLimit)
762 << " < "
763 // << virtualMemUsedAtLc*SCIP_FIXED_MEMORY_FACTOR
765 << std::endl;
766 SCIP_CALL( SCIPpresolve(scip) );
767 solvedAtInit = true;
769 // finalDualBound = SCIPgetDualbound(scip);
770 std::cout << "=== solved at Init ===" << std::endl;
772 writeSolution("Final Solution");
773 return 1;
774 }
775 // 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;
776 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;
777#else
778 SCIP_CALL_ABORT( SCIPsetRealParam(scip, "limits/memory", dynamic_cast<ScipParaParamSet *>(paraParams)->getRealParamValue(MemoryLimit)) );
779 std::cout << "** set memory limit for presolving in LC and solvers to " << dynamic_cast<ScipParaParamSet *>(paraParams)->getRealParamValue(MemoryLimit) << " for each SCIP **" << std::endl;
780#endif
781
782#if SCIP_APIVERSION >= 101
783 SCIP_PARAM* milp_threads = SCIPgetParam(scip, "presolving/milp/threads");
784 if( milp_threads != NULL && SCIPparamGetIntMax(milp_threads) > 1 )
785 {
786#ifdef _COMM_MPI_WORLD
787 SCIP_CALL_ABORT( SCIPsetIntParam(scip, "presolving/milp/threads", 0) );
788#else
789 SCIP_CALL_ABORT( SCIPsetIntParam(scip, "presolving/milp/threads", (paraComm->getSize() - 1)) );
790#endif
791 }
792#endif
793
795 {
796 double timeRemains = std::max( 0.0, (paraParams->getRealParamValue(UG::TimeLimit) - timer->getElapsedTime()) );
797 SCIP_CALL_ABORT( SCIPsetIntParam(scip,"timing/clocktype", 2) ); // to confirm this for the scip environment actually to work
798 SCIP_CALL_ABORT( SCIPsetRealParam(scip,"limits/time", timeRemains) );
799 }
800
801 SCIP_CALL( SCIPpresolve(scip) );
802 SCIP_STATUS scipStatus = SCIPgetStatus(scip);
803
804 if( scipStatus == SCIP_STATUS_OPTIMAL ||
805 scipStatus == SCIP_STATUS_INFEASIBLE ) // when sub-MIP is solved at root node, the solution may not be saved
806 {
807 solvedAtInit = true;
809 // finalDualBound = SCIPgetDualbound(scip);
810 std::cout << "=== solved at Init ===" << std::endl;
812 writeSolution("Final Solution");
813 return 1;
814 }
815 else if( scipStatus == SCIP_STATUS_MEMLIMIT )
816 {
817 solvedAtInit = true;
819 // finalDualBound = SCIPgetDualbound(scip);
820 std::cout << "=== solved at Init ===" << std::endl;
822 writeSolution("Final Solution");
823 return 1;
824 }
825 else
826 {
827 if( scipStatus == SCIP_STATUS_TIMELIMIT )
828 {
829 solvedAtInit = true;
831 // finalDualBound = SCIPgetDualbound(scip);
832 std::cout << "=== solved at Init ===" << std::endl;
834 writeSolution("Final Solution");
835 return 1;
836 }
837 else
838 {
839 /* adding root node cuts, if necessary */
841 {
842 if( !addRootNodeCuts() )
843 {
844 solvedAtInit = true;
846 // finalDualBound = SCIPgetDualbound(scip);
847 std::cout << "=== solved at Init ===" << std::endl;
849 writeSolution("Final Solution");
850 return 1;
851 }
852 else
853 {
856 {
857 solvedAtInit = true;
859 // finalDualBound = SCIPgetDualbound(scip);
860 std::cout << "=== solved at Init ===" << std::endl;
862 writeSolution("Final Solution");
863 return 1;
864 }
865 }
866 }
867 }
868 }
869
870#if defined(_COMM_PTH) || defined (_COMM_CPP11)
871#ifdef __linux__
872 // int nCores = sysconf(_SC_NPROCESSORS_CONF);
873 long long vmSize = getVmSize();
874 long long vmSizeForSolver = (vmSize - vmSizeBeforePresolving)/paraComm->getSize() + vmSizeBeforePresolving;
875 virtualMemUsedAtLc = std::max(vmSizeForSolver, (SCIPgetMemTotal(scip) + SCIPgetMemExternEstim(scip)))/SCIP_PRESOLVIG_MEMORY_FACTOR; /// in genral, it looks over estimated
876 std::cout << "** Estimated virtualMemUsedAtSolver = " << virtualMemUsedAtLc << ", getVmSize() = " << vmSize << ", SCIPgetMemUsed() = " << SCIPgetMemUsed(scip) << ", SCIPgetMemTotal() = " << SCIPgetMemTotal(scip) << ", SCIPgetMemExternEstim() = " << SCIPgetMemExternEstim(scip) << std::endl;
877#else
878 virtualMemUsedAtLc = SCIPgetMemTotal(scip) + SCIPgetMemExternEstim(scip);
879 std::cout << "** Estimated virtualMemUsedAtSolver = " << virtualMemUsedAtLc << ", SCIPgetMemUsed() = " << SCIPgetMemUsed(scip) << ", SCIPgetMemTotal() = " << SCIPgetMemTotal(scip) << ", SCIPgetMemExternEstim() = " << SCIPgetMemExternEstim(scip) << std::endl;
880#endif
881 // memoryLimitOfSolverSCIP = (dynamic_cast<ScipParaParamSet *>(paraParams)->getRealParamValue(MemoryLimit) - (virtualMemUsedAtLc*SCIP_FIXED_MEMORY_FACTOR))/((paraComm->getSize()-1)*SCIP_MEMORY_COPY_FACTOR);
883 std::cout << "** set memory limit for solvers to " << memoryLimitOfSolverSCIP << " for each SCIP **" << std::endl;
885 {
886 solvedAtInit = true;
888 // finalDualBound = SCIPgetDualbound(scip);
889 std::cout << "=== solved at Init ===" << std::endl;
891 writeSolution("Final Solution");
892 return 1;
893 }
894#endif
895
896 // output presolved instance information
897 int nNonLinearConsHdlrs = 0;
898 outputProblemInfo(&nNonLinearConsHdlrs);
899#ifdef _COMM_MPI_WORLD
900 if( SCIPgetNActiveBenders(scip) > 0 ) nNonLinearConsHdlrs++;
902 paraComm->bcast( &nNonLinearConsHdlrs, 1, ParaINT, 0 )
903 );
904 if( nNonLinearConsHdlrs > 0 )
905 {
907 }
908#endif
909 std::cout << "** Instance transfer method used: " << paraParams->getIntParamValue(InstanceTransferMethod) << std::endl;
910
911 if( SCIPgetNVars(scip) == 0 ) // all variables were fixed in presolve
912 {
913 SCIP_CALL( SCIPsolve(scip) );
914 solvedAtInit = true;
916 // finalDualBound = SCIPgetDualbound(scip);
917 std::cout << "=== solved at Init ===" << std::endl;
919 writeSolution("Final Solution");
920 return 1;
921 }
922
923 /** check if feasible solution is found or not. If it was found, then generate paraSolution */
924 SCIP_SOL *sol = SCIPgetBestSol(scip);
925 // std::cout << "solobj = " << SCIPgetSolOrigObj(scip, sol) << ", objlimit = " << SCIPgetObjlimit(scip) << std::endl;
926 if( sol )
927 {
928 if( EPSLT( objlimit, DBL_MAX, MINEPSILON ) )
929 {
930 if( ( SCIPgetObjsense(scip) == SCIP_OBJSENSE_MINIMIZE && SCIPgetSolOrigObj(scip, sol) < objlimit ) ||
931 ( SCIPgetObjsense(scip) == SCIP_OBJSENSE_MAXIMIZE && SCIPgetSolOrigObj(scip, sol) > objlimit ) )
932 {
933 int nVars = SCIPgetNVars(scip);
934 SCIP_VAR **vars = SCIPgetVars(scip);
935 SCIP_Real *vals = new SCIP_Real[nVars];
936 SCIP_CALL_ABORT( SCIPgetSolVals(scip, sol, nVars, vars, vals) );
937 solution = scipParaComm->createScipParaSolution(
938 0,
939 SCIPgetSolTransObj(scip, sol), // Only this value may be used
940 nVars,
941 vars,
942 vals
943 );
944 delete [] vals;
945 }
946 else
947 {
948 solution = scipParaComm->createScipParaSolution(
949 0,
950 ( ( objlimit / ( SCIPgetTransObjscale(scip) * SCIPgetObjsense(scip) ) ) - SCIPgetTransObjoffset(scip) ), // Only this value may be used
951 0,
952 (SCIP_VAR **)0,
953 0
954 );
955 }
956 }
957 else
958 {
959 int nVars = SCIPgetNVars(scip);
960 SCIP_VAR **vars = SCIPgetVars(scip);
961 SCIP_Real *vals = new SCIP_Real[nVars];
962 SCIP_CALL_ABORT( SCIPgetSolVals(scip, sol, nVars, vars, vals) );
963 solution = scipParaComm->createScipParaSolution(
964 0,
965 SCIPgetSolTransObj(scip, sol), // Only this value may be used
966 0,
967 (SCIP_VAR **)0,
968 0
969 );
970 delete [] vals;
971 }
972 }
973 else
974 {
975 if( EPSLT( objlimit, DBL_MAX, MINEPSILON ) )
976 {
977 solution = scipParaComm->createScipParaSolution(
978 0,
979 ( ( objlimit / ( SCIPgetTransObjscale(scip) * SCIPgetObjsense(scip) ) ) - SCIPgetTransObjoffset(scip) ), // Only this value may be used
980 0,
981 (SCIP_VAR **)0,
982 0
983 );
984 }
985 }
986
987
988
989 // instance = new PARA_INSTANCE_TYPE(scip, paraParams->getIntParamValue(InstanceTransferMethod));
990 #ifdef _COMM_MPI_WORLD
991 /** In ParaSCIP case, instance have to provided for the presolved instance **/
992 delete instance;
993 instance = scipParaComm->createScipParaInstance(scip, paraParams->getIntParamValue(InstanceTransferMethod));
994 #endif
995 // instance = scipParaComm->createScipParaInstance(scip, paraParams->getIntParamValue(InstanceTransferMethod));
996
997 /* for debugging
998 std::string subcipprefix("presolved_");
999 std::string subcipfilename;
1000 std::ostringstream oss;
1001 oss << subcipprefix;
1002 oss << instance->getProbName();
1003 subcipfilename = oss.str();
1004 subcipfilename += ".lp";
1005 if( SCIPgetStage(scip) >= SCIP_STAGE_TRANSFORMED )
1006 {
1007 SCIP_CALL_ABORT( SCIPwriteTransProblem(scip, subcipfilename.c_str(), "lp", FALSE) );
1008 }
1009 ************************/
1010
1011#ifdef _COMM_MPI_WORLD
1012 if( onlyLinearConss && paraParams->getIntParamValue(UG::InstanceTransferMethod) != 2 )
1013 {
1014 // restore original parameters
1015 SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/knapsack", originalUpgradeKnapsack));
1016 SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/logicor", originalUpgradeLogicor));
1017 SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/setppc", originalUpgradeSetppc));
1018 SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/varbound", originalUpgradeVarbound));
1019 }
1020#else
1021 if( noUpgrade )
1022 {
1023 SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/knapsack", originalUpgradeKnapsack));
1024 SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/logicor", originalUpgradeLogicor));
1025 SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/setppc", originalUpgradeSetppc));
1026 SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/varbound", originalUpgradeVarbound));
1027 }
1028#endif
1029
1030 int maxrounds = 0;
1031 SCIP_CALL_ABORT( SCIPgetIntParam(scip, "presolving/maxrounds", &maxrounds));
1032 if( !paraParams->getBoolParamValue(Quiet) && maxrounds != 0 && !qsol )
1033 {
1034 os << ".trans";
1035 transSolutionFile = fopen(os.str().c_str(), "a"); // if trans. solution file exists, append
1036 if( transSolutionFile == NULL )
1037 {
1038 THROW_LOGICAL_ERROR3("cannot open solution file <", os.str(), "> for writing");
1039 }
1040 }
1042 {
1043 std::ostringstream os2;
1045 if( onlyLinearConss )
1046 {
1047 os2 << instance->getProbName() << "_presolved.lp";
1048 }
1049 else
1050 {
1051 os2 << instance->getProbName() << "_presolved.cip";
1052 }
1053 SCIP_CALL_ABORT( SCIPwriteTransProblem(scip, os2.str().c_str(), NULL, FALSE));
1054 }
1055 }
1056 else
1057 {
1058 std::cout << std::endl;
1059 std::cout << "syntax: " << argv[0] << " fscip_param_file problem_file_name "
1060 << "[-l <logfile>] [-q] [-sl <settings>] [-s <settings>] [-sr <root_settings>] [-w <prefix_warm>] [-sth <number>] [-fsol <solution_file>] [-isol <initial solution file]" << std::endl;
1061 std::cout << " -l <logfile> : copy output into log file" << std::endl;
1062 std::cout << " -q : suppress screen messages" << std::endl;
1063 std::cout << " -sl <settings> : load parameter settings (.set) file for LC presolving" << std::endl;
1064 std::cout << " -s <settings> : load parameter settings (.set) file for solvers" << std::endl;
1065 std::cout << " -sr <root_settings> : load parameter settings (.set) file for root" << std::endl;
1066 std::cout << " -w <prefix_warm> : warm start file prefix ( prefix_warm_nodes.gz and prefix_warm_solution.txt are read )" << std::endl;
1067 std::cout << " -sth <number> : the number of solver threads used" << std::endl;
1068 std::cout << " -fsol <solution file> : specify output solution file" << std::endl;
1069 std::cout << " -qsol : quit to output solution file" << std::endl;
1070 std::cout << " -isol <intial solution file> : specify initial solution file" << std::endl;
1071 THROW_LOGICAL_ERROR1("invalid parameter");
1072 }
1073
1074 if( solution )
1075 {
1077 {
1078 writeSolution("");
1079 }
1080 else
1081 {
1082 writeSolution("Updated");
1083 }
1084 }
1085
1086 return 0;
1087}
1088
1089/** reInit function */
1090int
1092 int nRestartedRacing
1093 )
1094{
1095 /** save incumbent solution */
1096 char initSolFileName[SCIP_MAXSTRLEN];
1097
1098 if( isolname )
1099 {
1100 (void) SCIPsnprintf(initSolFileName, SCIP_MAXSTRLEN, "%s.%d", isolname, nRestartedRacing);
1101 if( !rename( isolname, initSolFileName ) )
1102 {
1103 std::cout << "Warning: initial solution file name cannot rename: " << isolname << ", " << nRestartedRacing << "'th restarted file." << std::endl;
1104 // perror("cannot rename");
1105 // THROW_LOGICAL_ERROR1("cannot rename solution file");
1106 }
1107 if( !generatedIsolname )
1108 {
1109 (void) SCIPsnprintf(initSolFileName, SCIP_MAXSTRLEN, "%s", isolname);
1110 generatedIsolname = new char[strlen(initSolFileName)+1];
1111 (void) strcpy(generatedIsolname, initSolFileName);
1112 }
1113 }
1114 else
1115 {
1116 if( !generatedIsolname )
1117 {
1118 (void) SCIPsnprintf(initSolFileName, SCIP_MAXSTRLEN, "i_%s.sol", instance->getProbName());
1119 generatedIsolname = new char[strlen(initSolFileName)+1];
1120 (void) strcpy(generatedIsolname, initSolFileName);
1121 }
1122 }
1123
1124 FILE *fp = fopen(generatedIsolname, "w");
1125 if( !fp )
1126 {
1127 std::cout << "Could not open " << generatedIsolname << " file to reinitialize for restart." << std::endl;
1128 abort();
1129 }
1130 assert( SCIPgetBestSol(scip) );
1131 SCIP_CALL_ABORT( SCIPprintBestSol( scip, fp, FALSE) );
1132 (void) fclose(fp);
1133
1134 // Problem Creation
1135 SCIP_RETCODE retcode = SCIPreadProb(scip, probname, NULL);
1136 if( retcode != SCIP_OKAY )
1137 {
1138 std::cout << "error reading file <" << probname << ">" << std::endl;
1139 SCIP_CALL( SCIPfreeProb(scip) );
1140 exit(1);
1141 }
1142
1143 // std::cout << "problem name in initiator ' " << SCIPgetProbName(scip) << std::endl;
1144
1145 SCIP_CALL_ABORT( SCIPtransformProb(scip));
1146 // NOTE:
1147 // When CPLEX license file cannot find, SCIPtransformProb(scip) may fail
1148 SCIP_CALL_ABORT( SCIPreadSol(scip, generatedIsolname) );
1149
1150 /* change problem name */
1151 char *probNameFromFileName;
1152 char *temp = new char[strlen(probname)+1];
1153 (void) strcpy(temp, probname);
1154 SCIPsplitFilename(temp, NULL, &probNameFromFileName, NULL, NULL);
1155 SCIP_CALL_ABORT( SCIPsetProbName(scip, probNameFromFileName));
1156 delete [] temp;
1157
1158#if ( defined(_COMM_PTH) || defined(_COMM_CPP11) )
1159 SCIP_CALL( SCIPsetBoolParam(scip, "misc/catchctrlc", FALSE) );
1160#endif
1161
1162#ifdef _COMM_MPI_WORLD
1163 SCIP_Bool originalUpgradeKnapsack;
1164 SCIP_Bool originalUpgradeLogicor;
1165 SCIP_Bool originalUpgradeSetppc;
1166 SCIP_Bool originalUpgradeVarbound;
1167 bool onlyLinearConss = onlyLinearConsHandler();
1168 if( onlyLinearConss )
1169 {
1170 SCIP_CALL_ABORT( SCIPgetBoolParam(scip, "constraints/linear/upgrade/knapsack", &originalUpgradeKnapsack));
1171 SCIP_CALL_ABORT( SCIPgetBoolParam(scip, "constraints/linear/upgrade/logicor", &originalUpgradeLogicor));
1172 SCIP_CALL_ABORT( SCIPgetBoolParam(scip, "constraints/linear/upgrade/setppc", &originalUpgradeSetppc));
1173 SCIP_CALL_ABORT( SCIPgetBoolParam(scip, "constraints/linear/upgrade/varbound", &originalUpgradeVarbound));
1174 SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/knapsack", FALSE));
1175 SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/logicor", FALSE));
1176 SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/setppc", FALSE));
1177 SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/varbound", FALSE));
1178 }
1179#endif
1180
1181 SCIP_CALL( SCIPpresolve(scip) );
1182 SCIP_STATUS scipStatus = SCIPgetStatus(scip);
1183
1184 // output presolved instance information
1185 int nNonLinearConsHdlrs = 0;
1186 outputProblemInfo(&nNonLinearConsHdlrs);
1187
1188 if( scipStatus == SCIP_STATUS_OPTIMAL ||
1189 scipStatus == SCIP_STATUS_INFEASIBLE ) // when sub-MIP is solved at root node, the solution may not be saved
1190 {
1191 solvedAtReInit = true;
1193 // finalDualBound = SCIPgetDualbound(scip);
1194 std::cout << "=== solved at reInit ===" << std::endl;
1195 finalDualBound = instance->convertToInternalValue(SCIPgetDualbound(scip));
1196 writeSolution("Final Solution");
1197 return 1;
1198 }
1199 else
1200 {
1201 /* adding root node cuts, if necessary */
1203 {
1204 if( !addRootNodeCuts() )
1205 {
1206 solvedAtReInit = true;
1208 // finalDualBound = SCIPgetDualbound(scip);
1209 std::cout << "=== solved at reInit ===" << std::endl;
1210 finalDualBound = instance->convertToInternalValue(SCIPgetDualbound(scip));
1211 writeSolution("Final Solution");
1212 return 1;
1213 }
1214 }
1215 }
1216
1217 if( SCIPgetNVars(scip) == 0 ) // all variables were fixed in presolve
1218 {
1219 SCIP_CALL( SCIPsolve(scip) );
1220 solvedAtReInit = true;
1222 // finalDualBound = SCIPgetDualbound(scip);
1223 std::cout << "=== solved at reInit ===" << std::endl;
1224 finalDualBound = instance->convertToInternalValue(SCIPgetDualbound(scip));
1225 writeSolution("Final Solution");
1226 return 1;
1227 }
1228
1229 DEF_SCIP_PARA_COMM( scipParaComm, paraComm );
1230 /** check if feasible solution is found or not. If it was found, then generate paraSolution */
1231 SCIP_SOL *sol = SCIPgetBestSol(scip);
1232 assert(sol);
1233 int nVars = SCIPgetNVars(scip);
1234 SCIP_VAR **vars = SCIPgetVars(scip);
1235 SCIP_Real *vals = new SCIP_Real[nVars];
1236 SCIP_CALL_ABORT( SCIPgetSolVals(scip, sol, nVars, vars, vals) );
1237 assert(solution);
1238 delete solution;
1239 solution = scipParaComm->createScipParaSolution(
1240 0,
1241 SCIPgetSolTransObj(scip, sol), // Only this value may be used
1242 nVars,
1243 vars,
1244 vals
1245 );
1247 {
1248 writeSolution("[Reinitialize]");
1249 }
1250 delete [] vals;
1251 // instance = new PARA_INSTANCE_TYPE(scip, paraParams->getIntParamValue(InstanceTransferMethod));
1252 assert(instance);
1253 delete instance;
1254 instance = scipParaComm->createScipParaInstance(scip, paraParams->getIntParamValue(InstanceTransferMethod));
1255
1256 /* for debugging
1257 std::string subcipprefix("presolved_");
1258 std::string subcipfilename;
1259 std::ostringstream oss;
1260 oss << instance->getProbName();
1261 subcipfilename = oss.str();
1262 subcipfilename += ".lp";
1263 if( SCIPgetStage(scip) >= SCIP_STAGE_TRANSFORMED )
1264 {
1265 SCIP_CALL_ABORT( SCIPwriteTransProblem(scip, subcipfilename.c_str(), "lp", FALSE) );
1266 }
1267 ************************/
1268
1269#ifdef _COMM_MPI_WORLD
1270 if( onlyLinearConss )
1271 {
1272 // restore original parameters
1273 SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/knapsack", originalUpgradeKnapsack));
1274 SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/logicor", originalUpgradeLogicor));
1275 SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/setppc", originalUpgradeSetppc));
1276 SCIP_CALL_ABORT( SCIPsetBoolParam(scip, "constraints/linear/upgrade/varbound", originalUpgradeVarbound));
1277 }
1278#endif
1279
1280 return 0;
1281
1282}
1283
1284bool
1286 BbParaSolution *sol,
1287 bool checksol
1288 )
1289{
1290 ScipParaSolution *tempSol = dynamic_cast< ScipParaSolution * >(sol);
1291
1292 if( tempSol->getNVars() == 0 )
1293 {
1294 delete tempSol;
1295 return false;
1296 }
1297
1298 /* If there is an active Benders' decomposition plugin, the stored solutions are not valid for the original problem.
1299 * This is due to the auxiliary variable not being present in the original problem. Thus, it is not possible to set
1300 * the incumbent solution
1301 */
1302 if( checksol && SCIPgetNActiveBenders(scip) > 0 )
1303 {
1304 delete tempSol;
1305 return false;
1306 }
1307
1308 SCIP_SOL* newsol; /* solution to be created for the original problem */
1309
1310 paraComm->lockApp(); /* lock is necessary, if Solver runs as thread */
1311
1312 /* the solution from the working node should have at least as many variables as we have in the load coordinator scip
1313 * it may be more if inactive variable had to be copied, i.e.,
1314 * SCIPgetNVars(scip) is the number of active variables in the load coordinator scip
1315 * tempSol->getNVars() is the number of original variables in the working node scip (scipParaSolver)
1316 */
1317 SCIP_VAR** vars = 0;
1318 ScipParaInstance *scipInstance = dynamic_cast<ScipParaInstance *>(instance);
1319 /*
1320 int maxrounds = 0;
1321 SCIP_CALL_ABORT( SCIPgetIntParam(scip, "presolving/maxrounds", &maxrounds));
1322 // if( paraParams->getIntParamValue(InstanceTransferMethod) == 2 // original file read
1323 if( maxrounds == 0 ) // nopreprocessing
1324 {
1325 //assert(SCIPgetNVars(scip) <= tempSol->getNVars());
1326 // create new solution for the original problem
1327 SCIP_CALL_ABORT( SCIPcreateOrigSol(scip, &newsol, 0) );
1328 vars = SCIPgetOrigVars(scip);
1329 }
1330 else
1331 {
1332 */
1333 if( checksol && SCIPgetNVars(scip) > tempSol->getNVars() )
1334 {
1335 std::cout << "*** You should check the solution! ***" << std::endl;
1336 std::cout << "checksol = " << checksol << std::endl;
1337 std::cout << "SCIPgetNVars(scip) = " << SCIPgetNVars(scip) << ", " << tempSol->getNVars() << std::endl;
1338 delete tempSol;
1339 return false;
1340 }
1341 assert(SCIPgetNVars(scip) <= tempSol->getNVars());
1342 SCIP_CALL_ABORT( SCIPcreateSol(scip, &newsol, 0) );
1343 vars = SCIPgetVars(scip);
1344 // }
1345
1346 int i;
1347 if( scipInstance->isOriginalIndeciesMap() )
1348 {
1349 int n = SCIPgetNVars(scip);
1350 SCIP_Real *orgSolValues = new SCIP_Real[tempSol->getNVars()];
1351 scipInstance->getSolValuesForOriginalProblem(tempSol, orgSolValues);
1352 // for( i = 0; i < n; i++ )
1353 // assert(SCIPgetNVars(scip) == tempSol->getNVars());
1354 for( i = 0; i < n; i++ )
1355 // for( i = 0; i < scipInstance->getVarIndexRange(); i++ )
1356 {
1357 SCIP_CALL_ABORT( SCIPsetSolVal(scip, newsol, vars[i], orgSolValues[i]) );
1358 // SCIP_CALL_ABORT( SCIPsetSolVal(scip, newsol, vars[tempSol->indexAmongSolvers(i)], orgSolValues[i]) );
1359 // int probindex = scipInstance->getOrigProbIndex(tempSol->indexAmongSolvers(i));
1360 // int probindex = scipInstance->getOrigProbIndex(tempSol->indexAmongSolvers(i));
1361 // int probindex = scipInstance->getOrigProbIndex(tempSol->indexAmongSolvers(i));
1362 /* skip inactive variable */
1363 // if( probindex < 0 ) continue;
1364 // assert(i == probindex); /* this is just a temporory assert, maybe this holds... */
1365 // SCIP_CALL_ABORT( SCIPsetSolVal(scip, newsol, vars[probindex], orgSolValues[i]) );
1366 // SCIP_CALL_ABORT( SCIPsetSolVal(scip, newsol, vars[i], orgSolValues[i]) );
1367 }
1368 delete [] orgSolValues;
1369 }
1370 else
1371 {
1372 // assert( SCIPgetNVars(scip) == tempSol->getNVars() );
1373 assert( SCIPgetNVars(scip) <= tempSol->getNVars() );
1374
1375 // for( i = 0; i < tempSol->getNVars(); i++ )
1376 // {
1377 // if( EPSGT(tempSol->getValues()[i],0.0, MINEPSILON) )
1378 // {
1379 // std::cout << "inex[" << i << "] = " << tempSol->indexAmongSolvers(i) << " = " << tempSol->getValues()[i] << std::endl;
1380 // }
1381 // }
1382
1383 for( i = 0; i < tempSol->getNVars(); i++ )
1384 {
1385 /* if index is larger-equal than number of active vars, then it's probably an inactive variable which had to be copied via SCIPcopy
1386 * so we just ignore its value
1387 */
1388 // if( tempSol->indexAmongSolvers(i) >= SCIPgetNVars(scip) ) continue;
1389 // if( tempSol->indexAmongSolvers(i) > ( tempSol->getNVars() - 1 ) ) break;
1390 // if( scipInstance->isOriginalIndeciesMap() )
1391 // {
1392 // int probindex = scipInstance->getOrigProbIndex(tempSol->indexAmongSolvers(i));
1393 // SCIP_CALL_ABORT( SCIPsetSolVal(scip, newsol, vars[probindex], tempSol->getValues()[i]) );
1394 // }
1395 // else
1396 // {
1397 // SCIP_CALL_ABORT( SCIPsetSolVal(scip, newsol, vars[tempSol->indexAmongSolvers(i)], tempSol->getValues()[i]) );
1398 if ( tempSol->indexAmongSolvers(i) >= 0 )
1399 {
1400 SCIP_CALL_ABORT( SCIPsetSolVal(scip, newsol, vars[tempSol->indexAmongSolvers(i)], tempSol->getValues()[i]) );
1401 // SCIP_CALL_ABORT( SCIPsetSolVal(scip, newsol, vars[i], tempSol->getValues()[i]) );
1402 // }
1403 }
1404 /*
1405 if( scipInstance->isOriginalIndeciesMap() )
1406 {
1407 if( scipInstance->getOrigProbIndex(tempSol->indexAmongSolvers(i)) >= 0 && scipInstance->getOrigProbIndex(tempSol->indexAmongSolvers(i)) < SCIPgetNVars(scip) )
1408 {
1409 SCIP_CALL_ABORT( SCIPsetSolVal(scip, newsol, vars[scipInstance->getOrigProbIndex(tempSol->indexAmongSolvers(i))], tempSol->getValues()[i]) );
1410 }
1411 }
1412 else
1413 {
1414 SCIP_CALL_ABORT( SCIPsetSolVal(scip, newsol, vars[tempSol->indexAmongSolvers(i)], tempSol->getValues()[i]) );
1415 }
1416 */
1417 }
1418 // if( i != tempSol->getNVars() )
1419 // {
1420 // /** the given solution should be generated in original space,
1421 // * therefore the solution values cannot use for ParaSCIP
1422 // */
1423 // SCIP_CALL_ABORT( SCIPfreeSol(scip, &newsol) );
1424 // delete tempSol;
1425 // std::cout << "solution size mismatch! Call Yuji!" << std::endl;
1426 // return false;
1427 // }
1428 }
1429
1430 SCIP_Bool success;
1431 // checksol = true;
1432
1433 bool primalValueUpdated = false;
1434
1436 {
1437 if( checksol ) // checksol == true only when this routine is called to add solution from checkpoint file.
1438 // therefore, no need to lock.
1439 {
1440#if (SCIP_VERSION < 321 || ( SCIP_VERSION == 321 && SCIP_SUBVERSION < 2) )
1441 SCIP_CALL_ABORT( SCIPtrySolFree(scip, &newsol, FALSE, TRUE, TRUE, TRUE, &success) );
1442#else
1443 SCIP_CALL_ABORT( SCIPtrySolFree(scip, &newsol, FALSE, TRUE, TRUE, TRUE, TRUE, &success) );
1444#endif
1445 }
1446 else
1447 {
1448 if( SCIPisTransformed(scip) && SCIPgetNSols(scip) > 0 )
1449 {
1450 double prevValue = SCIPgetPrimalbound(scip);
1451 SCIP_CALL_ABORT( SCIPaddSolFree(scip, &newsol, &success) );
1452 // if( EPSLT( SCIPgetPrimalbound(scip), prevValue, getEpsilon() ) )
1453 if( !EPSEQ( SCIPgetPrimalbound(scip), prevValue, getEpsilon() ) ) // I found increase case of this
1454 {
1455 primalValueUpdated = true;
1456 }
1457 }
1458 else
1459 {
1460 SCIP_CALL_ABORT( SCIPaddSolFree(scip, &newsol, &success) );
1461 primalValueUpdated = true;
1462 }
1463 // SCIP_CALL_ABORT( SCIPaddSolFree(scip, &newsol, &success) );
1464 // primalValueUpdated = true;
1465 }
1466
1467 // std::cout << "** 2 ** success = " << success << std::endl;
1468
1470
1471 if( success && primalValueUpdated )
1472 {
1473 if( solution )
1474 {
1475 delete solution;
1476 }
1477 solution = tempSol;
1479 {
1480 writeSolution("");
1481 }
1482 else
1483 {
1484 writeSolution("Updated");
1485 }
1486 /// relax tolerance, since very small difference raised the following assertion
1487 // if( !EPSEQ( SCIPgetUpperbound(scip), solution->getObjectiveFunctionValue(), (SCIPfeastol(scip) )*100.0) )
1488 if( !EPSEQ( SCIPgetUpperbound(scip), solution->getObjectiveFunctionValue(), SCIPfeastol(scip) ) )
1489 {
1490 std::cout << "*** A new solution generated in a Solver does not match with the upperbound in LC ***" << std::endl;
1491 std::cout << "SCIPgetUpperbound(scip) = " << SCIPgetUpperbound(scip) << std::endl;
1492 std::cout << "solution->getObjectiveFunctionValue() = " << solution->getObjectiveFunctionValue() << std::endl;
1493 std::cout << "Difference = " << (SCIPgetUpperbound(scip) - solution->getObjectiveFunctionValue())
1494 << ", SCIPfeastol(scip) = " << SCIPfeastol(scip) << std::endl;
1495 }
1496 return true;
1497 }
1498 else
1499 {
1500 if( checksol )
1501 {
1502 SCIP_CALL_ABORT( SCIPcreateOrigSol(scip, &newsol, 0) );
1503 vars = SCIPgetOrigVars(scip);
1504 if( scipInstance->isOriginalIndeciesMap() )
1505 {
1506 for( i = 0; i < tempSol->getNVars(); i++ )
1507 {
1508 int probindex = scipInstance->getOrigProbIndex(tempSol->indexAmongSolvers(i));
1509
1510 /* skip inactive variable */
1511 if( probindex < 0 ) continue;
1512
1513 // assert(i == probindex); /* this is just a temporory assert, maybe this holds... */
1514
1515 SCIP_CALL_ABORT( SCIPsetSolVal(scip, newsol, vars[probindex], tempSol->getValues()[i]) );
1516 }
1517 }
1518 else
1519 {
1520 for( i = 0; i < tempSol->getNVars(); i++ )
1521 {
1522 // SCIP_CALL_ABORT( SCIPsetSolVal(scip, newsol, vars[tempSol->indexAmongSolvers(i)], tempSol->getValues()[i]) );
1523 SCIP_CALL_ABORT( SCIPsetSolVal(scip, newsol, vars[i], tempSol->getValues()[i]) );
1524 }
1525 }
1526
1527 // if( i != tempSol->getNVars() ) /* this should not happen */
1528 // {
1529 // /** the given solution should be generated in original space,
1530 // * therefore the solution values cannot use for ParaSCIP
1531 // */
1532 // SCIP_CALL_ABORT( SCIPfreeSol(scip, &newsol) );
1533 // delete tempSol;
1534 // std::cout << "solution size mismatch! Call Yuji!" << std::endl;
1535 // return false;
1536 //}
1537#if (SCIP_VERSION < 321 || ( SCIP_VERSION == 321 && SCIP_SUBVERSION < 2) )
1538 SCIP_CALL_ABORT( SCIPtrySolFree(scip, &newsol, FALSE, TRUE, TRUE, TRUE, &success) );
1539#else
1540 SCIP_CALL_ABORT( SCIPtrySolFree(scip, &newsol, FALSE, TRUE, TRUE, TRUE, TRUE, &success) );
1541#endif
1542 // std::cout << "** 3 ** success = " << success << std::endl;
1543 if( success )
1544 {
1545 if( solution )
1546 {
1547 delete solution;
1548 }
1549 solution = tempSol;
1551 {
1552 writeSolution("");
1553 }
1554 else
1555 {
1556 writeSolution("Updated");
1557 }
1558 assert( EPSEQ( SCIPgetUpperbound(scip), solution->getObjectiveFunctionValue(), SCIPfeastol(scip) ) );
1559 return true;
1560 }
1561 }
1562 delete tempSol;
1563 return false;
1564 }
1565 }
1566 else
1567 {
1568 //
1569 // The following routine is not tested yet.
1570 //
1571 // std::cout << "Print sol. orig" << std::endl;
1572 // SCIP_CALL_ABORT( SCIPprintSol(scip, newsol, NULL, FALSE) );
1573 // std::cout << "Print sol. trans" << std::endl;
1574 // SCIP_CALL_ABORT( SCIPprintTransSol(scip, newsol, NULL, FALSE) );
1575 // int nVars = SCIPgetNVars(scip);
1576 // for( int i = 0; i < nVars; i ++)
1577 // {
1578 // std::cout << i << ": " << SCIPvarGetName(vars[tempSol->indexAmongSolvers(i)]) << std::endl;
1579 // std::cout << i << ": " << SCIPvarGetName(vars[i]) << std::endl;
1580 // }
1581
1582#if (SCIP_VERSION < 321 || ( SCIP_VERSION == 321 && SCIP_SUBVERSION < 2) )
1583 SCIP_CALL_ABORT( SCIPtrySolFree(scip, &newsol, FALSE, TRUE, TRUE, TRUE, &success) );
1584#else
1585 SCIP_CALL_ABORT( SCIPtrySolFree(scip, &newsol, FALSE, TRUE, TRUE, TRUE, TRUE, &success) );
1586#endif
1587 assert(success);
1588 if( success )
1589 {
1590 // SCIP_CALL_ABORT( SCIPfreeSol(scip, &newsol) );
1591 if( solution )
1592 {
1593 delete solution;
1594 }
1595 solution = tempSol;
1597 {
1598 writeSolution("");
1599 }
1600 else
1601 {
1602 writeSolution("Updated");
1603 }
1605 assert( EPSEQ( SCIPgetUpperbound(scip), solution->getObjectiveFunctionValue(), SCIPfeastol(scip) ) );
1606 return true;
1607 }
1608 else
1609 {
1610 SCIP_VAR* var = 0;
1611 for( i = 0; i < tempSol->getNVars(); i++ )
1612 {
1613 int probindex = scipInstance->getOrigProbIndex(tempSol->indexAmongSolvers(i));
1614
1615 /* skip inactive variable */
1616 if( probindex < 0 ) continue;
1617
1618 assert(i == probindex); /* this is just a temporory assert, maybe this holds... */
1619
1620 var = vars[probindex];
1621
1622 if( SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS ) continue;
1623 if( tempSol->getValues()[i] > 0.0 )
1624 {
1625 tempSol->setValue(i, SCIPfeasFloor(scip,tempSol->getValues()[i]));
1626 }
1627 else
1628 {
1629 tempSol->setValue(i, SCIPfeasCeil(scip, tempSol->getValues()[i]) );
1630 }
1631 SCIP_CALL_ABORT( SCIPsetSolVal(scip, newsol, var, tempSol->getValues()[i]) );
1632 }
1633
1634#if (SCIP_VERSION < 321 || ( SCIP_VERSION == 321 && SCIP_SUBVERSION < 2) )
1635 SCIP_CALL_ABORT( SCIPtrySol(scip, newsol, FALSE, TRUE, TRUE, TRUE, &success) );
1636#else
1637 SCIP_CALL_ABORT( SCIPtrySol(scip, newsol, FALSE, TRUE, TRUE, TRUE, TRUE, &success) );
1638#endif
1639 if( success )
1640 {
1641 tempSol->setObjectiveFuntionValue(convertToInternalValue(SCIPsolGetOrigObj(newsol)));
1642 SCIP_CALL_ABORT( SCIPfreeSol(scip, &newsol) );
1643 if( solution )
1644 {
1645 delete solution;
1646 }
1647 solution = tempSol;
1649 {
1650 writeSolution("");
1651 }
1652 else
1653 {
1654 writeSolution("Updated");
1655 }
1657 assert( EPSEQ( SCIPgetUpperbound(scip), solution->getObjectiveFunctionValue(), SCIPfeastol(scip) ) );
1658 return true;
1659 }
1660 else
1661 {
1662 fprintf(solutionFile, "*** Rejected Solution ***\n");
1663 SCIP_CALL_ABORT(SCIPprintSol(scip, newsol, solutionFile, FALSE));
1664 if( transSolutionFile )
1665 {
1666 fprintf(transSolutionFile, "*** Rejected Solution ***\n");
1667 SCIP_CALL_ABORT(SCIPprintTransSol(scip, newsol, transSolutionFile, FALSE));
1668 }
1669
1670 if( SCIPisFeasLT( scip, convertToExternalValue(tempSol->getObjectiveFunctionValue()), SCIPgetPrimalbound(scip) ) )
1671 {
1672 // paraComm->lockApp();
1673 std::cout << "Current scip primal value = " << SCIPgetPrimalbound(scip) << std::endl;
1674 std::cout << "Objective value = " << convertToExternalValue(tempSol->getObjectiveFunctionValue()) << std::endl;
1675 std::cout << "Initiator did not accept solution!" << std::endl;
1676 // paraComm->unlockApp();
1677 }
1678 SCIP_CALL_ABORT( SCIPfreeSol(scip, &newsol) );
1679 delete tempSol;
1681 return false;
1682 }
1683 }
1684 }
1685}
1686
1687void
1689 )
1690{
1694 int warmStarted = 0;
1695 if( isWarmStarted() )
1696 {
1697 warmStarted = 1;
1698 }
1699 paraComm->bcast(&warmStarted,1, ParaINT, 0);
1700 double incumbentValue;
1701 if( solution )
1702 {
1703 incumbentValue = solution->getObjectiveFunctionValue();
1704 }
1705 else
1706 {
1707 SCIP_SOL *sol = SCIPgetBestSol(scip);
1708 if ( sol )
1709 {
1710 int nVars = SCIPgetNVars(scip);
1711 SCIP_VAR **vars = SCIPgetVars(scip);
1712 SCIP_Real *vals = new SCIP_Real[nVars];
1713 SCIP_CALL_ABORT( SCIPgetSolVals(scip, sol, nVars, vars, vals) );
1714 DEF_SCIP_PARA_COMM( scipParaComm, paraComm);
1715 solution = scipParaComm->createScipParaSolution(
1716 0,
1717 SCIPgetSolTransObj(scip,sol),
1718 nVars,
1719 vars,
1720 vals
1721 );
1722 delete [] vals;
1723 incumbentValue = solution->getObjectiveFunctionValue();
1724 }
1725 else
1726 {
1727 incumbentValue = DBL_MAX;
1728 }
1729 }
1730 paraComm->bcast(&incumbentValue, 1, ParaDOUBLE, 0);
1731
1733 {
1734 int solutionExists = 0;
1735 paraComm->bcast(&solutionExists, 1, ParaINT, 0);
1736 }
1737 else
1738 {
1739 /** if a feasible solution exists, broadcast the solution */
1741 {
1742 /* bcast solution if it is necessary */
1743 int solutionExists = 0;
1744 if( solution )
1745 {
1746 solutionExists = 1;
1747 paraComm->bcast(&solutionExists, 1, ParaINT, 0);
1748 solution->bcast(paraComm, 0);
1749 }
1750 else
1751 {
1752 paraComm->bcast(&solutionExists, 1, ParaINT, 0);
1753 }
1754 }
1755 }
1756
1757 // allocate here, since the number of variables is fixed when the instance data are sent
1761 {
1762 assert( instance->getNVars() > 0 );
1763 assert( instance->getVarIndexRange() > 0 );
1764 // IndexRange must be bigger than NVars
1765 tightenedVarLbs = new double[instance->getVarIndexRange()];
1766 tightenedVarUbs = new double[instance->getVarIndexRange()];
1767 for( int i = 0; i < instance->getVarIndexRange(); i++ )
1768 {
1769 tightenedVarLbs[i] = -DBL_MAX;
1770 tightenedVarUbs[i] = DBL_MAX;
1771 }
1772 }
1773
1774}
1775
1776/** get gap */
1777double
1779 double dualBoundValue
1780 )
1781{
1782 if( !solution ) return SCIPinfinity(scip);
1784 SCIP_Real dualbound = instance->convertToExternalValue(dualBoundValue);
1785 return REALABS((primalbound - dualbound));
1786}
1787
1788/** get gap */
1789double
1791 double dualBoundValue
1792 )
1793{
1794 if( !solution ) return SCIPinfinity(scip);
1796 SCIP_Real dualbound = instance->convertToExternalValue(dualBoundValue);
1797
1798 if( SCIPisEQ(scip, primalbound, dualbound) )
1799 return 0.0;
1800 else if( SCIPisZero(scip, dualbound)
1801 || SCIPisZero(scip, primalbound)
1802 || SCIPisInfinity(scip, REALABS(primalbound))
1803 || SCIPisInfinity(scip, REALABS(dualbound))
1804 || primalbound * dualbound < 0.0 )
1805 return SCIPinfinity(scip);
1806 else
1807 return REALABS((primalbound - dualbound)/MIN(REALABS(dualbound),REALABS(primalbound)));
1808}
1809
1810/** get epsilon */
1811double
1813 )
1814{
1815 SCIP_Real epsilon;
1816 SCIP_CALL_ABORT( SCIPgetRealParam(scip, "numerics/epsilon", &epsilon));
1817 return epsilon;
1818}
1819
1820void
1822 const std::string& message
1823 )
1824{
1825 if( qsol ) return;
1826 std::ostringstream osold;
1827 if( message == "Final Solution" )
1828 {
1829#ifndef SCIP_THREADSAFE_MESSAGEHDLRS
1831 {
1832 SCIPmessageSetDefaultHandler(); // If no message handler is set, it cannot write solution,too.
1833 }
1834#endif
1835 if( solvedAtInit || (!paraParams->getBoolParamValue(Quiet)) ) // when solutionFileName is specified, it is always updated
1836 {
1837 fprintf(solutionFile, "[ Final Solution ]\n");
1838 }
1839 if( transSolutionFile )
1840 {
1841 fprintf(transSolutionFile, "[ Final Solution ]\n");
1842 }
1843 }
1844 else if ( message == "Updated" )
1845 {
1847 fclose(solutionFile);
1848 std::ostringstream os;
1849 if( solutionFileName )
1850 {
1851 osold << solutionFileName << ".old";
1852 os << solutionFileName;
1853 }
1854 else
1855 {
1857 osold << instance->getProbName() << ".sol.old";
1859 os << instance->getProbName() << ".sol";
1860 }
1861 // std::cout << "File Name: " << os.str().c_str() << " to " << osold.str().c_str() << std::endl;
1862 if( rename(os.str().c_str(), osold.str().c_str()) )
1863 {
1864 std::cerr << "Rename falied from " << "File Name: " << os.str().c_str() << " to " << osold.str().c_str() << std::endl;
1865 exit(1);
1866 }
1867 solutionFile = fopen(os.str().c_str(), "a"); // if solution file exists, append
1868 fprintf(solutionFile, "[ Final Solution ]\n");
1869 }
1870 else
1871 {
1872 fprintf(solutionFile,"%s\n",message.c_str());
1873 if( transSolutionFile )
1874 {
1875 fprintf(transSolutionFile,"%s\n", message.c_str());
1876 }
1877 }
1878 SCIP_SOL* sol = SCIPgetBestSol(scip);
1879 if( sol )
1880 {
1881 if( solvedAtInit || (!(message == "Final Solution")) || (!paraParams->getBoolParamValue(Quiet)) ) // when solutionFileName is specified, it is always updated
1882 {
1883 SCIP_CALL_ABORT( SCIPprintBestSol( scip, solutionFile, FALSE) );
1884 }
1885 if( transSolutionFile )
1886 {
1887 if( SCIPsolGetOrigin(sol) != SCIP_SOLORIGIN_ORIGINAL )
1888 {
1889 ScipParaInstance *scipInstance = dynamic_cast<ScipParaInstance *>(instance);
1890 if( scipInstance->isOriginalIndeciesMap() )
1891 {
1892 SCIP_CALL_ABORT( SCIPprintBestSol( scipInstance->getParaInstanceScip(), transSolutionFile, FALSE) );
1893 }
1894 else
1895 {
1896 SCIP_CALL_ABORT( SCIPprintBestTransSol( scip, transSolutionFile, FALSE) );
1897 }
1898 }
1899 else
1900 {
1901 fprintf(transSolutionFile, "best solution is defined in original space - cannot print it as transformed solution\n");
1902 }
1903 }
1904 /*
1905 if( userPlugins )
1906 {
1907 userPlugins->writeUserSolution(scip);
1908 }
1909 */
1910 }
1911 else
1912 {
1913 fprintf(solutionFile, "No Solution\n");
1914 if( transSolutionFile )
1915 {
1916 fprintf(transSolutionFile, "No Solution\n");
1917 }
1918 }
1919 if ( message == "Updated" )
1920 {
1921 remove(osold.str().c_str());
1922 }
1923}
1924
1925void
1927 const std::string& filename
1928 )
1929{
1930 FILE *file = fopen(filename.c_str(),"a");
1931 if( !file )
1932 {
1933 std::cout << "file : " << filename << "cannot open." << std::endl;
1934 exit(1);
1935 }
1936 ScipParaInstance *scipInstance = dynamic_cast<ScipParaInstance *>(instance);
1937 if( scipInstance->isOriginalIndeciesMap() )
1938 {
1939 SCIP_CALL_ABORT( SCIPprintOrigProblem(scipInstance->getParaInstanceScip(), file, "lp", FALSE) );
1940 }
1941 else
1942 {
1943 SCIP_CALL_ABORT( SCIPprintTransProblem(scip, file, "lp", FALSE) );
1944 }
1945}
1946
1947/** write solver runtime parameters */
1948void
1950 std::ostream *os
1951 )
1952{
1953 if( scipDiffParamSetRoot->nDiffParams() == 0 )
1954 {
1955 *os << "[ SCIP parameters for root Solver are all default values ]" << std::endl;
1956 }
1957 else
1958 {
1959 *os << "[ Not default SCIP parameters for root Solver are as follows ]" << std::endl;
1961 }
1962
1963 if( scipDiffParamSet->nDiffParams() == 0 )
1964 {
1965 *os << "[ SCIP parameters for NOT root Solvers are all default values ]" << std::endl;
1966 }
1967 else
1968 {
1969 *os << "[ Not default SCIP parameters for NOT root Solvers are as follows ]" << std::endl;
1970 *os << scipDiffParamSet->toString();
1971 }
1972
1973}
1974
1975#ifdef UG_WITH_ZLIB
1976/** write checkpoint solution */
1977void
1979 const std::string& filename
1980 )
1981{
1982 gzstream::ogzstream checkpointSolutionStream;
1983 checkpointSolutionStream.open(filename.c_str(), std::ios::out | std::ios::binary);
1984 if( !checkpointSolutionStream )
1985 {
1986 std::cout << "Checkpoint file for solution cannot open. file name = " << filename << std::endl;
1987 exit(1);
1988 }
1989 if( solution )
1990 solution->write(checkpointSolutionStream);
1991 checkpointSolutionStream.close(); /** empty solution file is necessary,
1992 * because it is removed next at the next checkpoint */
1993}
1994
1995/** read solution from checkpoint file */
1996double
1998 char *afterCheckpointingSolutionFileName
1999 )
2000{
2001 char tempSolutionFileName[SCIP_MAXSTRLEN];
2002 (void) SCIPsnprintf(tempSolutionFileName, SCIP_MAXSTRLEN, "%s_solution.gz", prefixWarm);
2003 gzstream::igzstream checkpointSolutionStream;
2004 checkpointSolutionStream.open(tempSolutionFileName, std::ios::in | std::ios::binary);
2005 if( !checkpointSolutionStream )
2006 {
2007 std::cout << "checkpoint solution file cannot open: file name = " << tempSolutionFileName << std::endl;
2008 exit(1);
2009 }
2010 if( solution )
2011 {
2013 if( sol->read(paraComm, checkpointSolutionStream) )
2014 {
2016 {
2017 delete solution;
2018 solution = sol;
2019 }
2020 }
2021 else
2022 {
2023 delete sol;
2024 }
2025 }
2026 else
2027 {
2029 if( !solution->read(paraComm, checkpointSolutionStream) )
2030 {
2031 delete solution;
2032 solution = 0;
2033 checkpointSolutionStream.close();
2034 }
2035 }
2036 checkpointSolutionStream.close();
2037 if( solution )
2038 {
2039 if( !tryToSetIncumbentSolution(dynamic_cast<BbParaSolution *>(solution->clone(paraComm)), true) )
2040 {
2041 std::cout << "***** Given solution is wrong! ***************************" << std::endl;
2042 std::cout << "***** If the solution was given from checkpoint file, ***" << std::endl;
2043 std::cout << "***** it might be generated in original problem space **" << std::endl;
2044 std::cout << "***** Only primal value is used. *************************" << std::endl;
2045 std::cout << "***** You should better to use -isol option. ************" << std::endl;
2046 std::cout << "***** Or, better to use no distribute solution option. ***" << std::endl;
2047 }
2048 }
2049
2050 /** check if after checkpoing solution file exists or not */
2051 checkpointSolutionStream.open(afterCheckpointingSolutionFileName, std::ios::in | std::ios::binary);
2052 if( checkpointSolutionStream )
2053 {
2054 /** set up from after checkpointing solution file */
2056 if( sol->read(paraComm, checkpointSolutionStream) )
2057 {
2058 if( !solution )
2059 {
2060 solution = sol;
2061 if( tryToSetIncumbentSolution(dynamic_cast<BbParaSolution *>(solution->clone(paraComm)), true) )
2062 {
2063 std::cout << "***** After checkpoint solution is RIGHT! ****************" << std::endl;
2064 }
2065 }
2066 else
2067 {
2069 {
2070 delete solution;
2071 solution = sol;
2072 if( tryToSetIncumbentSolution(dynamic_cast<BbParaSolution *>(solution->clone(paraComm)), true) )
2073 {
2074 std::cout << "***** After checkpoint solution is RIGHT! ****************" << std::endl;
2075 }
2076 }
2077 }
2078 }
2079 else
2080 {
2081 delete sol;
2082 }
2083 checkpointSolutionStream.close();
2084 }
2085
2086 if( solution )
2087 {
2089 }
2090 else
2091 {
2092 return DBL_MAX;
2093 }
2094}
2095#endif
2096
2097/** generate racing ramp-up parameter sets */
2098void
2100 int nParamSets,
2101 ParaRacingRampUpParamSet **racingRampUpParamSets
2102 )
2103{
2104 ScipDiffParamSet *racingScipDiffParamSet = 0; // assume all default
2105
2106 if ( std::string(paraParams->getStringParamValue(UG::RacingParamsDirPath)) != std::string("") )
2107 {
2108 DEF_SCIP_PARA_COMM( scipParaComm, paraComm);
2109
2110 for( int n = 1; n < nParamSets + 1 ; n++ )
2111 {
2112 std::ostringstream oss;
2114 << "/"
2115 << std::setfill('0') << std::setw(5)
2117 << ".set";
2118
2119 SCIP_CALL_ABORT( SCIPresetParams(scip) );
2120 if( SCIPreadParams(scip, oss.str().c_str()) != SCIP_OKAY )
2121 {
2122 std::cout << "Cannot read racing parameter file = " << oss.str().c_str() << std::endl;
2123 exit(1);
2124 }
2125
2126 racingScipDiffParamSet = scipParaComm->createScipDiffParamSet(scip);
2127 racingRampUpParamSets[n-1] = scipParaComm->createScipParaRacingRampUpParamSet(
2131 n,
2132 ( (n - 1) % paraParams->getIntParamValue(UG::NMaxRacingBaseParameters)), // the number of variable permutation seed; start from default: 0
2133 0,
2134 racingScipDiffParamSet
2135 );
2136 SCIP_CALL_ABORT( SCIPresetParams(scip) );
2137 }
2138 }
2139 else
2140 {
2141 if( racingSettingsName )
2142 {
2143 SCIP_CALL_ABORT( SCIPresetParams(scip) );
2144 SCIP_CALL_ABORT( SCIPreadParams(scip, racingSettingsName) );
2145 // DEF_SCIP_PARA_COMM( scipParaComm, paraComm );
2146 // racingScipDiffParamSet = scipParaComm->createScipDiffParamSet(scip);
2147 // SCIP_CALL_ABORT( SCIPresetParams(scip) );
2148 }
2149 /*
2150 else
2151 {
2152 racingScipDiffParamSet = 0; // all default
2153 }*/
2154
2155
2156 int n = 0; /**< keep the number of generated params */
2157#if (SCIP_VERSION < 321 || ( SCIP_VERSION == 321 && SCIP_SUBVERSION < 2) )
2158 int npm = -1; /**< keep the number of variable permutation seed; start from default: -1 */
2159#else
2160 int npm = 0; /**< keep the number of variable permutation seed; start from default: 0 */
2161#endif
2162 int nbo = 0; /**< keep the number of branching order seed */
2163
2164 DEF_SCIP_PARA_COMM( scipParaComm, paraComm);
2165
2166 for(;;)
2167 {
2168 for( int i = 0; i < paraParams->getIntParamValue(MaxNRacingParamSetSeed); i++ )
2169 {
2170#if (SCIP_VERSION < 321 || ( SCIP_VERSION == 321 && SCIP_SUBVERSION < 2) )
2171 if( npm > ( paraParams->getIntParamValue(TryNVariablegOrderInRacing) - 1 ) ) npm = -1;
2172#else
2173 if( npm > ( paraParams->getIntParamValue(TryNVariablegOrderInRacing) - 1 ) ) npm = 0;
2174#endif
2176 if( racingSettingsName )
2177 {
2178 racingScipDiffParamSet = scipParaComm->createScipDiffParamSet(scip);
2179 }
2180 racingRampUpParamSets[n] = scipParaComm->createScipParaRacingRampUpParamSet(
2184 i,
2185 npm,
2186 nbo,
2187 racingScipDiffParamSet
2188 );
2189 npm++;
2190 nbo++;
2191 n++;
2192 if( n >= nParamSets ) return;
2193 }
2194 }
2195 if( racingSettingsName )
2196 {
2197 SCIP_CALL_ABORT( SCIPresetParams(scip) );
2198 }
2199 }
2200}
2201
2202/** get solving status string */
2203std::string
2205 )
2206{
2207 SCIP_SOL* sol = SCIPgetBestSol(scip);
2208 if( sol )
2209 {
2210 return std::string("solution found exist");
2211 }
2212 else
2213 {
2214 return std::string("no solution");
2215 }
2216}
2217
2218/** print solver version **/
2219void
2221 std::ostream *os /**< output file (or NULL for standard output) */
2222 )
2223{
2224#ifndef SCIP_THREADSAFE_MESSAGEHDLRS
2225 SCIPprintVersion( NULL );
2226#else
2227 SCIPprintVersion( scip, NULL );
2228#endif
2229
2230 SCIPprintExternalCodes(scip, NULL);
2231}
2232
2233/** set initial stat on initiator */
2234void
2236 ParaInitialStat *initialStat
2237 )
2238{
2239 ScipParaInitialStat *scipInitialStat = dynamic_cast<ScipParaInitialStat *>(initialStat);
2240 ScipParaInstance *scipInstance = dynamic_cast<ScipParaInstance *>(instance);
2241 if( scipInstance->isOriginalIndeciesMap() )
2242 {
2243 scipInitialStat->accumulateOn(scipInstance->getParaInstanceScip());;
2244 }
2245 else
2246 {
2247 scipInitialStat->accumulateOn(scip);
2248 }
2249}
2250
2251/** set initial stat on DiffSubproblem */
2252void
2254 int minDepth,
2255 int maxDepth,
2256 BbParaDiffSubproblem *diffSubproblem
2257 )
2258{
2259 ScipParaDiffSubproblem *scipDiffSubproblem = dynamic_cast<ScipParaDiffSubproblem *>(diffSubproblem);
2260 ScipParaInstance *scipInstance = dynamic_cast<ScipParaInstance *>(instance);
2261 if( scipInstance->isOriginalIndeciesMap() )
2262 {
2263 scipDiffSubproblem->addInitialBranchVarStats(minDepth, maxDepth, scipInstance->getParaInstanceScip());
2264 }
2265 else
2266 {
2267 scipDiffSubproblem->addInitialBranchVarStats(minDepth, maxDepth, scip);
2268 }
2269}
2270
2271/** set final solver status */
2272void
2274 FinalSolverState state
2275 )
2276{
2277 finalState = state;
2278}
2279
2280/** set number of nodes solved */
2281void
2283 long long n
2284 )
2285{
2286 nSolved = n;
2287}
2288
2289/** set final dual bound */
2290void
2292 double bound
2293 )
2294{
2295 if( bound > finalDualBound )
2296 {
2297 finalDualBound = bound;
2298 }
2299}
2300
2301/** output solution status */
2302void
2304 std::ostream *os,
2305 double time
2306 )
2307{
2308 if( os == 0 )
2309 {
2310 os = &std::cout;
2311 }
2312
2313 if( finalState != Aborted )
2314 {
2315 *os << "SCIP Status : ";
2316 }
2317
2318 switch ( finalState )
2319 {
2321 *os << "initial nodes were generated" << std::endl;
2322 break;
2323 case Aborted:
2324 *os << std::endl;
2325 break;
2327 *os << "solving was interrupted [hard time limit reached]" << std::endl;
2328 break;
2330 *os << "solving was interrupted [memory limit reached]" << std::endl;
2331 break;
2332 case GivenGapIsReached:
2333 *os << "solving was interrupted [given gap reached]" << std::endl;
2334 break;
2336 *os << "solving was interrupted" << std::endl;
2337 break;
2338 case ProblemWasSolved:
2339 if( SCIPgetNSols(scip) > 0 )
2340 {
2341 *os << "problem is solved" << std::endl;
2342 }
2343 else
2344 {
2345 *os << "problem is solved [infeasible]" << std::endl;
2346 }
2347 break;
2349 *os << "requested subproblems are solved" << std::endl;
2350 break;
2351 default:
2352 THROW_LOGICAL_ERROR1("invalid final state");
2353 }
2354
2355 *os << "Total Time : " << time << std::endl;
2356 *os << " solving : " << time << std::endl;
2357 *os << " presolving : " << SCIPgetPresolvingTime(scip) << " (included in solving)" << std::endl;
2358 *os << "B&B Tree :" << std::endl;
2359 *os << " nodes (total) : " << nSolved << std::endl;
2360 *os << "Solution :" << std::endl;
2361 *os << " Solutions found : " << SCIPgetNSols(scip) << std::endl;
2362 SCIP_Real primalbound = SCIPinfinity(scip);
2363 // std::cout << "** Nsols = " << SCIPgetNSols(scip) << std::endl;
2364 // if( solution )
2365 // {
2366 // std::cout << "*** obj = " << convertToExternalValue(solution->getObjectiveFuntionValue()) << std::endl;
2367 // }
2368 if( SCIPgetNSols(scip) != 0 )
2369 {
2370 primalbound = SCIPgetPrimalbound(scip);
2371 }
2372 else
2373 {
2374 if( solution && solution->getNVars() > 0 )
2375 {
2376 primalbound = solution->getObjectiveFunctionValue(); // This solution should be in original problem space.
2377 // So, do not have to convert to original space.
2378 }
2379 else
2380 {
2381 if( EPSLT( objlimit, DBL_MAX, MINEPSILON ) )
2382 {
2383 primalbound = objlimit;
2384 }
2385 }
2386 }
2387 *os << " Primal Bound : ";
2388 if( SCIPisInfinity(scip, REALABS(primalbound) ) )
2389 {
2390 *os << " -" << std::endl;
2391 }
2392 else
2393 {
2394 (*os).setf(std::ios::showpos);
2395 *os << std::scientific << std::showpoint << std::setprecision(14) << primalbound << std::endl;
2396 (*os).unsetf(std::ios::showpos);
2397 }
2398
2399 finalDualBound = instance->convertToExternalValue(finalDualBound); // converted to original one
2400 SCIP_Real finalGap = 0.0;
2401 if( SCIPisEQ(scip, primalbound, finalDualBound) )
2402 finalGap = 0.0;
2403 else if( SCIPisZero(scip, finalDualBound)
2404 || SCIPisZero(scip, primalbound)
2405 || SCIPisInfinity(scip, REALABS(primalbound))
2406 || SCIPisInfinity(scip, REALABS(finalDualBound))
2407 || primalbound * finalDualBound < 0.0 )
2408 finalGap = SCIPinfinity(scip);
2409 else
2410 finalGap = REALABS((primalbound - finalDualBound)/MIN(REALABS(finalDualBound),REALABS(primalbound)));
2411
2412#if SCIP_VERSION > 302 || ( SCIP_VERSION == 302 && SCIP_SUBVERSION == 1 )
2413 *os << " Dual Bound : ";
2414#else
2415 *os << "Dual Bound : ";
2416#endif
2417 if( SCIPisInfinity(scip, REALABS(finalDualBound) ) )
2418 *os << " -" << std::endl;
2419 else
2420 {
2421 (*os).setf(std::ios::showpos);
2422 *os << std::scientific << std::showpoint << std::setprecision(14)
2423 << finalDualBound << std::endl;
2424 (*os).unsetf(std::ios::showpos);
2425 }
2426 *os << "Gap : ";
2427 if( SCIPgetNSols(scip) == 0 )
2428 {
2429 *os << " -" << std::endl;
2430 }
2431 else if( SCIPisInfinity(scip, finalGap ) )
2432 *os << " infinite" << std::endl;
2433 else
2434 {
2435 *os << std::fixed << std::setprecision(5) << 100.0 * finalGap << " %" << std::endl;
2436 }
2437 if( finalGap > SCIPepsilon(scip) && !SCIPisInfinity(scip, REALABS(primalbound) ) )
2438 {
2439 *os << std::scientific << "* Warning: final gap: " << finalGap << " is greater than SCIPepsilon: " << SCIPepsilon(scip) << std::endl;
2440 }
2441
2442 assert( finalState != ProblemWasSolved ||
2443 ( finalState == ProblemWasSolved && ( SCIPgetNSols(scip) == 0 || ( SCIPgetNSols(scip) != 0 ) ) ) );
2444
2445 if( userPlugins )
2446 {
2448 }
2449}
2450
2451void
2453 int *nNonLinearConsHdlrs
2454 )
2455{
2456 std::cout << "Original Problem :" << std::endl;
2457 std::cout << " Problem name : " << SCIPgetProbName(scip) << std::endl;
2458 std::cout << " Variables : " << SCIPgetNOrigVars(scip)
2459 << " (" << SCIPgetNOrigBinVars(scip) << " binary, "
2460 << SCIPgetNOrigIntVars(scip) << " integer, "
2461 << SCIPgetNOrigImplVars(scip) << " implicit integer, "
2462 << SCIPgetNOrigContVars(scip) << " continuous)" << std::endl;
2463 std::cout << " Constraints : " << SCIPgetNOrigConss(scip) << std::endl;
2464 std::cout << " Objective sense : " << (SCIPgetObjsense(scip) == SCIP_OBJSENSE_MINIMIZE ? "minimize" : "maximize") << std::endl;
2465 std::cout << "Presolved Problem :" << std::endl;
2466 std::cout << " Variables : " << SCIPgetNVars(scip)
2467 << " (" << SCIPgetNBinVars(scip) << " binary, "
2468 << SCIPgetNIntVars(scip) << " integer, "
2469 << SCIPgetNImplVars(scip) << " implicit integer, "
2470 << SCIPgetNContVars(scip) << " continuous)" << std::endl;
2471 std::cout << " Constraints : " << SCIPgetNConss(scip) << std::endl;
2472
2473 std::cout << "Constraints : Number" << std::endl;
2474 for( int i = 0; i < SCIPgetNConshdlrs(scip); ++i )
2475 {
2476 SCIP_CONSHDLR* conshdlr;
2477 int startnactiveconss;
2478 int maxnactiveconss;
2479 conshdlr = SCIPgetConshdlrs(scip)[i];
2480 startnactiveconss = SCIPconshdlrGetStartNActiveConss(conshdlr);
2481 maxnactiveconss = SCIPconshdlrGetMaxNActiveConss(conshdlr);
2482 if( startnactiveconss > 0 )
2483 {
2484 std::cout << " " << std::setw(17) << std::left << SCIPconshdlrGetName(conshdlr) << ": "
2485 << startnactiveconss << ( maxnactiveconss > startnactiveconss ? '+' : ' ') << std::endl;
2486 if ( std::string(SCIPconshdlrGetName(conshdlr)) != std::string("linear") )
2487 {
2488 *nNonLinearConsHdlrs += startnactiveconss;
2489 }
2490 }
2491 }
2492}
2493
2494bool
2496 )
2497{
2498 for( int i = 0; i < SCIPgetNConss(scip); ++i )
2499 {
2500 SCIP_CONS** conss = SCIPgetConss(scip);
2501 SCIP_CONSHDLR* conshdlr = SCIPconsGetHdlr(conss[i]);
2502 if( std::string(SCIPconshdlrGetName(conshdlr)) != std::string("linear") )
2503 {
2504 return false;
2505 }
2506 }
2507 return true;
2508}
2509
2510void
2512 ScipUserPlugins *inUi
2513 )
2514{
2515 userPlugins = inUi;
2516}
2517
2518#ifdef UG_WITH_UGS
2519/** read ugs incumbent solution **/
2520bool
2521ScipParaInitiator::readUgsIncumbentSolution(
2522 UGS::UgsParaCommMpi *ugsComm,
2523 int source
2524 )
2525{
2526 UGS::UgsUpdateIncumbent *updateIncumbent = new UGS::UgsUpdateIncumbent();
2527 updateIncumbent->receive(ugsComm->getMyComm(), source);
2528
2529 if( ( instance->getOrigObjSense() == SCIP_OBJSENSE_MINIMIZE && (convertToExternalValue(solution->getObjectiveFunctionValue()) - updateIncumbent->getObjective() ) > MINEPSILON ) ||
2530 ( instance->getOrigObjSense() == SCIP_OBJSENSE_MAXIMIZE && ( updateIncumbent->getObjective() - convertToExternalValue(solution->getObjectiveFunctionValue()) ) > MINEPSILON ) )
2531 {
2532 // std::cout << "################### SCIP: going to set the incumbnet !!! ##############" << std::endl;
2533 // std::cout << "################### in SCIP = " << convertToExternalValue(solution->getObjectiveFuntionValue()) << ", from outside = " << updateIncumbent->getObjective() << std::endl;
2534 std::ostringstream s;
2535 s << ugsComm->getSolverName(updateIncumbent->getUpdatedSolverId()) << "-" << updateIncumbent->getSeqNumber() << ".sol";
2536 SCIP_SOL *origSol;
2537 SCIP_CALL_ABORT( SCIPcreateOrigSol(scip, &origSol, NULL) );
2538 SCIP_Bool partial = FALSE;
2539 SCIP_Bool error = FALSE;
2540 SCIP_CALL_ABORT( SCIPreadSolFile(scip, s.str().c_str(), origSol, FALSE, &partial, &error ) );
2541
2542 // std::cout << "################## partial = " << partial << ", error = " << error << " ##############" << std::endl;
2543
2544 DEF_SCIP_PARA_COMM( scipParaComm, paraComm);
2545
2546 if( solution ) delete solution;
2547 if( (!partial) && (!error) )
2548 {
2549 SCIP_Bool stored = FALSE;
2550 SCIP_CALL_ABORT( SCIPtrySol(scip, origSol, FALSE, TRUE, TRUE, TRUE, FALSE, &stored) );
2551
2552 // std::cout << "################## stored = " << stored << " ##############" << std::endl;
2553
2554 if( stored )
2555 {
2556 SCIP_SOL *sol = SCIPgetBestSol(scip);
2557 int nVars = SCIPgetNVars(scip);
2558 SCIP_VAR **vars = SCIPgetVars(scip);
2559 SCIP_Real *vals = new SCIP_Real[nVars];
2560 SCIP_CALL_ABORT( SCIPgetSolVals(scip, sol, nVars, vars, vals) );
2561 solution = scipParaComm->createScipParaSolution(
2562 0,
2563 SCIPgetSolTransObj(scip, sol), // Only this value may be used
2564 nVars,
2565 vars,
2566 vals
2567 );
2568 delete [] vals;
2569 }
2570 else
2571 {
2572 solution = scipParaComm->createScipParaSolution(
2573 0,
2574 convertToInternalValue(updateIncumbent->getObjective()), // Only this value may be used
2575 0,
2576 (SCIP_VAR **)0,
2577 0
2578 );
2579 }
2580 }
2581 else
2582 {
2583 solution = scipParaComm->createScipParaSolution(
2584 0,
2585 convertToInternalValue(updateIncumbent->getObjective()), // Only this value may be used
2586 0,
2587 (SCIP_VAR **)0,
2588 0
2589 );
2590 }
2591
2592 SCIP_CALL_ABORT( SCIPfreeSol(scip, &origSol) );
2593
2594 delete updateIncumbent;
2595
2596 return true;
2597
2598 }
2599 else
2600 {
2601 delete updateIncumbent;
2602 return false;
2603 }
2604}
2605
2606/** write ugs incumbent solution **/
2607void
2608ScipParaInitiator::writeUgsIncumbentSolution(
2609 UGS::UgsParaCommMpi *ugsComm
2610 )
2611{
2612 /* Write out the solution */
2613 seqNumber++;
2614 std::ostringstream s;
2615 s << ugsComm->getMySolverName() << "-" << seqNumber << ".sol";
2616 FILE *fp = fopen(s.str().c_str(), "w");
2617 if( fp == NULL )
2618 {
2619 fprintf (stderr, "Cannot open solution file to write. File name = %s\n", s.str().c_str());
2620 exit(1);
2621 }
2622
2623 SCIP_SOL* sol = SCIPgetBestSol(scip);
2624
2625 assert(sol);
2626 fprintf( fp, "# ");
2627
2628 SCIP_CALL_ABORT( SCIPprintSol(scip, sol, fp, TRUE) );
2629
2630 fclose(fp);
2631
2632 UGS::UgsUpdateIncumbent *uui = new UGS::UgsUpdateIncumbent(ugsComm->getMySolverId(), seqNumber, convertToExternalValue(solution->getObjectiveFunctionValue()) );
2633 uui->send(ugsComm->getMyComm(),0);
2634 // std::cout << "Rank" << ugsComm->getRank() << " Sent to 0: " << uui->toString() << std::endl;
2635 delete uui;
2636
2637 return;
2638}
2639#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)
int reInit(int nRestartedRacing)
void accumulateInitialStat(UG::ParaInitialStat *initialStat)
UG::FinalSolverState finalState
UG::ParaParamSet * paraParams
ScipDiffParamSet * scipDiffParamSetRoot
void includeUserPlugins(SCIP *inScip)
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
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
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