Scippy

SCIP

Solving Constraint Integer Programs

heur_indicator.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 heur_indicator.c
26  * @ingroup DEFPLUGINS_HEUR
27  * @brief handle partial solutions for linear problems with indicators and otherwise continuous variables
28  * @author Marc Pfetsch
29  *
30  * For linear problems with indicators and otherwise continuous variables, the indicator constraint handler can produce
31  * partial solutions, i.e., values for the indicator variables. This partial solution can be passed to this heuristic,
32  * which then fixes these values and solves an LP. Additionally a local search for a better solution is added.
33  */
34 
35 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
36 
37 #include "blockmemshell/memory.h"
38 #include "scip/cons_indicator.h"
39 #include "scip/heur_indicator.h"
40 #include "scip/pub_cons.h"
41 #include "scip/pub_heur.h"
42 #include "scip/pub_message.h"
43 #include "scip/pub_sol.h"
44 #include "scip/pub_var.h"
45 #include "scip/scip_cons.h"
46 #include "scip/scip_copy.h"
47 #include "scip/scip_general.h"
48 #include "scip/scip_heur.h"
49 #include "scip/scip_lp.h"
50 #include "scip/scip_mem.h"
51 #include "scip/scip_message.h"
52 #include "scip/scip_numerics.h"
53 #include "scip/scip_param.h"
54 #include "scip/scip_prob.h"
55 #include "scip/scip_probing.h"
56 #include "scip/scip_sol.h"
57 #include "scip/scip_tree.h"
58 #include <string.h>
59 
60 #define HEUR_NAME "indicator"
61 #define HEUR_DESC "indicator heuristic to create feasible solutions from values for indicator variables"
62 #define HEUR_DISPCHAR SCIP_HEURDISPCHAR_LNS
63 #define HEUR_PRIORITY -20200
64 #define HEUR_FREQ 1
65 #define HEUR_FREQOFS 0
66 #define HEUR_MAXDEPTH -1
67 #define HEUR_TIMING SCIP_HEURTIMING_DURINGLPLOOP
68 #define HEUR_USESSUBSCIP FALSE /**< does the heuristic use a secondary SCIP instance? */
69 
70 #define DEFAULT_ONEOPT FALSE /**< whether the one-opt heuristic should be started */
71 #define DEFAULT_IMPROVESOLS FALSE /**< Try to improve other solutions by one-opt? */
72 
73 
74 /** primal heuristic data */
75 struct SCIP_HeurData
76 {
77  int nindconss; /**< number of indicator constraints */
78  SCIP_CONS** indconss; /**< indicator constraints */
79  SCIP_Bool* solcand; /**< bitset of indicator variables in solution candidate */
80  SCIP_Real obj; /**< objective of previously stored solution */
81  SCIP_Bool oneopt; /**< whether the one-opt heuristic should be started */
82  SCIP_CONSHDLR* indicatorconshdlr; /**< indicator constraint handler */
83  SCIP_SOL* lastsol; /**< last solution considered for improvement */
84  SCIP_Bool improvesols; /**< Try to improve other solutions by one-opt? */
85 };
86 
87 /*
88  * Local methods
89  */
90 
91 /** try one-opt on given solution */
92 static
94  SCIP* scip, /**< SCIP data structure */
95  SCIP_HEUR* heur, /**< indicator heuristic */
96  SCIP_HEURDATA* heurdata, /**< heuristic data */
97  int nindconss, /**< number of indicator constraints */
98  SCIP_CONS** indconss, /**< indicator constraints */
99  SCIP_Bool* solcand, /**< values for indicator variables in partial solution */
100  int* nfoundsols /**< number of solutions found */
101  )
102 {
103  SCIP_Bool cutoff;
104  SCIP_Bool lperror;
105  SCIP_Bool stored;
106  SCIP_SOL* sol;
107  int cnt = 0;
108  int i;
109  int c;
110 
111  assert( scip != NULL );
112  assert( heur != NULL );
113  assert( heurdata != NULL );
114  assert( nindconss == 0 || indconss != NULL );
115  assert( solcand != NULL );
116  assert( nfoundsols != NULL );
117 
118  SCIPdebugMsg(scip, "Performing one-opt ...\n");
119  *nfoundsols = 0;
120 
121  SCIP_CALL( SCIPstartProbing(scip) );
122 
123  for (i = 0; i < nindconss && ! SCIPisStopped(scip); ++i)
124  {
125  SCIP_VAR* binvar;
126 
127  /* skip nonactive constraints */
128  if ( ! SCIPconsIsActive(indconss[i]) )
129  continue;
130 
131  binvar = SCIPgetBinaryVarIndicator(indconss[i]);
132  assert( binvar != NULL );
133 
134  /* skip constraints with fixed variables */
135  if ( SCIPvarGetUbLocal(binvar) < 0.5 || SCIPvarGetLbLocal(binvar) > 0.5 )
136  continue;
137 
138  /* return if the we would exceed the depth limit of the tree */
139  if( SCIP_MAXTREEDEPTH <= SCIPgetDepth(scip) )
140  break;
141 
142  if ( solcand[i] )
143  continue;
144 
145  /* get rid of all bound changes */
146  SCIP_CALL( SCIPnewProbingNode(scip) );
147  ++cnt;
148 
149  /* fix variables */
150  for (c = 0; c < nindconss; ++c)
151  {
152  SCIP_Bool s;
153 
154  /* skip nonactive constraints */
155  if ( ! SCIPconsIsActive(indconss[c]) )
156  continue;
157 
158  binvar = SCIPgetBinaryVarIndicator(indconss[c]);
159  assert( binvar != NULL );
160 
161  /* fix variables according to solution candidate, except constraint i */
162  if ( c == i )
163  s = ! solcand[c];
164  else
165  s = solcand[c];
166 
167  if ( ! s )
168  {
169  if ( SCIPvarGetLbLocal(binvar) < 0.5 && SCIPvarGetUbLocal(binvar) > 0.5 )
170  {
171  SCIP_CALL( SCIPchgVarLbProbing(scip, binvar, 1.0) );
172  }
173  }
174  else
175  {
176  if ( SCIPvarGetUbLocal(binvar) > 0.5 && SCIPvarGetLbLocal(binvar) < 0.5 )
177  {
178  SCIP_CALL( SCIPchgVarUbProbing(scip, binvar, 0.0) );
179  }
180  }
181  }
182 
183  /* propagate variables */
184  SCIP_CALL( SCIPpropagateProbing(scip, -1, &cutoff, NULL) );
185  if ( cutoff )
186  {
187  SCIP_CALL( SCIPbacktrackProbing(scip, 0) );
188  continue;
189  }
190 
191  /* solve LP to move continuous variables */
192  SCIP_CALL( SCIPsolveProbingLP(scip, -1, &lperror, &cutoff) );
193 
194  /* the LP often reaches the objective limit - we currently do not use such solutions */
195  if ( lperror || cutoff || SCIPgetLPSolstat(scip) != SCIP_LPSOLSTAT_OPTIMAL )
196  {
197 #ifdef SCIP_DEBUG
198  if ( lperror )
199  SCIPdebugMsg(scip, "An LP error occurred.\n");
200 #endif
201  SCIP_CALL( SCIPbacktrackProbing(scip, 0) );
202  continue;
203  }
204 
205  /* create solution */
206  SCIP_CALL( SCIPcreateSol(scip, &sol, heur) );
207 
208  /* copy the current LP solution to the working solution */
209  SCIP_CALL( SCIPlinkLPSol(scip, sol) );
210 
211  /* check solution for feasibility */
212  SCIPdebugMsg(scip, "One-opt found solution candidate with value %g.\n", SCIPgetSolTransObj(scip, sol));
213 
214  /* only check integrality, because we solved an LP */
215  SCIP_CALL( SCIPtrySolFree(scip, &sol, FALSE, FALSE, FALSE, TRUE, FALSE, &stored) );
216  if ( stored )
217  ++(*nfoundsols);
218  SCIP_CALL( SCIPbacktrackProbing(scip, 0) );
219  }
220  SCIP_CALL( SCIPendProbing(scip) );
221 
222  SCIPdebugMsg(scip, "Finished one-opt (tried variables: %d, found sols: %d).\n", cnt, *nfoundsols);
223 
224  return SCIP_OKAY;
225 }
226 
227 
228 /** try given solution */
229 static
231  SCIP* scip, /**< SCIP data structure */
232  SCIP_HEUR* heur, /**< indicator heuristic */
233  SCIP_HEURDATA* heurdata, /**< heuristic data */
234  int nindconss, /**< number of indicator constraints */
235  SCIP_CONS** indconss, /**< indicator constraints */
236  SCIP_Bool* solcand, /**< values for indicator variables in partial solution */
237  int* nfoundsols /**< number of solutions found */
238  )
239 {
240  SCIP_Bool cutoff;
241  SCIP_Bool lperror;
242  SCIP_Bool stored;
243  SCIP_SOL* sol;
244  int c;
245 
246  assert( scip != NULL );
247  assert( heur != NULL );
248  assert( heurdata != NULL );
249  assert( nindconss == 0 || indconss != NULL );
250  assert( solcand != NULL );
251  assert( nfoundsols != NULL );
252 
253  SCIPdebugMsg(scip, "Trying to generate feasible solution with indicators from solution candidate (obj: %f) ...\n", heurdata->obj);
254  *nfoundsols = 0;
255 
256  SCIP_CALL( SCIPstartProbing(scip) );
257 
258  /* we can stop here if we have already reached the maximal depth */
259  if( SCIP_MAXTREEDEPTH <= SCIPgetDepth(scip) )
260  {
261  SCIP_CALL( SCIPendProbing(scip) );
262  return SCIP_OKAY;
263  }
264 
265  SCIP_CALL( SCIPnewProbingNode(scip) );
266 
267  /* fix variables */
268  for (c = 0; c < nindconss; ++c)
269  {
270  SCIP_VAR* binvar;
271 
272  /* skip nonactive constraints */
273  if ( ! SCIPconsIsActive(indconss[c]) )
274  continue;
275 
276  binvar = SCIPgetBinaryVarIndicator(indconss[c]);
277  assert( binvar != NULL );
278 
279  /* Fix binary variables not in cover to 1 and corresponding slack variables to 0. The other binary variables are fixed to 0. */
280  if ( ! solcand[c] )
281  {
282  /* to be sure, check for non-fixed variables */
283  if ( SCIPvarGetLbLocal(binvar) < 0.5 && SCIPvarGetUbLocal(binvar) > 0.5 )
284  {
285  SCIP_CALL( SCIPchgVarLbProbing(scip, binvar, 1.0) );
286  }
287  }
288  else
289  {
290  if ( SCIPvarGetUbLocal(binvar) > 0.5 && SCIPvarGetLbLocal(binvar) < 0.5 )
291  {
292  SCIP_CALL( SCIPchgVarUbProbing(scip, binvar, 0.0) );
293  }
294  }
295  }
296 
297  /* propagate variables */
298  SCIP_CALL( SCIPpropagateProbing(scip, -1, &cutoff, NULL) );
299  if ( cutoff )
300  {
301  SCIPdebugMsg(scip, "Solution candidate reaches cutoff (in propagation).\n");
302  SCIP_CALL( SCIPendProbing(scip) );
303  return SCIP_OKAY;
304  }
305 
306  /* solve LP to move continuous variables */
307  SCIP_CALL( SCIPsolveProbingLP(scip, -1, &lperror, &cutoff) );
308 
309  /* the LP often reaches the objective limit - we currently do not use such solutions */
310  if ( lperror || cutoff || SCIPgetLPSolstat(scip) != SCIP_LPSOLSTAT_OPTIMAL )
311  {
312 #ifdef SCIP_DEBUG
313  if ( lperror )
314  {
315  SCIPdebugMsg(scip, "An LP error occurred.\n");
316  }
317  else
318  {
319  SCIPdebugMsg(scip, "Solution candidate reaches cutoff (in LP solving).\n");
320  }
321 #endif
322  SCIP_CALL( SCIPendProbing(scip) );
323  return SCIP_OKAY;
324  }
325 
326  /* create solution */
327  SCIP_CALL( SCIPcreateSol(scip, &sol, heur) );
328 
329  /* copy the current LP solution to the working solution */
330  SCIP_CALL( SCIPlinkLPSol(scip, sol) );
331 
332  /* check solution for feasibility */
333 #ifdef SCIP_DEBUG
334  SCIPdebugMsg(scip, "Found solution candidate with value %g.\n", SCIPgetSolTransObj(scip, sol));
335 #ifdef SCIP_MORE_DEBUG
336  SCIP_CALL( SCIPprintSol(scip, sol, NULL, FALSE) );
337 #endif
338  SCIP_CALL( SCIPtrySolFree(scip, &sol, TRUE, TRUE, TRUE, TRUE, TRUE, &stored) );
339  if ( stored )
340  {
341  ++(*nfoundsols);
342  SCIPdebugMsg(scip, "Solution is feasible and stored.\n");
343  }
344  else
345  SCIPdebugMsg(scip, "Solution was not stored.\n");
346 #else
347  /* only check integrality, because we solved an LP */
348  SCIP_CALL( SCIPtrySolFree(scip, &sol, FALSE, FALSE, FALSE, TRUE, FALSE, &stored) );
349  if ( stored )
350  ++(*nfoundsols);
351 #endif
352  SCIP_CALL( SCIPendProbing(scip) );
353 
354  /* possibly perform one-opt */
355  if ( stored && heurdata->oneopt )
356  {
357  int nfound = 0;
358  assert( *nfoundsols > 0 );
359  SCIP_CALL( tryOneOpt(scip, heur, heurdata, nindconss, indconss, solcand, &nfound) );
360  }
361 
362  return SCIP_OKAY;
363 }
364 
365 
366 /*
367  * Callback methods of primal heuristic
368  */
369 
370 /** copy method for primal heuristic plugins (called when SCIP copies plugins) */
371 static
372 SCIP_DECL_HEURCOPY(heurCopyIndicator)
373 { /*lint --e{715}*/
374  assert( scip != NULL );
375  assert( heur != NULL );
376  assert( strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0 );
377 
378  /* call inclusion method of primal heuristic */
380 
381  return SCIP_OKAY;
382 }
383 
384 /** initialization method of primal heuristic (called after problem was transformed) */
385 static
386 SCIP_DECL_HEURINIT(heurInitIndicator)
387 { /*lint --e{715}*/
388  SCIP_HEURDATA* heurdata;
389 
390  assert( heur != NULL );
391  assert( scip != NULL );
392 
393  /* get heuristic data */
394  heurdata = SCIPheurGetData(heur);
395  assert( heurdata != NULL );
396 
397  if ( heurdata->indicatorconshdlr == NULL )
398  {
399  heurdata->indicatorconshdlr = SCIPfindConshdlr(scip, "indicator");
400  if ( heurdata->indicatorconshdlr == NULL )
401  {
402  SCIPwarningMessage(scip, "Could not find indicator constraint handler.\n");
403  }
404  }
405 
406  return SCIP_OKAY;
407 }
408 
409 /** destructor of primal heuristic to free user data (called when SCIP is exiting) */
410 static
411 SCIP_DECL_HEURFREE(heurFreeIndicator)
412 { /*lint --e{715}*/
413  SCIP_HEURDATA* heurdata;
414 
415  assert( heur != NULL );
416  assert( scip != NULL );
417 
418  /* get heuristic data */
419  heurdata = SCIPheurGetData(heur);
420  assert( heurdata != NULL );
421 
422  SCIPfreeBlockMemoryArrayNull(scip, &(heurdata->indconss), heurdata->nindconss);
423  SCIPfreeBlockMemoryArrayNull(scip, &(heurdata->solcand), heurdata->nindconss);
424 
425  /* free heuristic data */
426  SCIPfreeBlockMemory(scip, &heurdata);
427  SCIPheurSetData(heur, NULL);
428 
429  return SCIP_OKAY;
430 }
431 
432 
433 /** execution method of primal heuristic */
434 static
435 SCIP_DECL_HEUREXEC(heurExecIndicator)
436 { /*lint --e{715}*/
437  SCIP_HEURDATA* heurdata;
438  int nfoundsols = 0;
439 
440  assert( heur != NULL );
441  assert( scip != NULL );
442  assert( result != NULL );
443 
444  *result = SCIP_DIDNOTRUN;
445 
446  if ( SCIPgetSubscipDepth(scip) > 0 )
447  return SCIP_OKAY;
448 
449  /* get heuristic's data */
450  heurdata = SCIPheurGetData(heur);
451  assert( heurdata != NULL );
452 
453  /* call heuristic, if solution candidate is available */
454  if ( heurdata->solcand != NULL )
455  {
456  assert( heurdata->nindconss > 0 );
457  assert( heurdata->indconss != NULL );
458 
459  /* The heuristic will only be successful if there are no integral variables and no binary variables except the
460  * indicator variables. */
461  if ( SCIPgetNIntVars(scip) > 0 || heurdata->nindconss < SCIPgetNBinVars(scip) )
462  return SCIP_OKAY;
463 
464  SCIP_CALL( trySolCandidate(scip, heur, heurdata, heurdata->nindconss, heurdata->indconss, heurdata->solcand, &nfoundsols) );
465 
466  if ( nfoundsols > 0 )
467  *result = SCIP_FOUNDSOL;
468  else
469  *result = SCIP_DIDNOTFIND;
470 
471  /* free memory */
472  SCIPfreeBlockMemoryArray(scip, &(heurdata->solcand), heurdata->nindconss);
473  SCIPfreeBlockMemoryArray(scip, &(heurdata->indconss), heurdata->nindconss);
474  }
475 
476  /* try to improve solutions generated by other heuristics */
477  if ( heurdata->improvesols )
478  {
479  SCIP_CONS** indconss;
480  SCIP_Bool* solcand;
481  SCIP_SOL* bestsol;
482  int nindconss;
483  int i;
484 
485  if ( heurdata->indicatorconshdlr == NULL )
486  return SCIP_OKAY;
487 
488  /* check whether a new best solution has been found */
489  bestsol = SCIPgetBestSol(scip);
490  if ( bestsol == heurdata->lastsol )
491  return SCIP_OKAY;
492  heurdata->lastsol = bestsol;
493 
494  /* avoid solutions produced by this heuristic */
495  if ( SCIPsolGetHeur(bestsol) == heur )
496  return SCIP_OKAY;
497 
498  /* The heuristic will only be successful if there are no integral variables and no binary variables except the
499  * indicator variables. */
500  nindconss = SCIPconshdlrGetNConss(heurdata->indicatorconshdlr);
501  if ( SCIPgetNIntVars(scip) > 0 || nindconss < SCIPgetNBinVars(scip) )
502  return SCIP_OKAY;
503 
504  if ( nindconss == 0 )
505  return SCIP_OKAY;
506 
507  indconss = SCIPconshdlrGetConss(heurdata->indicatorconshdlr);
508  assert( indconss != NULL );
509 
510  /* fill solution candidate */
511  SCIP_CALL( SCIPallocBufferArray(scip, &solcand, nindconss) );
512  for (i = 0; i < nindconss; ++i)
513  {
514  SCIP_VAR* binvar;
515  SCIP_Real val;
516 
517  solcand[i] = FALSE;
518  if ( SCIPconsIsActive(indconss[i]) )
519  {
520  binvar = SCIPgetBinaryVarIndicator(indconss[i]);
521  assert( binvar != NULL );
522 
523  val = SCIPgetSolVal(scip, bestsol, binvar);
524  assert( SCIPisFeasIntegral(scip, val) );
525  if ( val > 0.5 )
526  solcand[i] = TRUE;
527  }
528  }
529 
530  SCIPdebugMsg(scip, "Trying to improve best solution of value %f.\n", SCIPgetSolOrigObj(scip, bestsol) );
531 
532  /* try one-opt heuristic */
533  SCIP_CALL( tryOneOpt(scip, heur, heurdata, nindconss, indconss, solcand, &nfoundsols) );
534 
535  if ( nfoundsols > 0 )
536  *result = SCIP_FOUNDSOL;
537  else
538  *result = SCIP_DIDNOTFIND;
539 
540  SCIPfreeBufferArray(scip, &solcand);
541  }
542 
543  return SCIP_OKAY;
544 }
545 
546 
547 /*
548  * primal heuristic specific interface methods
549  */
550 
551 /** creates the indicator primal heuristic and includes it in SCIP */
553  SCIP* scip /**< SCIP data structure */
554  )
555 {
556  SCIP_HEURDATA* heurdata;
557  SCIP_HEUR* heur;
558 
559  /* create Indicator primal heuristic data */
560  SCIP_CALL( SCIPallocBlockMemory(scip, &heurdata) );
561  heurdata->nindconss = 0;
562  heurdata->indconss = NULL;
563  heurdata->solcand = NULL;
564  heurdata->lastsol = NULL;
565  heurdata->indicatorconshdlr = NULL;
566  heurdata->obj = SCIPinfinity(scip);
567 
568  /* include primal heuristic */
569  SCIP_CALL( SCIPincludeHeurBasic(scip, &heur,
571  HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecIndicator, heurdata) );
572 
573  assert( heur != NULL );
574 
575  /* set non-NULL pointers to callback methods */
576  SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyIndicator) );
577  SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitIndicator) );
578  SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeIndicator) );
579 
580  /* add parameters */
582  "heuristics/" HEUR_NAME "/oneopt",
583  "whether the one-opt heuristic should be started",
584  &heurdata->oneopt, TRUE, DEFAULT_ONEOPT, NULL, NULL) );
585 
587  "heuristics/" HEUR_NAME "/improvesols",
588  "Try to improve other solutions by one-opt?",
589  &heurdata->improvesols, TRUE, DEFAULT_IMPROVESOLS, NULL, NULL) );
590 
591  return SCIP_OKAY;
592 }
593 
594 
595 /** pass partial solution for indicator variables to heuristic */
597  SCIP* scip, /**< SCIP data structure */
598  SCIP_HEUR* heur, /**< indicator heuristic */
599  int nindconss, /**< number of indicator constraints */
600  SCIP_CONS** indconss, /**< indicator constraints */
601  SCIP_Bool* solcand, /**< values for indicator variables in partial solution */
602  SCIP_Real obj /**< objective of solution */
603  )
604 {
605  SCIP_HEURDATA* heurdata;
606 
607  assert( scip != NULL );
608  assert( heur != NULL );
609  assert( strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0 );
610  assert( nindconss > 0 );
611  assert( indconss != NULL );
612  assert( solcand != NULL );
613 
614  /* get heuristic's data */
615  heurdata = SCIPheurGetData(heur);
616  assert( heurdata != NULL );
617 
618  if ( obj >= heurdata->obj )
619  return SCIP_OKAY;
620 
621  /* copy indicator information */
622  if ( heurdata->indconss != NULL )
623  SCIPfreeBlockMemoryArray(scip, &(heurdata->indconss), heurdata->nindconss);
624 
625  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(heurdata->indconss), indconss, nindconss) );
626  heurdata->nindconss = nindconss;
627 
628  /* copy partial solution */
629  if ( heurdata->solcand != NULL )
630  BMScopyMemoryArray(heurdata->solcand, solcand, nindconss);
631  else
632  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(heurdata->solcand), solcand, nindconss) );
633  heurdata->obj = obj;
634 
635  return SCIP_OKAY;
636 }
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:110
int SCIPgetNIntVars(SCIP *scip)
Definition: scip_prob.c:2082
SCIP_RETCODE SCIPlinkLPSol(SCIP *scip, SCIP_SOL *sol)
Definition: scip_sol.c:882
#define NULL
Definition: def.h:267
SCIP_RETCODE SCIPincludeHeurIndicator(SCIP *scip)
static SCIP_DECL_HEURCOPY(heurCopyIndicator)
public methods for SCIP parameter handling
SCIP_RETCODE SCIPbacktrackProbing(SCIP *scip, int probingdepth)
Definition: scip_probing.c:225
public methods for memory management
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition: scip_cons.c:941
SCIP_RETCODE SCIPheurPassIndicator(SCIP *scip, SCIP_HEUR *heur, int nindconss, SCIP_CONS **indconss, SCIP_Bool *solcand, SCIP_Real obj)
#define HEUR_DESC
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:18135
constraint handler for indicator constraints
static SCIP_DECL_HEURINIT(heurInitIndicator)
SCIP_CONS ** SCIPconshdlrGetConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4595
#define FALSE
Definition: def.h:94
int SCIPgetSubscipDepth(SCIP *scip)
Definition: scip_copy.c:2605
SCIP_Real SCIPinfinity(SCIP *scip)
#define TRUE
Definition: def.h:93
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
struct SCIP_HeurData SCIP_HEURDATA
Definition: type_heur.h:77
public methods for problem variables
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip_mem.h:108
SCIP_RETCODE SCIPincludeHeurBasic(SCIP *scip, SCIP_HEUR **heur, const char *name, const char *desc, char dispchar, int priority, int freq, int freqofs, int maxdepth, SCIP_HEURTIMING timingmask, SCIP_Bool usessubscip, SCIP_DECL_HEUREXEC((*heurexec)), SCIP_HEURDATA *heurdata)
Definition: scip_heur.c:117
SCIP_RETCODE SCIPchgVarLbProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_probing.c:301
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:136
void SCIPheurSetData(SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
Definition: heur.c:1374
#define HEUR_MAXDEPTH
#define SCIPallocBlockMemory(scip, ptr)
Definition: scip_mem.h:89
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:120
#define SCIPdebugMsg
Definition: scip_message.h:78
SCIP_Bool SCIPconsIsActive(SCIP_CONS *cons)
Definition: cons.c:8277
public methods for numerical tolerances
static SCIP_DECL_HEURFREE(heurFreeIndicator)
public methods for the branch-and-bound tree
#define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
Definition: scip_mem.h:105
#define HEUR_DISPCHAR
public methods for managing constraints
const char * SCIPheurGetName(SCIP_HEUR *heur)
Definition: heur.c:1453
#define HEUR_TIMING
#define DEFAULT_ONEOPT
SCIP_RETCODE SCIPsetHeurFree(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURFREE((*heurfree)))
Definition: scip_heur.c:178
SCIP_RETCODE SCIPpropagateProbing(SCIP *scip, int maxproprounds, SCIP_Bool *cutoff, SCIP_Longint *ndomredsfound)
Definition: scip_probing.c:580
#define HEUR_PRIORITY
SCIP_RETCODE SCIPendProbing(SCIP *scip)
Definition: scip_probing.c:260
SCIP_HEUR * SCIPsolGetHeur(SCIP_SOL *sol)
Definition: sol.c:2804
SCIP_Real SCIPgetSolTransObj(SCIP *scip, SCIP_SOL *sol)
Definition: scip_sol.c:1347
public methods for problem copies
public methods for primal CIP solutions
#define DEFAULT_IMPROVESOLS
#define HEUR_NAME
handle partial solutions for linear problems with indicators and otherwise continuous variables ...
#define SCIP_CALL(x)
Definition: def.h:380
SCIP_RETCODE SCIPsolveProbingLP(SCIP *scip, int itlim, SCIP_Bool *lperror, SCIP_Bool *cutoff)
Definition: scip_probing.c:819
public methods for primal heuristic plugins and divesets
int SCIPconshdlrGetNConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4638
public methods for constraint handler plugins and constraints
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:124
#define SCIP_Bool
Definition: def.h:91
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
Definition: scip_lp.c:168
int SCIPgetDepth(SCIP *scip)
Definition: scip_tree.c:670
SCIP_RETCODE SCIPtrySolFree(SCIP *scip, SCIP_SOL **sol, SCIP_Bool printreason, SCIP_Bool completely, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *stored)
Definition: scip_sol.c:3050
#define BMScopyMemoryArray(ptr, source, num)
Definition: memory.h:134
SCIP_Real SCIPgetSolOrigObj(SCIP *scip, SCIP_SOL *sol)
Definition: scip_sol.c:1300
SCIP_VAR * SCIPgetBinaryVarIndicator(SCIP_CONS *cons)
#define SCIP_MAXTREEDEPTH
Definition: def.h:316
int SCIPgetNBinVars(SCIP *scip)
Definition: scip_prob.c:2037
public methods for the LP relaxation, rows and columns
static SCIP_RETCODE tryOneOpt(SCIP *scip, SCIP_HEUR *heur, SCIP_HEURDATA *heurdata, int nindconss, SCIP_CONS **indconss, SCIP_Bool *solcand, int *nfoundsols)
general public methods
SCIP_SOL * SCIPgetBestSol(SCIP *scip)
Definition: scip_sol.c:2169
public methods for solutions
public methods for the probing mode
public methods for message output
SCIP_RETCODE SCIPsetHeurInit(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURINIT((*heurinit)))
Definition: scip_heur.c:194
#define SCIP_Real
Definition: def.h:173
SCIP_Bool SCIPisStopped(SCIP *scip)
Definition: scip_general.c:718
public methods for message handling
static SCIP_RETCODE trySolCandidate(SCIP *scip, SCIP_HEUR *heur, SCIP_HEURDATA *heurdata, int nindconss, SCIP_CONS **indconss, SCIP_Bool *solcand, int *nfoundsols)
#define HEUR_FREQ
SCIP_RETCODE SCIPsetHeurCopy(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURCOPY((*heurcopy)))
Definition: scip_heur.c:162
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:18145
#define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
Definition: scip_mem.h:111
SCIP_RETCODE SCIPnewProbingNode(SCIP *scip)
Definition: scip_probing.c:165
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
SCIP_RETCODE SCIPstartProbing(SCIP *scip)
Definition: scip_probing.c:119
public methods for primal heuristics
SCIP_HEURDATA * SCIPheurGetData(SCIP_HEUR *heur)
Definition: heur.c:1364
#define HEUR_USESSUBSCIP
static SCIP_DECL_HEUREXEC(heurExecIndicator)
public methods for global and local (sub)problems
SCIP_RETCODE SCIPchgVarUbProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_probing.c:345
#define HEUR_FREQOFS
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip_sol.c:1217
SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip_param.c:57
SCIP_RETCODE SCIPcreateSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
Definition: scip_sol.c:184
memory allocation routines
SCIP_RETCODE SCIPprintSol(SCIP *scip, SCIP_SOL *sol, FILE *file, SCIP_Bool printzeros)
Definition: scip_sol.c:1631