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 objsepa.h
17 * @brief C++ wrapper for cut separators
18 * @author Tobias Achterberg
19 */
20
21 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
22
23 #ifndef __SCIP_OBJSEPA_H__
24 #define __SCIP_OBJSEPA_H__
25
26 #include <cstring>
27
28 #include "scip/scip.h"
29 #include "objscip/objcloneable.h"
30
31 namespace scip
32 {
33
34 /** @brief C++ wrapper for cut separators
35 *
36 * This class defines the interface for cut separators implemented in C++.
37 *
38 * - \ref SEPA "Instructions for implementing a cut separator"
39 * - \ref SEPARATORS "List of available cut separators"
40 * - \ref type_sepa.h "Corresponding C interface"
41 */
(1) Event missing_assign: |
Class "scip::ObjSepa" owns resources that are freed in its destructor but has no user-written assignment operator. |
(2) Event free_resource: |
The destructor frees member "scip_desc_". [details] |
(3) Event free_resource: |
The destructor frees member "scip_name_". [details] |
42 class ObjSepa : public ObjCloneable
43 {
44 public:
45 /*lint --e{1540}*/
46
47 /** SCIP data structure */
48 SCIP* scip_;
49
50 /** name of the cut separator */
51 char* scip_name_;
52
53 /** description of the cut separator */
54 char* scip_desc_;
55
56 /** default priority of the cut separator */
57 const int scip_priority_;
58
59 /** frequency for calling separator */
60 const int scip_freq_;
61
62 /** maximal relative distance from current node's dual bound to primal bound compared to best node's dual bound for applying
63 * separation (0.0: only on current best node, 1.0: on all nodes)
64 */
65 const SCIP_Real scip_maxbounddist_;
66
67 /** does the separator use a secondary SCIP instance? */
68 const SCIP_Bool scip_usessubscip_;
69
70 /** should separator be delayed, if other separators found cuts? */
71 const SCIP_Bool scip_delay_;
72
73 /** default constructor */
74 ObjSepa(
75 SCIP* scip, /**< SCIP data structure */
76 const char* name, /**< name of cut separator */
77 const char* desc, /**< description of cut separator */
78 int priority, /**< priority of the cut separator */
79 int freq, /**< frequency for calling separator */
80 SCIP_Real maxbounddist, /**< maximal relative distance from current node's dual bound to primal bound compared
81 * to best node's dual bound for applying separation */
82 SCIP_Bool usessubscip, /**< does the separator use a secondary SCIP instance? */
83 SCIP_Bool delay /**< should separator be delayed, if other separators found cuts? */
84 )
85 : scip_(scip),
86 scip_name_(0),
87 scip_desc_(0),
88 scip_priority_(priority),
89 scip_freq_(freq),
90 scip_maxbounddist_(maxbounddist),
91 scip_usessubscip_(usessubscip),
92 scip_delay_(delay)
93 {
94 /* the macro SCIPduplicateMemoryArray does not need the first argument: */
95 SCIP_CALL_ABORT( SCIPduplicateMemoryArray(scip_, &scip_name_, name, std::strlen(name)+1) );
96 SCIP_CALL_ABORT( SCIPduplicateMemoryArray(scip_, &scip_desc_, desc, std::strlen(desc)+1) );
97 }
98
99 /** destructor */
100 virtual ~ObjSepa()
101 {
102 /* the macro SCIPfreeMemoryArray does not need the first argument: */
103 /*lint --e{64}*/
(1) Event freed_arg: |
"BMSfreeMemory_call" frees parameter "this->scip_name_". [details] |
104 SCIPfreeMemoryArray(scip_, &scip_name_);
(1) Event freed_arg: |
"BMSfreeMemory_call" frees parameter "this->scip_desc_". [details] |
105 SCIPfreeMemoryArray(scip_, &scip_desc_);
106 }
107
108 /** destructor of cut separator to free user data (called when SCIP is exiting)
109 *
110 * @see SCIP_DECL_SEPAFREE(x) in @ref type_sepa.h
111 */
112 virtual SCIP_DECL_SEPAFREE(scip_free)
113 { /*lint --e{715}*/
114 return SCIP_OKAY;
115 }
116
117 /** initialization method of cut separator (called after problem was transformed)
118 *
119 * @see SCIP_DECL_SEPAINIT(x) in @ref type_sepa.h
120 */
121 virtual SCIP_DECL_SEPAINIT(scip_init)
122 { /*lint --e{715}*/
123 return SCIP_OKAY;
124 }
125
126 /** deinitialization method of cut separator (called before transformed problem is freed)
127 *
128 * @see SCIP_DECL_SEPAEXIT(x) in @ref type_sepa.h
129 */
130 virtual SCIP_DECL_SEPAEXIT(scip_exit)
131 { /*lint --e{715}*/
132 return SCIP_OKAY;
133 }
134
135 /** solving process initialization method of separator (called when branch and bound process is about to begin)
136 *
137 * @see SCIP_DECL_SEPAINITSOL(x) in @ref type_sepa.h
138 */
139 virtual SCIP_DECL_SEPAINITSOL(scip_initsol)
140 { /*lint --e{715}*/
141 return SCIP_OKAY;
142 }
143
144 /** solving process deinitialization method of separator (called before branch and bound process data is freed)
145 *
146 * @see SCIP_DECL_SEPAEXITSOL(x) in @ref type_sepa.h
147 */
148 virtual SCIP_DECL_SEPAEXITSOL(scip_exitsol)
149 { /*lint --e{715}*/
150 return SCIP_OKAY;
151 }
152
153 /** LP solution separation method of separator
154 *
155 * @see SCIP_DECL_SEPAEXECLP(x) in @ref type_sepa.h
156 */
157 virtual SCIP_DECL_SEPAEXECLP(scip_execlp)
158 { /*lint --e{715}*/
159 assert(result != NULL);
160 *result = SCIP_DIDNOTRUN;
161 return SCIP_OKAY;
162 }
163
164 /** arbitrary primal solution separation method of separator
165 *
166 * @see SCIP_DECL_SEPAEXECSOL(x) in @ref type_sepa.h
167 */
168 virtual SCIP_DECL_SEPAEXECSOL(scip_execsol)
169 { /*lint --e{715}*/
170 assert(result != NULL);
171 *result = SCIP_DIDNOTRUN;
172 return SCIP_OKAY;
173 }
174 };
175
176 } /* namespace scip */
177
178
179
180 /** creates the cut separator for the given cut separator object and includes it in SCIP
181 *
182 * The method should be called in one of the following ways:
183 *
184 * 1. The user is resposible of deleting the object:
185 * SCIP_CALL( SCIPcreate(&scip) );
186 * ...
187 * MySepa* mysepa = new MySepa(...);
188 * SCIP_CALL( SCIPincludeObjSepa(scip, &mysepa, FALSE) );
189 * ...
190 * SCIP_CALL( SCIPfree(&scip) );
191 * delete mysepa; // delete sepa AFTER SCIPfree() !
192 *
193 * 2. The object pointer is passed to SCIP and deleted by SCIP in the SCIPfree() call:
194 * SCIP_CALL( SCIPcreate(&scip) );
195 * ...
196 * SCIP_CALL( SCIPincludeObjSepa(scip, new MySepa(...), TRUE) );
197 * ...
198 * SCIP_CALL( SCIPfree(&scip) ); // destructor of MySepa is called here
199 */
200 SCIP_EXPORT
201 SCIP_RETCODE SCIPincludeObjSepa(
202 SCIP* scip, /**< SCIP data structure */
203 scip::ObjSepa* objsepa, /**< cut separator object */
204 SCIP_Bool deleteobject /**< should the cut separator object be deleted when cut separator is freed? */
205 );
206
207 /** returns the sepa object of the given name, or 0 if not existing */
208 SCIP_EXPORT
209 scip::ObjSepa* SCIPfindObjSepa(
210 SCIP* scip, /**< SCIP data structure */
211 const char* name /**< name of cut separator */
212 );
213
214 /** returns the sepa object for the given cut separator */
215 SCIP_EXPORT
216 scip::ObjSepa* SCIPgetObjSepa(
217 SCIP* scip, /**< SCIP data structure */
218 SCIP_SEPA* sepa /**< cut separator */
219 );
220
221 #endif
222