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