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