1    	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2    	/*                                                                           */
3    	/*                  This file is part of the program and library             */
4    	/*         SCIP --- Solving Constraint Integer Programs                      */
5    	/*                                                                           */
6    	/*  Copyright (c) 2002-2023 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   objbenderscut.h
26   	 * @brief  C++ wrapper for Benders' decomposition cuts
27   	 * @author Stephen J. Maher
28   	 */
29   	
30   	/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
31   	
32   	#ifndef __SCIP_OBJBENDERSCUT_H__
33   	#define __SCIP_OBJBENDERSCUT_H__
34   	
35   	
36   	#include <cassert>
37   	#include <cstring>
38   	#include <utility>
39   	
40   	#include "scip/scip.h"
41   	#include "objscip/objcloneable.h"
42   	#include "objscip/objbenders.h"
43   	
44   	namespace scip
45   	{
46   	
47   	/** @brief C++ wrapper for Benders' decomposition cut
48   	 *
49   	 *  This class defines the interface for the Benders' decomposition cuts implemented in C++. Note that there is
50   	 *  a pure virtual function (this must be implemented). This function is: benderscut_exec().
51   	 *
52   	 *  - \ref BENDERSCUT "Instructions for implementing a Benders' decomposition plugin"
53   	 *  - \ref BENDERSCUTS "List of available Benders' decomposition plugins"
54   	 *  - \ref type_benderscut.h "Corresponding C interface"
55   	 */
56   	class ObjBenderscut : public ObjCloneable
57   	{
58   	public:
59   	   /*lint --e{1540}*/
60   	
61   	   /** SCIP data structure */
62   	   SCIP* scip_;
63   	
64   	   /** name of the Benders' decomposition cut */
65   	   char* scip_name_;
66   	
67   	   /** description of the Benders' decomposition cut */
68   	   char* scip_desc_;
69   	
70   	   /** the priority of the Benders' decomposition cut */
71   	   const int scip_priority_;
72   	
73   	   /** is the Benders' decomposition cut generated from the LP relaxation of the subproblem */
74   	   const SCIP_Bool scip_islpcut_;
75   	
76   	   /** default constructor */
77   	   ObjBenderscut(
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          islpcut             /**< is the cut generated from the LP relaxation */
83   	      )
84   	      : scip_(scip),
85   	        scip_name_(0),
86   	        scip_desc_(0),
87   	        scip_priority_(priority),
88   	        scip_islpcut_(islpcut)
89   	   {
90   	      /* the macro SCIPduplicateMemoryArray does not need the first argument: */
91   	      SCIP_CALL_ABORT( SCIPduplicateMemoryArray(scip_, &scip_name_, name, std::strlen(name)+1) );
92   	      SCIP_CALL_ABORT( SCIPduplicateMemoryArray(scip_, &scip_desc_, desc, std::strlen(desc)+1) );
93   	   }
94   	
95   	   /** copy constructor */
96   	   ObjBenderscut(const ObjBenderscut& o)
97   	       : ObjBenderscut(o.scip_, o.scip_name_, o.scip_desc_, o.scip_priority_, o.scip_islpcut_)
98   	   {
99   	   }
100  	
101  	   /** move constructor */
102  	   ObjBenderscut(ObjBenderscut&& o)
103  	       : scip_(o.scip_), scip_name_(0), scip_desc_(0), scip_priority_(o.scip_priority_), scip_islpcut_(o.scip_islpcut_)
104  	   {
105  	      std::swap(scip_name_, o.scip_name_);
106  	      std::swap(scip_desc_, o.scip_desc_);
107  	   }
108  	
109  	   /** destructor */
110  	   virtual ~ObjBenderscut()
111  	   {
112  	      /* the macro SCIPfreeMemoryArray does not need the first argument: */
113  	      /*lint --e{64}*/
114  	      SCIPfreeMemoryArray(scip_, &scip_name_);
115  	      SCIPfreeMemoryArray(scip_, &scip_desc_);
116  	   }
117  	
118  	   /** assignment of polymorphic classes causes slicing and is therefore disabled. */
119  	   ObjBenderscut& operator=(const ObjBenderscut& o) = delete;
120  	
121  	   /** assignment of polymorphic classes causes slicing and is therefore disabled. */
122  	   ObjBenderscut& operator=(ObjBenderscut&& o) = delete;
123  	
124  	   /** copy method for compression plugins (called when SCIP copies plugins)
125  	    *
126  	    *  @see SCIP_DECL_BENDERSCUTCOPY(x) in @ref type_benders.h
127  	    */
128  	   virtual SCIP_DECL_BENDERSCUTCOPY(scip_copy)
129  	   {  /*lint --e{715}*/
130  	      return SCIP_OKAY;
131  	   }
132  	
133  	   /** destructor of Benders' decomposition cuts to free user data (called when SCIP is exiting)
134  	    *
135  	    *  @see SCIP_DECL_BENDERSCUTFREE(x) in @ref type_benders.h
136  	    */
137  	   virtual SCIP_DECL_BENDERSCUTFREE(scip_free)
138  	   {  /*lint --e{715}*/
139  	      return SCIP_OKAY;
140  	   }
141  	
142  	   /** initialization method of Benders' decomposition cuts (called after problem was transformed)
143  	    *
144  	    *  @see SCIP_DECL_BENDERSCUTINIT(x) in @ref type_benders.h
145  	    */
146  	   virtual SCIP_DECL_BENDERSCUTINIT(scip_init)
147  	   {  /*lint --e{715}*/
148  	      return SCIP_OKAY;
149  	   }
150  	
151  	   /** deinitialization method of Benders' decomposition cuts (called before transformed problem is freed)
152  	    *
153  	    *  @see SCIP_DECL_BENDERSCUTEXIT(x) in @ref type_benders.h
154  	    */
155  	   virtual SCIP_DECL_BENDERSCUTEXIT(scip_exit)
156  	   {  /*lint --e{715}*/
157  	      return SCIP_OKAY;
158  	   }
159  	
160  	   /** solving process initialization method of Benders' decomposition cuts (called when branch and bound process is about to begin)
161  	    *
162  	    *  @see SCIP_DECL_BENDERSCUTINITSOL(x) in @ref type_benders.h
163  	    */
164  	   virtual SCIP_DECL_BENDERSCUTINITSOL(scip_initsol)
165  	   {  /*lint --e{715}*/
166  	      return SCIP_OKAY;
167  	   }
168  	
169  	   /** solving process deinitialization method of Benders' decomposition cuts (called before branch and bound process data is freed)
170  	    *
171  	    *  This method is called before the branch and bound process is freed.
172  	    *  The Benders' decomposition cuts should use this call to clean up its branch and bound data.
173  	    *
174  	    *  @see SCIP_DECL_BENDERSCUTEXITSOL(x) in @ref type_benders.h
175  	    */
176  	   virtual SCIP_DECL_BENDERSCUTEXITSOL(scip_exitsol)
177  	   {  /*lint --e{715}*/
178  	      return SCIP_OKAY;
179  	   }
180  	
181  	   /** execution method of Benders' decomposition cuts technique
182  	    *
183  	    *  @see SCIP_DECL_BENDERSCUTEXEC(x) in @ref type_benders.h
184  	    */
185  	   virtual SCIP_DECL_BENDERSCUTEXEC(scip_exec) = 0;
186  	};
187  	
188  	} /* namespace scip */
189  	
190  	
191  	
192  	/** creates the Benders' decomposition cut for the given Benders' decomposition cut object and includes it in SCIP
193  	 *
194  	 *  The method should be called in one of the following ways:
195  	 *
196  	 *   1. The user is responsible for deleting the object:
197  	 *       SCIP_CALL( SCIPcreate(&scip) );
198  	 *       ...
199  	 *       MyBenderscut* mybenderscut = new MyBenderscut(...);
200  	 *       SCIP_CALL( SCIPincludeObjBenderscut(scip, benders, &mybenderscut, FALSE) );
201  	 *       ...
202  	 *       SCIP_CALL( SCIPfree(&scip) );
203  	 *       delete mybenderscut;    // delete benderscut AFTER SCIPfree() !
204  	 *
205  	 *   2. The object pointer is passed to SCIP and deleted by SCIP in the SCIPfree() call:
206  	 *       SCIP_CALL( SCIPcreate(&scip) );
207  	 *       ...
208  	 *       SCIP_CALL( SCIPincludeObjBenderscut(scip, benders, new MyBenderscut(...), TRUE) );
209  	 *       ...
210  	 *       SCIP_CALL( SCIPfree(&scip) );  // destructor of MyBenderscut is called here
211  	 */
212  	SCIP_EXPORT
213  	SCIP_RETCODE SCIPincludeObjBenderscut(
214  	   SCIP*                 scip,               /**< SCIP data structure */
215  	   scip::ObjBenders*     objbenders,         /**< Benders' decomposition object */
216  	   scip::ObjBenderscut*  objbenderscut,      /**< Benders' decomposition cut object */
217  	   SCIP_Bool             deleteobject        /**< should the Benders' cut object be deleted when benderscut is freed? */
218  	   );
219  	
220  	/** returns the benderscut object of the given name, or 0 if not existing */
221  	SCIP_EXPORT
222  	scip::ObjBenderscut* SCIPfindObjBenderscut(
223  	   scip::ObjBenders*     objbenders,         /**< Benders' decomposition object */
224  	   const char*           name                /**< name of Benders' decomposition cut */
225  	   );
226  	
227  	/** returns the benderscut object for the given constraint handler */
228  	SCIP_EXPORT
229  	scip::ObjBenderscut* SCIPgetObjBenderscut(
230  	   SCIP*                 scip,               /**< SCIP data structure */
231  	   SCIP_BENDERSCUT*      benderscut          /**< Benders' decomposition cut */
232  	   );
233  	
234  	#endif
235