Scippy

SCIP

Solving Constraint Integer Programs

scip_general.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program and library */
4 /* SCIP --- Solving Constraint Integer Programs */
5 /* */
6 /* Copyright (c) 2002-2024 Zuse Institute Berlin (ZIB) */
7 /* */
8 /* Licensed under the Apache License, Version 2.0 (the "License"); */
9 /* you may not use this file except in compliance with the License. */
10 /* You may obtain a copy of the License at */
11 /* */
12 /* http://www.apache.org/licenses/LICENSE-2.0 */
13 /* */
14 /* Unless required by applicable law or agreed to in writing, software */
15 /* distributed under the License is distributed on an "AS IS" BASIS, */
16 /* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17 /* See the License for the specific language governing permissions and */
18 /* limitations under the License. */
19 /* */
20 /* You should have received a copy of the Apache-2.0 license */
21 /* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22 /* */
23 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24 
25 /**@file scip_general.c
26  * @ingroup OTHER_CFILES
27  * @brief general public methods
28  * @author Tobias Achterberg
29  * @author Timo Berthold
30  * @author Gerald Gamrath
31  * @author Leona Gottwald
32  * @author Stefan Heinz
33  * @author Gregor Hendel
34  * @author Thorsten Koch
35  * @author Alexander Martin
36  * @author Marc Pfetsch
37  * @author Michael Winkler
38  * @author Kati Wolter
39  *
40  * @todo check all SCIP_STAGE_* switches, and include the new stages TRANSFORMED and INITSOLVE
41  */
42 
43 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
44 
45 #include "blockmemshell/memory.h"
46 #include "lpi/lpi.h"
47 #include "scip/exprinterpret.h"
48 #include "scip/clock.h"
49 #include "scip/debug.h"
50 #include "scip/dialog.h"
51 #include "scip/interrupt.h"
52 #include "scip/mem.h"
53 #include "scip/message_default.h"
54 #include "scip/nlp.h"
55 #include "scip/pub_message.h"
56 #include "scip/retcode.h"
57 #include "scip/scipbuildflags.h"
58 #include "scip/scipcoreplugins.h"
59 #include "scip/scip_general.h"
60 #include "scip/scipgithash.h"
61 #include "scip/scip_mem.h"
62 #include "scip/scip_message.h"
63 #include "scip/scip_numerics.h"
64 #include "scip/scip_prob.h"
65 #include "scip/scip_solvingstats.h"
66 #include "scip/set.h"
67 #include "scip/solve.h"
68 #include "scip/struct_mem.h"
69 #include "scip/struct_primal.h"
70 #include "scip/struct_prob.h"
71 #include "scip/struct_scip.h"
72 #include "scip/struct_set.h"
73 #include "scip/struct_stat.h"
74 #include "scip/syncstore.h"
75 #include "scip/lapack_calls.h"
76 
77 #include <string.h>
78 #if defined(_WIN32) || defined(_WIN64)
79 #else
80 #include <strings.h> /*lint --e{766}*/
81 #endif
82 
83 #ifdef SCIP_WITH_ZLIB
84 #include <zlib.h>
85 #endif
86 
87 /* In debug mode, the following methods are implemented as function calls to ensure
88  * type validity.
89  * In optimized mode, the methods are implemented as defines to improve performance.
90  * However, we want to have them in the library anyways, so we have to undef the defines.
91  */
92 
93 #undef SCIPgetStage
94 #undef SCIPhasPerformedPresolve
95 #undef SCIPisStopped
96 
97 /** returns complete SCIP version number in the format "major . minor tech"
98  *
99  * @return complete SCIP version
100  */
102  void
103  )
104 {
105  return SCIP_VERSION_MAJOR + SCIP_VERSION_MINOR/100.0; /*lint !e835*/
106 }
107 
108 /** returns SCIP major version
109  *
110  * @return major SCIP version
111  */
113  void
114  )
115 {
116  return SCIP_VERSION_MAJOR;
117 }
118 
119 /** returns SCIP minor version
120  *
121  * @return minor SCIP version
122  */
124  void
125  )
126 {
127  return SCIP_VERSION_MINOR;
128 }
129 
130 /** returns SCIP technical version
131  *
132  * @return technical SCIP version
133  */
135  void
136  )
137 {
138  return SCIP_VERSION_PATCH;
139 }
140 
141 /** returns SCIP sub version number
142  *
143  * @return subversion SCIP version
144  */
146  void
147  )
148 {
149  return SCIP_SUBVERSION;
150 }
151 
152 /** prints a version information line to a file stream via the message handler system
153  *
154  * @note If the message handler is set to a NULL pointer nothing will be printed
155  */
157  SCIP* scip, /**< SCIP data structure */
158  FILE* file /**< output file (or NULL for standard output) */
159  )
160 {
161  assert( scip != NULL );
162 
163  SCIPmessageFPrintInfo(scip->messagehdlr, file, "SCIP version %d.%d.%d",
165 #if SCIP_SUBVERSION > 0
166  SCIPmessageFPrintInfo(scip->messagehdlr, file, ".%d", SCIPsubversion());
167 #endif
168 
169  SCIPmessageFPrintInfo(scip->messagehdlr, file, " [precision: %d byte]", (int)sizeof(SCIP_Real));
170 
171 #ifndef BMS_NOBLOCKMEM
172  SCIPmessageFPrintInfo(scip->messagehdlr, file, " [memory: block]");
173 #else
174  SCIPmessageFPrintInfo(scip->messagehdlr, file, " [memory: standard]");
175 #endif
176 #ifndef NDEBUG
177  SCIPmessageFPrintInfo(scip->messagehdlr, file, " [mode: debug]");
178 #else
179  SCIPmessageFPrintInfo(scip->messagehdlr, file, " [mode: optimized]");
180 #endif
181  SCIPmessageFPrintInfo(scip->messagehdlr, file, " [LP solver: %s]", SCIPlpiGetSolverName());
182  SCIPmessageFPrintInfo(scip->messagehdlr, file, " [GitHash: %s]", SCIPgetGitHash());
183  SCIPmessageFPrintInfo(scip->messagehdlr, file, "\n");
184  SCIPmessageFPrintInfo(scip->messagehdlr, file, "%s\n", SCIP_COPYRIGHT);
185 }
186 
187 /** prints detailed information on the compile-time flags
188  *
189  * @note If the message handler is set to a NULL pointer nothing will be printed
190  */
192  SCIP* scip, /**< SCIP data structure */
193  FILE* file /**< output file (or NULL for standard output) */
194  )
195 {
196  assert( scip != NULL );
197 
198  /* compiler */
199  SCIPmessageFPrintInfo(scip->messagehdlr, file, "Compiler: ");
200 #if defined(__INTEL_COMPILER)
201  SCIPmessageFPrintInfo(scip->messagehdlr, file, "Intel %d\n", __INTEL_COMPILER);
202 #elif defined(__clang__)
203  SCIPmessageFPrintInfo(scip->messagehdlr, file, "clang %d.%d.%d\n", __clang_major__, __clang_minor__, __clang_patchlevel__);
204 #elif defined(_MSC_VER)
205  SCIPmessageFPrintInfo(scip->messagehdlr, file, "microsoft visual c %d\n", _MSC_FULL_VER);
206 #elif defined(__GNUC__)
207 #if defined(__GNUC_PATCHLEVEL__)
208  SCIPmessageFPrintInfo(scip->messagehdlr, file, "gcc %d.%d.%d\n", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
209 #else
210  SCIPmessageFPrintInfo(scip->messagehdlr, file, "gcc %d.%d\n", __GNUC__, __GNUC_MINOR__);
211 #endif
212 #else
213  SCIPmessageFPrintInfo(scip->messagehdlr, file, "unknown\n");
214 #endif
215 
216  /* build flags */
217  SCIPmessageFPrintInfo(scip->messagehdlr, file, "\nBuild options:\n%s", SCIPgetBuildFlags());
218 }
219 
220 /** prints error message for the given SCIP_RETCODE via the error prints method */
222  SCIP_RETCODE retcode /**< SCIP return code causing the error */
223  )
224 {
225  SCIPmessagePrintError("SCIP Error (%d): ", retcode);
226  SCIPretcodePrintError(retcode);
227  SCIPmessagePrintError("\n");
228 }
229 
230 /*
231  * general SCIP methods
232  */
233 
234 /** internal method to create SCIP */
235 static
237  SCIP** scip /**< pointer to SCIP data structure */
238  )
239 {
240  assert(scip != NULL);
241 
242  SCIP_ALLOC( BMSallocMemory(scip) );
243 
244  /* all members are initialized to NULL */
245  BMSclearMemory(*scip);
246 
247  /* create a default message handler */
248  SCIP_CALL( SCIPcreateMessagehdlrDefault(&(*scip)->messagehdlr, TRUE, NULL, FALSE) );
249 
250  SCIP_CALL( SCIPmemCreate(&(*scip)->mem) );
251  SCIP_CALL( SCIPsetCreate(&(*scip)->set, (*scip)->messagehdlr, (*scip)->mem->setmem, *scip) );
252  SCIP_CALL( SCIPinterruptCreate(&(*scip)->interrupt) );
253  SCIP_CALL( SCIPdialoghdlrCreate((*scip)->set, &(*scip)->dialoghdlr) );
254  SCIP_CALL( SCIPclockCreate(&(*scip)->totaltime, SCIP_CLOCKTYPE_DEFAULT) );
255  SCIP_CALL( SCIPsyncstoreCreate( &(*scip)->syncstore ) );
256 
257  /* include additional core functionality */
259 
260  SCIPclockStart((*scip)->totaltime, (*scip)->set);
261 
262  SCIP_CALL( SCIPnlpInclude((*scip)->set, SCIPblkmem(*scip)) );
263 
264  if( strcmp(SCIPlpiGetSolverName(), "NONE") != 0 )
265  {
267  }
268  if( strcmp(SCIPexprintGetName(), "NONE") != 0 )
269  {
271  }
272 
273 #ifdef SCIP_WITH_ZLIB
274  SCIP_CALL( SCIPsetIncludeExternalCode((*scip)->set, "ZLIB " ZLIB_VERSION, "General purpose compression library by J. Gailly and M. Adler (zlib.net)") );
275 #endif
276 
277 #ifdef SCIP_WITH_LAPACK
278  {
279  char name[SCIP_MAXSTRLEN];
280  int major;
281  int minor;
282  int patch;
283 
284  SCIPlapackVersion(&major, &minor, &patch);
285  SCIPsnprintf(name, SCIP_MAXSTRLEN, "LAPACK %d.%d.%d", major, minor, patch);
286 
287  SCIP_CALL( SCIPsetIncludeExternalCode((*scip)->set, name, "General Linear Algebra PACKage (http://www.netlib.org/lapack/)") );
288  }
289 #endif
290 
291  return SCIP_OKAY;
292 }
293 
294 /** creates and initializes SCIP data structures
295  *
296  * @note The SCIP default message handler is installed. Use the method SCIPsetMessagehdlr() to install your own
297  * message handler or SCIPsetMessagehdlrLogfile() and SCIPsetMessagehdlrQuiet() to write into a log
298  * file and turn off/on the display output, respectively.
299  *
300  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
301  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
302  *
303  * @post After calling this method \SCIP reached the solving stage \ref SCIP_STAGE_INIT
304  *
305  * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
306  */
308  SCIP** scip /**< pointer to SCIP data structure */
309  )
310 {
311  assert(scip != NULL);
312 
313  SCIP_CALL_FINALLY( doScipCreate(scip), (void)SCIPfree(scip) );
314 
315  return SCIP_OKAY;
316 }
317 
318 /** frees SCIP data structures
319  *
320  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
321  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
322  *
323  * @pre This method can be called if @p scip is in one of the following stages:
324  * - \ref SCIP_STAGE_INIT
325  * - \ref SCIP_STAGE_PROBLEM
326  * - \ref SCIP_STAGE_TRANSFORMED
327  * - \ref SCIP_STAGE_INITPRESOLVE
328  * - \ref SCIP_STAGE_PRESOLVING
329  * - \ref SCIP_STAGE_PRESOLVED
330  * - \ref SCIP_STAGE_EXITPRESOLVE
331  * - \ref SCIP_STAGE_SOLVING
332  * - \ref SCIP_STAGE_SOLVED
333  * - \ref SCIP_STAGE_FREE
334  *
335  * @post After calling this method \SCIP reached the solving stage \ref SCIP_STAGE_FREE
336  *
337  * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
338  */
340  SCIP** scip /**< pointer to SCIP data structure */
341  )
342 {
343  assert(scip != NULL);
344  if( *scip == NULL )
345  return SCIP_OKAY;
346 
347  SCIP_CALL( SCIPcheckStage(*scip, "SCIPfree", TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE) );
348 
349  SCIP_CALL( SCIPfreeProb(*scip) );
350  assert((*scip)->set->stage == SCIP_STAGE_INIT);
351 
352  /* switch stage to FREE */
353  (*scip)->set->stage = SCIP_STAGE_FREE;
354 
355  SCIP_CALL( SCIPsyncstoreRelease(&(*scip)->syncstore) );
356  SCIP_CALL( SCIPsetFree(&(*scip)->set, (*scip)->mem->setmem) );
357  SCIP_CALL( SCIPdialoghdlrFree(*scip, &(*scip)->dialoghdlr) );
358  SCIPclockFree(&(*scip)->totaltime);
359  SCIPinterruptFree(&(*scip)->interrupt);
360  SCIP_CALL( SCIPmemFree(&(*scip)->mem) );
361 
362  /* release message handler */
363  SCIP_CALL( SCIPmessagehdlrRelease(&(*scip)->messagehdlr) );
364 
365  BMSfreeMemory(scip);
366 
367  return SCIP_OKAY;
368 }
369 
370 #undef SCIPgetStage
371 #undef SCIPhasPerformedPresolve
372 #undef SCIPisStopped
373 
374 /** returns current stage of SCIP
375  *
376  * @return the current SCIP stage
377  *
378  * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
379  */
381  SCIP* scip /**< SCIP data structure */
382  )
383 {
384  assert(scip != NULL);
385  assert(scip->set != NULL);
386 
387  return scip->set->stage;
388 }
389 
390 /** outputs SCIP stage and solution status if applicable via the message handler
391  *
392  * @note If the message handler is set to a NULL pointer nothing will be printed
393  *
394  * @note If limits have been changed between the solution and the call to this function, the status is recomputed and
395  * thus may to correspond to the original status.
396  *
397  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
398  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
399  *
400  * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages.
401  */
403  SCIP* scip, /**< SCIP data structure */
404  FILE* file /**< output file (or NULL for standard output) */
405  )
406 {
407  SCIP_CALL( SCIPcheckStage(scip, "SCIPprintStage", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE) );
408 
409  switch( scip->set->stage )
410  {
411  case SCIP_STAGE_INIT:
412  SCIPmessageFPrintInfo(scip->messagehdlr, file, "initialization");
413  break;
414  case SCIP_STAGE_PROBLEM:
415  SCIPmessageFPrintInfo(scip->messagehdlr, file, "problem creation / modification");
416  break;
418  SCIPmessageFPrintInfo(scip->messagehdlr, file, "problem transformation");
419  break;
421  SCIPmessageFPrintInfo(scip->messagehdlr, file, "problem transformed");
422  break;
424  SCIPmessageFPrintInfo(scip->messagehdlr, file, "presolving is being initialized");
425  break;
427  if( SCIPsolveIsStopped(scip->set, scip->stat, TRUE) )
428  {
429  SCIPmessageFPrintInfo(scip->messagehdlr, file, "solving was interrupted [");
430  SCIP_CALL( SCIPprintStatus(scip, file) );
431  SCIPmessageFPrintInfo(scip->messagehdlr, file, "]");
432  }
433  else
434  SCIPmessageFPrintInfo(scip->messagehdlr, file, "presolving process is running");
435  break;
437  SCIPmessageFPrintInfo(scip->messagehdlr, file, "presolving is being exited");
438  break;
440  if( SCIPsolveIsStopped(scip->set, scip->stat, TRUE) )
441  {
442  SCIPmessageFPrintInfo(scip->messagehdlr, file, "solving was interrupted [");
443  SCIP_CALL( SCIPprintStatus(scip, file) );
444  SCIPmessageFPrintInfo(scip->messagehdlr, file, "]");
445  }
446  else
447  SCIPmessageFPrintInfo(scip->messagehdlr, file, "problem is presolved");
448  break;
450  SCIPmessageFPrintInfo(scip->messagehdlr, file, "solving process initialization");
451  break;
452  case SCIP_STAGE_SOLVING:
453  if( SCIPsolveIsStopped(scip->set, scip->stat, TRUE) )
454  {
455  SCIPmessageFPrintInfo(scip->messagehdlr, file, "solving was interrupted [");
456  SCIP_CALL( SCIPprintStatus(scip, file) );
457  SCIPmessageFPrintInfo(scip->messagehdlr, file, "]");
458  }
459  else
460  SCIPmessageFPrintInfo(scip->messagehdlr, file, "solving process is running");
461  break;
462  case SCIP_STAGE_SOLVED:
463  SCIPmessageFPrintInfo(scip->messagehdlr, file, "problem is solved [");
464  SCIP_CALL( SCIPprintStatus(scip, file) );
465  SCIPmessageFPrintInfo(scip->messagehdlr, file, "]");
466 
467  /* We output that the objective limit has been reached if no solution respecting the objective limit has been
468  * found (nlimsolsfound == 0) and the primal bound is finite. Note that it still might be that the original
469  * problem is infeasible, even without the objective limit, i.e., we cannot be sure that we actually reached the
470  * objective limit. */
471  if( scip->primal->nlimsolsfound == 0 && !SCIPisInfinity(scip, (SCIP_Real)SCIPgetObjsense(scip) * SCIPgetPrimalbound(scip)) )
472  SCIPmessageFPrintInfo(scip->messagehdlr, file, " (objective limit reached)");
473 
474  break;
476  SCIPmessageFPrintInfo(scip->messagehdlr, file, "solving process deinitialization");
477  break;
479  SCIPmessageFPrintInfo(scip->messagehdlr, file, "freeing transformed problem");
480  break;
481  case SCIP_STAGE_FREE:
482  SCIPmessageFPrintInfo(scip->messagehdlr, file, "freeing SCIP");
483  break;
484  default:
485  SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage);
486  return SCIP_INVALIDDATA;
487  }
488 
489  return SCIP_OKAY;
490 }
491 
492 /** gets solution status
493  *
494  * @return SCIP solution status
495  *
496  * See \ref SCIP_Status "SCIP_STATUS" for a complete list of all possible solving status.
497  */
499  SCIP* scip /**< SCIP data structure */
500  )
501 {
502  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetStatus", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE) );
503 
504  if( scip->set->stage == SCIP_STAGE_INIT || scip->set->stage == SCIP_STAGE_FREE )
505  return SCIP_STATUS_UNKNOWN;
506  else
507  {
508  assert(scip->stat != NULL);
509 
510  return scip->stat->status;
511  }
512 }
513 
514 /** outputs solution status
515  *
516  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
517  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
518  *
519  * See \ref SCIP_Status "SCIP_STATUS" for a complete list of all possible solving status.
520  */
522  SCIP* scip, /**< SCIP data structure */
523  FILE* file /**< output file (or NULL for standard output) */
524  )
525 {
526  SCIP_CALL( SCIPcheckStage(scip, "SCIPprintStatus", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE) );
527 
528  switch( SCIPgetStatus(scip) )
529  {
530  case SCIP_STATUS_UNKNOWN:
531  SCIPmessageFPrintInfo(scip->messagehdlr, file, "unknown");
532  break;
534  SCIPmessageFPrintInfo(scip->messagehdlr, file, "user interrupt");
535  break;
537  SCIPmessageFPrintInfo(scip->messagehdlr, file, "node limit reached");
538  break;
540  SCIPmessageFPrintInfo(scip->messagehdlr, file, "total node limit reached");
541  break;
543  SCIPmessageFPrintInfo(scip->messagehdlr, file, "stall node limit reached");
544  break;
546  SCIPmessageFPrintInfo(scip->messagehdlr, file, "time limit reached");
547  break;
549  SCIPmessageFPrintInfo(scip->messagehdlr, file, "memory limit reached");
550  break;
552  SCIPmessageFPrintInfo(scip->messagehdlr, file, "gap limit reached");
553  break;
555  SCIPmessageFPrintInfo(scip->messagehdlr, file, "primal limit reached");
556  break;
558  SCIPmessageFPrintInfo(scip->messagehdlr, file, "dual limit reached");
559  break;
561  SCIPmessageFPrintInfo(scip->messagehdlr, file, "solution limit reached");
562  break;
564  SCIPmessageFPrintInfo(scip->messagehdlr, file, "solution improvement limit reached");
565  break;
567  SCIPmessageFPrintInfo(scip->messagehdlr, file, "restart limit reached");
568  break;
569  case SCIP_STATUS_OPTIMAL:
570  SCIPmessageFPrintInfo(scip->messagehdlr, file, "optimal solution found");
571  break;
573  SCIPmessageFPrintInfo(scip->messagehdlr, file, "infeasible");
574  break;
576  SCIPmessageFPrintInfo(scip->messagehdlr, file, "unbounded");
577  break;
579  SCIPmessageFPrintInfo(scip->messagehdlr, file, "infeasible or unbounded");
580  break;
582  SCIPmessageFPrintInfo(scip->messagehdlr, file, "termination signal received");
583  break;
584  default:
585  SCIPerrorMessage("invalid status code <%d>\n", SCIPgetStatus(scip));
586  return SCIP_INVALIDDATA;
587  }
588 
589  return SCIP_OKAY;
590 }
591 
592 /** returns whether the current stage belongs to the transformed problem space
593  *
594  * @return Returns TRUE if the \SCIP instance is transformed, otherwise FALSE
595  */
597  SCIP* scip /**< SCIP data structure */
598  )
599 {
600  assert(scip != NULL);
601 
602  return ((int)scip->set->stage >= (int)SCIP_STAGE_TRANSFORMING);
603 }
604 
605 /** returns whether the solution process should be probably correct
606  *
607  * @note This feature is not supported yet!
608  *
609  * @return Returns TRUE if \SCIP is exact solving mode, otherwise FALSE
610  */
612  SCIP* scip /**< SCIP data structure */
613  )
614 {
615  assert(scip != NULL);
616  assert(scip->set != NULL);
617 
618  return (scip->set->misc_exactsolve);
619 }
620 
621 /** returns whether the presolving process would be finished given no more presolving reductions are found in this
622  * presolving round
623  *
624  * Checks whether the number of presolving rounds is not exceeded and the presolving reductions found in the current
625  * presolving round suffice to trigger another presolving round.
626  *
627  * @note if subsequent presolvers find more reductions, presolving might continue even if the method returns FALSE
628  * @note does not check whether infeasibility or unboundedness was already detected in presolving (which would result
629  * in presolving being stopped although the method returns TRUE)
630  *
631  * @return Returns TRUE if presolving is finished if no further reductions are detected
632  */
634  SCIP* scip /**< SCIP data structure */
635  )
636 {
637  int maxnrounds;
638  SCIP_Bool finished;
639 
640  assert(scip != NULL);
641  assert(scip->stat != NULL);
642  assert(scip->transprob != NULL);
643 
644  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPisPresolveFinished", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
645 
646  /* get maximum number of presolving rounds */
647  maxnrounds = scip->set->presol_maxrounds;
648  if( maxnrounds == -1 )
649  maxnrounds = INT_MAX;
650 
651  /* don't abort, if enough changes were applied to the variables */
652  finished = (scip->transprob->nvars == 0
653  || (scip->stat->npresolfixedvars - scip->stat->lastnpresolfixedvars
654  + scip->stat->npresolaggrvars - scip->stat->lastnpresolaggrvars
656  + (scip->stat->npresolchgbds - scip->stat->lastnpresolchgbds)/10.0
657  + (scip->stat->npresoladdholes - scip->stat->lastnpresoladdholes)/10.0
658  <= scip->set->presol_abortfac * scip->transprob->nvars)); /*lint !e653*/
659 
660  /* don't abort, if enough changes were applied to the constraints */
661  finished = finished
662  && (scip->transprob->nconss == 0
663  || (scip->stat->npresoldelconss - scip->stat->lastnpresoldelconss
664  + scip->stat->npresoladdconss - scip->stat->lastnpresoladdconss
666  + scip->stat->npresolchgsides - scip->stat->lastnpresolchgsides
667  <= scip->set->presol_abortfac * scip->transprob->nconss));
668 
669  /* don't abort, if enough changes were applied to the coefficients (assume a 1% density of non-zero elements) */
670  finished = finished
671  && (scip->transprob->nvars == 0 || scip->transprob->nconss == 0
672  || (scip->stat->npresolchgcoefs - scip->stat->lastnpresolchgcoefs
673  <= scip->set->presol_abortfac * 0.01 * scip->transprob->nvars * scip->transprob->nconss));
674 
675 #ifdef SCIP_DISABLED_CODE
676  /* since 2005, we do not take cliques and implications into account when deciding whether to stop presolving */
677  /* don't abort, if enough new implications or cliques were found (assume 100 implications per variable) */
678  finished = finished
679  && (scip->stat->nimplications - scip->stat->lastnpresolimplications
680  <= scip->set->presol_abortfac * 100 * scip->transprob->nbinvars)
681  && (SCIPcliquetableGetNCliques(scip->cliquetable) - scip->stat->lastnpresolcliques
682  <= scip->set->presol_abortfac * scip->transprob->nbinvars);
683 #endif
684 
685  /* abort if maximal number of presolving rounds is reached */
686  finished = finished || (scip->stat->npresolrounds + 1 >= maxnrounds);
687 
688  return finished;
689 }
690 
691 /** returns whether SCIP has performed presolving during the last solve
692  *
693  * @return Returns TRUE if presolving was performed during the last solve
694  */
696  SCIP* scip /**< SCIP data structure */
697  )
698 {
699  assert(scip != NULL);
700  assert(scip->stat != NULL);
701 
702  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPhasPerformedPresolve", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
703 
704  return scip->stat->performpresol;
705 }
706 
707 /** returns whether the user pressed CTRL-C to interrupt the solving process
708  *
709  * @return Returns TRUE if Ctrl-C was pressed, otherwise FALSE.
710  */ /*lint -e715*/
712  SCIP* scip /**< SCIP data structure */
713  )
714 {
715  return SCIPinterrupted();
716 }
717 
718 /** returns whether the solving process should be / was stopped before proving optimality;
719  * if the solving process should be / was stopped, the status returned by SCIPgetStatus() yields
720  * the reason for the premature abort
721  *
722  * @return Returns TRUE if solving process is stopped/interrupted, otherwise FALSE.
723  */
725  SCIP* scip /**< SCIP data structure */
726  )
727 {
728  SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPisStopped", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
729 
730  return SCIPsolveIsStopped(scip->set, scip->stat, FALSE);
731 }
732 
733 /** includes information about an external code linked into the SCIP library */
735  SCIP* scip, /**< SCIP data structure */
736  const char* name, /**< name of external code */
737  const char* description /**< description of external code, or NULL */
738  )
739 {
740  assert(scip != NULL);
741  assert(name != NULL);
742 
743  SCIP_CALL( SCIPcheckStage(scip, "SCIPincludeExternalCodeInformation", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
744 
745  SCIP_CALL( SCIPsetIncludeExternalCode(scip->set, name, description) );
746 
747  return SCIP_OKAY;
748 }
749 
750 /** returns an array of names of currently included external codes */
752  SCIP* scip /**< SCIP data structure */
753  )
754 {
755  assert(scip != NULL);
756  assert(scip->set != NULL);
757 
758  return scip->set->extcodenames;
759 }
760 
761 /** returns an array of the descriptions of currently included external codes
762  *
763  * @note some descriptions may be NULL
764  */
766  SCIP* scip /**< SCIP data structure */
767  )
768 {
769  assert(scip != NULL);
770  assert(scip->set != NULL);
771 
772  return scip->set->extcodedescs;
773 }
774 
775 /** returns the number of currently included information on external codes */
777  SCIP* scip /**< SCIP data structure */
778  )
779 {
780  assert(scip != NULL);
781  assert(scip->set != NULL);
782 
783  return scip->set->nextcodes;
784 }
785 
786 /** prints information on external libraries to a file stream via the message handler system
787  *
788  * @note If the message handler is set to a NULL pointer nothing will be printed
789  */
791  SCIP* scip, /**< SCIP data structure */
792  FILE* file /**< output file (or NULL for standard output) */
793  )
794 {
795  int i;
796 
797  SCIPmessageFPrintInfo(scip->messagehdlr, file, "External libraries: ");
798  if( scip->set->nextcodes == 0 )
799  {
800  SCIPinfoMessage(scip, file, "none\n");
801  return;
802  }
803  SCIPinfoMessage(scip, file, "\n");
804 
805  for( i = 0; i < scip->set->nextcodes; ++i )
806  {
807  SCIPinfoMessage(scip, file, " %-20s %s\n", scip->set->extcodenames[i], scip->set->extcodedescs[i] != NULL ? scip->set->extcodedescs[i] : "");
808  }
809 }
SCIP_STAT * stat
Definition: struct_scip.h:80
SCIP_Bool SCIPsolveIsStopped(SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool checknodelimits)
Definition: solve.c:102
int npresoladdconss
Definition: struct_stat.h:252
#define NULL
Definition: def.h:267
const char * SCIPexprintGetName(void)
default message handler
SCIP_RETCODE SCIPsyncstoreRelease(SCIP_SYNCSTORE **syncstore)
Definition: syncstore.c:89
SCIP_STATUS status
Definition: struct_stat.h:186
SCIP_STAGE SCIPgetStage(SCIP *scip)
Definition: scip_general.c:380
methods to interpret (evaluate) an expression "fast"
public methods for memory management
SCIP_Real SCIPgetPrimalbound(SCIP *scip)
int presol_maxrounds
Definition: struct_set.h:453
#define SCIP_MAXSTRLEN
Definition: def.h:288
internal methods for clocks and timing issues
SCIP_RETCODE SCIPsetCreate(SCIP_SET **set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, SCIP *scip)
Definition: set.c:1183
int npresolaggrvars
Definition: struct_stat.h:247
#define SCIP_CALL_FINALLY(x, y)
Definition: def.h:422
char ** SCIPgetExternalCodeDescriptions(SCIP *scip)
Definition: scip_general.c:765
int npresolfixedvars
Definition: struct_stat.h:246
SCIP_PRIMAL * primal
Definition: struct_scip.h:95
#define SCIP_SUBVERSION
Definition: def.h:135
interface methods for specific LP solvers
int npresoldelconss
Definition: struct_stat.h:251
int SCIPmajorVersion(void)
Definition: scip_general.c:112
int lastnpresolchgvartypes
Definition: struct_stat.h:258
#define FALSE
Definition: def.h:94
void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:290
void SCIPprintExternalCodes(SCIP *scip, FILE *file)
Definition: scip_general.c:790
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10877
SCIP_STAGE stage
Definition: struct_set.h:75
#define TRUE
Definition: def.h:93
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
char ** SCIPgetExternalCodeNames(SCIP *scip)
Definition: scip_general.c:751
const char * SCIPgetGitHash(void)
Definition: scipgithash.c:37
const char * SCIPexprintGetDesc(void)
SCIP_RETCODE SCIPinterruptCreate(SCIP_INTERRUPT **interrupt)
Definition: interrupt.c:91
SCIP_PROB * transprob
Definition: struct_scip.h:99
SCIP_RETCODE SCIPcreate(SCIP **scip)
Definition: scip_general.c:307
#define BMSfreeMemory(ptr)
Definition: memory.h:145
SCIP_Bool SCIPisTransformed(SCIP *scip)
Definition: scip_general.c:596
SCIP_Bool SCIPpressedCtrlC(SCIP *scip)
Definition: scip_general.c:711
int lastnpresoladdconss
Definition: struct_stat.h:262
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:208
public methods for numerical tolerances
SCIP_DIALOGHDLR * dialoghdlr
Definition: struct_scip.h:75
public methods for querying solving statistics
SCIP_RETCODE SCIPsetFree(SCIP_SET **set, BMS_BLKMEM *blkmem)
Definition: set.c:2839
char ** extcodedescs
Definition: struct_set.h:115
int SCIPcliquetableGetNCliques(SCIP_CLIQUETABLE *cliquetable)
Definition: implics.c:3506
int npresolchgcoefs
Definition: struct_stat.h:254
int npresolchgvartypes
Definition: struct_stat.h:248
SCIP_Bool SCIPisPresolveFinished(SCIP *scip)
Definition: scip_general.c:633
int lastnpresolfixedvars
Definition: struct_stat.h:256
git hash methods
int lastnpresoladdholes
Definition: struct_stat.h:260
void SCIPmessagePrintError(const char *formatstr,...)
Definition: message.c:791
#define SCIPerrorMessage
Definition: pub_message.h:64
methods for block memory pools and memory buffers
SCIP_RETCODE SCIPfreeProb(SCIP *scip)
Definition: scip_prob.c:694
int npresolchgsides
Definition: struct_stat.h:255
void SCIPlapackVersion(int *majorver, int *minorver, int *patchver)
Definition: lapack_calls.c:181
int lastnpresolchgbds
Definition: struct_stat.h:259
register additional core functionality that is designed as plugins
SCIP_RETCODE SCIPcheckStage(SCIP *scip, const char *method, SCIP_Bool init, SCIP_Bool problem, SCIP_Bool transforming, SCIP_Bool transformed, SCIP_Bool initpresolve, SCIP_Bool presolving, SCIP_Bool exitpresolve, SCIP_Bool presolved, SCIP_Bool initsolve, SCIP_Bool solving, SCIP_Bool solved, SCIP_Bool exitsolve, SCIP_Bool freetrans, SCIP_Bool freescip)
Definition: debug.c:2208
SCIP_STATUS SCIPgetStatus(SCIP *scip)
Definition: scip_general.c:498
SCIP_Real SCIPversion(void)
Definition: scip_general.c:101
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition: scip_mem.c:57
void SCIPretcodePrintError(SCIP_RETCODE retcode)
Definition: retcode.c:113
SCIP_RETCODE SCIPprintStage(SCIP *scip, FILE *file)
Definition: scip_general.c:402
SCIP_RETCODE SCIPdialoghdlrCreate(SCIP_SET *set, SCIP_DIALOGHDLR **dialoghdlr)
Definition: dialog.c:336
internal methods for NLP management
SCIP_RETCODE SCIPmessagehdlrRelease(SCIP_MESSAGEHDLR **messagehdlr)
Definition: message.c:348
const char * SCIPlpiGetSolverDesc(void)
Definition: lpi_clp.cpp:463
int npresolchgbds
Definition: struct_stat.h:249
internal methods for global SCIP settings
#define SCIP_CALL(x)
Definition: def.h:380
int npresoladdholes
Definition: struct_stat.h:250
SCIP main data structure.
SCIP_RETCODE SCIPprintStatus(SCIP *scip, FILE *file)
Definition: scip_general.c:521
int lastnpresoldelconss
Definition: struct_stat.h:261
interface methods for lapack functions
SCIP_RETCODE SCIPclockCreate(SCIP_CLOCK **clck, SCIP_CLOCKTYPE clocktype)
Definition: clock.c:170
methods for catching the user CTRL-C interrupt
SCIP_CLIQUETABLE * cliquetable
Definition: struct_scip.h:98
SCIP_RETCODE SCIPmemCreate(SCIP_MEM **mem)
Definition: mem.c:43
#define SCIP_COPYRIGHT
Definition: def.h:137
the function declarations for the synchronization store
internal methods for user interface dialog
int SCIPgetNExternalCodes(SCIP *scip)
Definition: scip_general.c:776
#define SCIP_Bool
Definition: def.h:91
SCIP_Bool SCIPinterrupted(void)
Definition: interrupt.c:163
static SCIP_RETCODE doScipCreate(SCIP **scip)
Definition: scip_general.c:236
void SCIPprintVersion(SCIP *scip, FILE *file)
Definition: scip_general.c:156
void SCIPinterruptFree(SCIP_INTERRUPT **interrupt)
Definition: interrupt.c:104
int nbinvars
Definition: struct_prob.h:72
enum SCIP_Status SCIP_STATUS
Definition: type_stat.h:67
int npresolrounds
Definition: struct_stat.h:242
void SCIPclockFree(SCIP_CLOCK **clck)
Definition: clock.c:185
SCIP_RETCODE SCIPsetIncludeExternalCode(SCIP_SET *set, const char *name, const char *description)
Definition: set.c:5295
methods for debugging
int SCIPsubversion(void)
Definition: scip_general.c:145
SCIP_RETCODE SCIPincludeCorePlugins(SCIP *scip)
int lastnpresolchgcoefs
Definition: struct_stat.h:264
datastructures for block memory pools and memory buffers
int SCIPtechVersion(void)
Definition: scip_general.c:134
datastructures for problem statistics
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
#define BMSclearMemory(ptr)
Definition: memory.h:129
SCIP_RETCODE SCIPsyncstoreCreate(SCIP_SYNCSTORE **syncstore)
Definition: syncstore.c:67
internal methods for return codes for SCIP methods
datastructures for storing and manipulating the main problem
SCIP_Bool misc_exactsolve
Definition: struct_set.h:395
general public methods
SCIP_RETCODE SCIPcreateMessagehdlrDefault(SCIP_MESSAGEHDLR **messagehdlr, SCIP_Bool bufferedoutput, const char *filename, SCIP_Bool quiet)
char ** extcodenames
Definition: struct_set.h:114
internal methods for main solving loop and node processing
int nconss
Definition: struct_prob.h:83
SCIP_SET * set
Definition: struct_scip.h:73
public methods for message output
void SCIPmessageFPrintInfo(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *formatstr,...)
Definition: message.c:618
SCIP_MESSAGEHDLR * messagehdlr
Definition: struct_scip.h:76
#define SCIP_Real
Definition: def.h:173
SCIP_RETCODE SCIPmemFree(SCIP_MEM **mem)
Definition: mem.c:69
enum SCIP_Stage SCIP_STAGE
Definition: type_set.h:59
SCIP_Bool SCIPisStopped(SCIP *scip)
Definition: scip_general.c:724
datastructures for collecting primal CIP solutions and primal informations
public methods for message handling
#define BMSallocMemory(ptr)
Definition: memory.h:118
int nextcodes
Definition: struct_set.h:162
SCIP_OBJSENSE SCIPgetObjsense(SCIP *scip)
Definition: scip_prob.c:1225
build flags methods
SCIP_RETCODE SCIPincludeExternalCodeInformation(SCIP *scip, const char *name, const char *description)
Definition: scip_general.c:734
SCIP_Bool performpresol
Definition: struct_stat.h:282
SCIP_Bool SCIPhasPerformedPresolve(SCIP *scip)
Definition: scip_general.c:695
SCIP_RETCODE SCIPnlpInclude(SCIP_SET *set, BMS_BLKMEM *blkmem)
Definition: nlp.c:3514
SCIP_RETCODE SCIPdialoghdlrFree(SCIP *scip, SCIP_DIALOGHDLR **dialoghdlr)
Definition: dialog.c:367
#define SCIP_CALL_ABORT(x)
Definition: def.h:359
void SCIPprintError(SCIP_RETCODE retcode)
Definition: scip_general.c:221
#define SCIP_ALLOC(x)
Definition: def.h:391
int lastnpresolchgsides
Definition: struct_stat.h:265
public methods for global and local (sub)problems
const char * SCIPlpiGetSolverName(void)
Definition: lpi_clp.cpp:454
SCIP_Real presol_abortfac
Definition: struct_set.h:452
int SCIPminorVersion(void)
Definition: scip_general.c:123
SCIP_Longint nlimsolsfound
Definition: struct_primal.h:49
int npresolupgdconss
Definition: struct_stat.h:253
void SCIPprintBuildOptions(SCIP *scip, FILE *file)
Definition: scip_general.c:191
datastructures for global SCIP settings
SCIP_Bool SCIPisExactSolve(SCIP *scip)
Definition: scip_general.c:611
int lastnpresolaggrvars
Definition: struct_stat.h:257
int lastnpresolupgdconss
Definition: struct_stat.h:263
SCIP_RETCODE SCIPfree(SCIP **scip)
Definition: scip_general.c:339
int nimplications
Definition: struct_stat.h:241
const char * SCIPgetBuildFlags(void)
memory allocation routines