Scippy

SCIP

Solving Constraint Integer Programs

objbenders.h
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 2002-2022 Zuse Institute Berlin */
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 objbenders.h
26  * @brief C++ wrapper for Benders' decomposition
27  * @author Stephen J. Maher
28  */
29 
30 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
31 
32 #ifndef __SCIP_OBJBENDERS_H__
33 #define __SCIP_OBJBENDERS_H__
34 
35 
36 #include <cassert>
37 #include <cstring>
38 #include <utility>
39 
40 #include "scip/scip.h"
41 #include "objscip/objcloneable.h"
42 
43 namespace scip
44 {
45 
46 /**
47  * @brief C++ wrapper for Benders' decomposition plugins
48  *
49  * This class defines the interface for the Benders' decomposition framework implemented in C++. Note that there
50  * are pure virtual functions (these have to be implemented). These functions are: benders_exec(), benders_createsub(),
51  * benders_getvar().
52  *
53  * - \ref BENDER "Instructions for implementing a Benders' decomposition plugin"
54  * - \ref BENDERS "List of available Benders' decomposition plugins"
55  * - \ref type_benders.h "Corresponding C interface"
56  */
57 class ObjBenders : public ObjCloneable
58 {
59 public:
60  /*lint --e{1540}*/
61 
62  /** SCIP data structure */
64 
65  /** name of the Benders' decomposition */
66  char* scip_name_;
67 
68  /** description of the Benders' decomposition */
69  char* scip_desc_;
70 
71  /** the priority of the Benders' decomposition */
72  const int scip_priority_;
73 
74  /** should cuts be generated from the LP solution */
76 
77  /** should cuts be generated from the pseudo solution */
79 
80  /** should cuts be generated from the relaxation solution */
82 
83  /** should this Benders' decomposition share the auxiliary variables from the highest priority Benders? */
85 
86  /** default constructor */
88  SCIP* scip, /**< SCIP data structure */
89  const char* name, /**< name of Benders' decomposition */
90  const char* desc, /**< description of Benders' decomposition */
91  int priority, /**< priority of the Benders' decomposition */
92  SCIP_Bool cutlp, /**< should Benders' cuts be generated for LP solutions */
93  SCIP_Bool cutpseudo, /**< should Benders' cuts be generated for pseudo solutions */
94  SCIP_Bool cutrelax, /**< should Benders' cuts be generated for relaxation solutions */
95  SCIP_Bool shareauxvars /**< should this Benders' use the highest priority Benders' aux vars */
96  )
97  : scip_(scip),
98  scip_name_(0),
99  scip_desc_(0),
100  scip_priority_(priority),
101  scip_cutlp_(cutlp),
102  scip_cutpseudo_(cutpseudo),
103  scip_cutrelax_(cutrelax),
104  scip_shareauxvars_(shareauxvars)
105  {
106  /* the macro SCIPduplicateMemoryArray does not need the first argument: */
107  SCIP_CALL_ABORT( SCIPduplicateMemoryArray(scip_, &scip_name_, name, std::strlen(name)+1) );
108  SCIP_CALL_ABORT( SCIPduplicateMemoryArray(scip_, &scip_desc_, desc, std::strlen(desc)+1) );
109  }
110 
111  /** copy constructor */
113  : ObjBenders(o.scip_, o.scip_name_, o.scip_desc_, o.scip_priority_, o.scip_cutlp_, o.scip_cutpseudo_,
114  o.scip_cutrelax_, o.scip_shareauxvars_)
115  {
116  }
117 
118  /** move constructor */
120  : scip_(o.scip_),
121  scip_name_(0),
122  scip_desc_(0),
123  scip_priority_(o.scip_priority_),
124  scip_cutlp_(o.scip_cutlp_),
125  scip_cutpseudo_(o.scip_cutpseudo_),
126  scip_cutrelax_(o.scip_cutrelax_),
127  scip_shareauxvars_(o.scip_shareauxvars_)
128  {
129  std::swap(scip_name_, o.scip_name_);
130  std::swap(scip_desc_, o.scip_desc_);
131  }
132 
133  /** destructor */
134  virtual ~ObjBenders()
135  {
136  /* the macro SCIPfreeMemoryArray does not need the first argument: */
137  /*lint --e{64}*/
138  SCIPfreeMemoryArray(scip_, &scip_name_);
139  SCIPfreeMemoryArray(scip_, &scip_desc_);
140  }
141 
142  /** assignment of polymorphic classes causes slicing and is therefore disabled. */
143  ObjBenders& operator=(const ObjBenders& o) = delete;
144 
145  /** assignment of polymorphic classes causes slicing and is therefore disabled. */
146  ObjBenders& operator=(ObjBenders&& o) = delete;
147 
148  /** copy method for benders plugins (called when SCIP copies plugins)
149  *
150  * @see SCIP_DECL_BENDERSCOPY(x) in @ref type_benders.h
151  */
152  virtual SCIP_DECL_BENDERSCOPY(scip_copy)
153  { /*lint --e{715}*/
154  return SCIP_OKAY;
155  }
156 
157  /** destructor of variable benders to free user data (called when SCIP is exiting)
158  *
159  * @see SCIP_DECL_BENDERSFREE(x) in @ref type_benders.h
160  */
161  virtual SCIP_DECL_BENDERSFREE(scip_free)
162  { /*lint --e{715}*/
163  return SCIP_OKAY;
164  }
165 
166  /** initialization method of variable benders (called after problem was transformed and benders is active)
167  *
168  * @see SCIP_DECL_BENDERSINIT(x) in @ref type_benders.h
169  */
170  virtual SCIP_DECL_BENDERSINIT(scip_init)
171  { /*lint --e{715}*/
172  return SCIP_OKAY;
173  }
174 
175  /** deinitialization method of variable benders (called before transformed problem is freed and benders is active)
176  *
177  * @see SCIP_DECL_BENDERSEXIT(x) in @ref type_benders.h
178  */
179  virtual SCIP_DECL_BENDERSEXIT(scip_exit)
180  { /*lint --e{715}*/
181  return SCIP_OKAY;
182  }
183 
184  /** presolving initialization method of constraint handler (called when presolving is about to begin)
185  *
186  * @see SCIP_DECL_BENDERSINITPRE(x) in @ref type_benders.h
187  */
188  virtual SCIP_DECL_BENDERSINITPRE(scip_initpre)
189  { /*lint --e{715}*/
190  return SCIP_OKAY;
191  }
192 
193  /** presolving deinitialization method of constraint handler (called after presolving has been finished)
194  *
195  * @see SCIP_DECL_BENDERSEXITPRE(x) in @ref type_benders.h
196  */
197  virtual SCIP_DECL_BENDERSEXITPRE(scip_exitpre)
198  { /*lint --e{715}*/
199  return SCIP_OKAY;
200  }
201 
202  /** solving process initialization method of variable benders (called when branch and bound process is about to begin)
203  *
204  * @see SCIP_DECL_BENDERSINITSOL(x) in @ref type_benders.h
205  */
206  virtual SCIP_DECL_BENDERSINITSOL(scip_initsol)
207  { /*lint --e{715}*/
208  return SCIP_OKAY;
209  }
210 
211  /** solving process deinitialization method of variable benders (called before branch and bound process data is freed)
212  *
213  * @see SCIP_DECL_BENDERSEXITSOL(x) in @ref type_benders.h
214  */
215  virtual SCIP_DECL_BENDERSEXITSOL(scip_exitsol)
216  { /*lint --e{715}*/
217  return SCIP_OKAY;
218  }
219 
220  /** the method for creating the Benders' decomposition subproblem. This method is called during the initialisation stage
221  * (after the master problem was transformed)
222  *
223  * @see SCIP_DECL_BENDERSCREATESUB(x) in @ref type_benders.h
224  */
225  virtual SCIP_DECL_BENDERSCREATESUB(scip_createsub) = 0;
226 
227  /** called before the subproblem solving loop for Benders' decomposition. The pre subproblem solve function gives the
228  * user an oppportunity to perform any global set up for the Benders' decomposition.
229  *
230  * @see SCIP_DECL_BENDERSPRESUBSOLVE(x) in @ref type_benders.h
231  */
232  virtual SCIP_DECL_BENDERSPRESUBSOLVE(scip_presubsolve)
233  { /*lint --e{715}*/
234  return SCIP_OKAY;
235  }
236 
237  /** the solving method for a single convex Benders' decomposition subproblem. The solving methods are separated so
238  * that they can be called in parallel.
239  *
240  * @see SCIP_DECL_BENDERSSOLVESUBCONVEX(x) in @ref type_benders.h
241  */
242  virtual SCIP_DECL_BENDERSSOLVESUBCONVEX(scip_solvesubconvex)
243  { /*lint --e{715}*/
244  return SCIP_OKAY;
245  }
246 
247  /** the solving method for a single Benders' decomposition subproblem. The solving methods are separated so that they
248  * can be called in parallel.
249  *
250  * @see SCIP_DECL_BENDERSSOLVESUB(x) in @ref type_benders.h
251  */
252  virtual SCIP_DECL_BENDERSSOLVESUB(scip_solvesub)
253  { /*lint --e{715}*/
254  return SCIP_OKAY;
255  }
256 
257  /** the post-solve method for Benders' decomposition. The post-solve method is called after the subproblems have
258  * been solved but before they are freed.
259  * @see SCIP_DECL_BENDERSPOSTSOLVE(x) in @ref type_benders.h
260  */
261  virtual SCIP_DECL_BENDERSPOSTSOLVE(scip_postsolve)
262  { /*lint --e{715}*/
263  return SCIP_OKAY;
264  }
265 
266  /** frees the subproblem so that it can be resolved in the next iteration. In the SCIP case, this involves freeing the
267  * transformed problem using SCIPfreeTransform()
268  *
269  * @see SCIP_DECL_BENDERSFREESUB(x) in @ref type_benders.h
270  */
271  virtual SCIP_DECL_BENDERSFREESUB(scip_freesub)
272  { /*lint --e{715}*/
273  return SCIP_OKAY;
274  }
275 
276  /** the variable mapping from the subproblem to the master problem.
277  *
278  * @see SCIP_DECL_BENDERSGETVAR(x) in @ref type_benders.h
279  */
280  virtual SCIP_DECL_BENDERSGETVAR(scip_getvar) = 0;
281 
282 };
283 
284 } /* namespace scip */
285 
286 
287 
288 /** creates the Benders' decomposition for the given Benders' decomposition object and includes it in SCIP
289  *
290  * The method should be called in one of the following ways:
291  *
292  * 1. The user is resposible of deleting the object:
293  * SCIP_CALL( SCIPcreate(&scip) );
294  * ...
295  * MyBenders* mybenders = new MyBenders(...);
296  * SCIP_CALL( SCIPincludeObjBenders(scip, &mybenders, FALSE) );
297  * ...
298  * SCIP_CALL( SCIPfree(&scip) );
299  * delete mybenders; // delete benders AFTER SCIPfree() !
300  *
301  * 2. The object pointer is passed to SCIP and deleted by SCIP in the SCIPfree() call:
302  * SCIP_CALL( SCIPcreate(&scip) );
303  * ...
304  * SCIP_CALL( SCIPincludeObjBenders(scip, new MyBenders(...), TRUE) );
305  * ...
306  * SCIP_CALL( SCIPfree(&scip) ); // destructor of MyBenders is called here
307  */
308 SCIP_EXPORT
310  SCIP* scip, /**< SCIP data structure */
311  scip::ObjBenders* objbenders, /**< Benders' decomposition object */
312  SCIP_Bool deleteobject /**< should the Benders' decomposition object be deleted when benders is freed? */
313  );
314 
315 /** returns the benders object of the given name, or 0 if not existing */
316 SCIP_EXPORT
318  SCIP* scip, /**< SCIP data structure */
319  const char* name /**< name of Benders' decomposition */
320  );
321 
322 /** returns the benders object for the given constraint handler */
323 SCIP_EXPORT
325  SCIP* scip, /**< SCIP data structure */
326  SCIP_BENDERS* benders /**< Benders' decomposition */
327  );
328 
329 #endif
virtual SCIP_DECL_BENDERSCOPY(scip_copy)
Definition: objbenders.h:152
ObjBenders(const ObjBenders &o)
Definition: objbenders.h:112
virtual SCIP_DECL_BENDERSCREATESUB(scip_createsub)=0
virtual SCIP_DECL_BENDERSINIT(scip_init)
Definition: objbenders.h:170
virtual SCIP_DECL_BENDERSPRESUBSOLVE(scip_presubsolve)
Definition: objbenders.h:232
#define SCIPduplicateMemoryArray(scip, ptr, source, num)
Definition: scip_mem.h:76
#define SCIPfreeMemoryArray(scip, ptr)
Definition: scip_mem.h:80
const SCIP_Bool scip_shareauxvars_
Definition: objbenders.h:84
virtual SCIP_DECL_BENDERSSOLVESUB(scip_solvesub)
Definition: objbenders.h:252
char * scip_name_
Definition: objbenders.h:66
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
virtual SCIP_DECL_BENDERSFREESUB(scip_freesub)
Definition: objbenders.h:271
scip::ObjBenders * SCIPfindObjBenders(SCIP *scip, const char *name)
Definition: objbenders.cpp:373
virtual SCIP_DECL_BENDERSINITPRE(scip_initpre)
Definition: objbenders.h:188
virtual SCIP_DECL_BENDERSEXIT(scip_exit)
Definition: objbenders.h:179
ObjBenders & operator=(const ObjBenders &o)=delete
definition of base class for all clonable classes
C++ wrapper for Benders&#39; decomposition plugins.
Definition: objbenders.h:57
char * scip_desc_
Definition: objbenders.h:69
SCIP_RETCODE SCIPincludeObjBenders(SCIP *scip, scip::ObjBenders *objbenders, SCIP_Bool deleteobject)
Definition: objbenders.cpp:344
virtual SCIP_DECL_BENDERSEXITSOL(scip_exitsol)
Definition: objbenders.h:215
ObjBenders(ObjBenders &&o)
Definition: objbenders.h:119
const int scip_priority_
Definition: objbenders.h:72
virtual SCIP_DECL_BENDERSGETVAR(scip_getvar)=0
#define SCIP_Bool
Definition: def.h:93
virtual SCIP_DECL_BENDERSPOSTSOLVE(scip_postsolve)
Definition: objbenders.h:261
virtual ~ObjBenders()
Definition: objbenders.h:134
ObjBenders(SCIP *scip, const char *name, const char *desc, int priority, SCIP_Bool cutlp, SCIP_Bool cutpseudo, SCIP_Bool cutrelax, SCIP_Bool shareauxvars)
Definition: objbenders.h:87
const SCIP_Bool scip_cutpseudo_
Definition: objbenders.h:78
const SCIP_Bool scip_cutlp_
Definition: objbenders.h:75
Definition of base class for all clonable classes.
Definition: objcloneable.h:47
virtual SCIP_DECL_BENDERSEXITPRE(scip_exitpre)
Definition: objbenders.h:197
virtual SCIP_DECL_BENDERSSOLVESUBCONVEX(scip_solvesubconvex)
Definition: objbenders.h:242
scip::ObjBenders * SCIPgetObjBenders(SCIP *scip, SCIP_BENDERS *benders)
Definition: objbenders.cpp:392
virtual SCIP_DECL_BENDERSINITSOL(scip_initsol)
Definition: objbenders.h:206
#define SCIP_CALL_ABORT(x)
Definition: def.h:372
virtual SCIP_DECL_BENDERSFREE(scip_free)
Definition: objbenders.h:161
SCIP callable library.
const SCIP_Bool scip_cutrelax_
Definition: objbenders.h:81