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