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