1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /*                                                                           */
3 /*                  This file is part of the program and library             */
4 /*         SCIP --- Solving Constraint Integer Programs                      */
5 /*                                                                           */
6 /*    Copyright (C) 2002-2021 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.cpp
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 #include <cassert>
24 
25 #include "objsepa.h"
26 
27 
28 
29 
30 /*
31  * Data structures
32  */
33 
34 /** cut separator data */
35 struct SCIP_SepaData
36 {
37    scip::ObjSepa*        objsepa;            /**< cut separator object */
38    SCIP_Bool             deleteobject;       /**< should the cut separator object be deleted when cut separator is freed? */
39 };
40 
41 
42 
43 /*
44  * Callback methods of cut separator
45  */
46 
47 extern "C"
48 {
49 
50 /** copy method for separator plugins (called when SCIP copies plugins) */
51 static
SCIP_DECL_SEPACOPY(sepaCopyObj)52 SCIP_DECL_SEPACOPY(sepaCopyObj)
53 {  /*lint --e{715}*/
54    SCIP_SEPADATA* sepadata;
55 
56    assert(scip != NULL);
57 
58    sepadata = SCIPsepaGetData(sepa);
59    assert(sepadata != NULL);
60    assert(sepadata->objsepa != NULL);
61    assert(sepadata->objsepa->scip_ != scip);
62 
63    if( sepadata->objsepa->iscloneable() )
64    {
65       scip::ObjSepa* newobjsepa;
66       newobjsepa = dynamic_cast<scip::ObjSepa*> (sepadata->objsepa->clone(scip));
67 
68       /* call include method of separator object */
69       SCIP_CALL( SCIPincludeObjSepa(scip, newobjsepa, TRUE) );
70    }
71 
72    return SCIP_OKAY;
73 }
74 
75 /** destructor of cut separator to free user data (called when SCIP is exiting) */
76 static
SCIP_DECL_SEPAFREE(sepaFreeObj)77 SCIP_DECL_SEPAFREE(sepaFreeObj)
78 {  /*lint --e{715}*/
79    SCIP_SEPADATA* sepadata;
80 
81    sepadata = SCIPsepaGetData(sepa);
82    assert(sepadata != NULL);
83    assert(sepadata->objsepa != NULL);
84    assert(sepadata->objsepa->scip_ == scip);
85 
86    /* call virtual method of sepa object */
87    SCIP_CALL( sepadata->objsepa->scip_free(scip, sepa) );
88 
89    /* free sepa object */
90    if( sepadata->deleteobject )
91       delete sepadata->objsepa;
92 
93    /* free sepa data */
94    delete sepadata;
95    SCIPsepaSetData(sepa, NULL); /*lint !e64*/
96 
97    return SCIP_OKAY;
98 }
99 
100 
101 /** initialization method of cut separator (called after problem was transformed) */
102 static
SCIP_DECL_SEPAINIT(sepaInitObj)103 SCIP_DECL_SEPAINIT(sepaInitObj)
104 {  /*lint --e{715}*/
105    SCIP_SEPADATA* sepadata;
106 
107    sepadata = SCIPsepaGetData(sepa);
108    assert(sepadata != NULL);
109    assert(sepadata->objsepa != NULL);
110    assert(sepadata->objsepa->scip_ == scip);
111 
112    /* call virtual method of sepa object */
113    SCIP_CALL( sepadata->objsepa->scip_init(scip, sepa) );
114 
115    return SCIP_OKAY;
116 }
117 
118 
119 /** deinitialization method of cut separator (called before transformed problem is freed) */
120 static
SCIP_DECL_SEPAEXIT(sepaExitObj)121 SCIP_DECL_SEPAEXIT(sepaExitObj)
122 {  /*lint --e{715}*/
123    SCIP_SEPADATA* sepadata;
124 
125    sepadata = SCIPsepaGetData(sepa);
126    assert(sepadata != NULL);
127    assert(sepadata->objsepa != NULL);
128 
129    /* call virtual method of sepa object */
130    SCIP_CALL( sepadata->objsepa->scip_exit(scip, sepa) );
131 
132    return SCIP_OKAY;
133 }
134 
135 
136 /** solving process initialization method of separator (called when branch and bound process is about to begin) */
137 static
SCIP_DECL_SEPAINITSOL(sepaInitsolObj)138 SCIP_DECL_SEPAINITSOL(sepaInitsolObj)
139 {  /*lint --e{715}*/
140    SCIP_SEPADATA* sepadata;
141 
142    sepadata = SCIPsepaGetData(sepa);
143    assert(sepadata != NULL);
144    assert(sepadata->objsepa != NULL);
145 
146    /* call virtual method of sepa object */
147    SCIP_CALL( sepadata->objsepa->scip_initsol(scip, sepa) );
148 
149    return SCIP_OKAY;
150 }
151 
152 
153 /** solving process deinitialization method of separator (called before branch and bound process data is freed) */
154 static
SCIP_DECL_SEPAEXITSOL(sepaExitsolObj)155 SCIP_DECL_SEPAEXITSOL(sepaExitsolObj)
156 {  /*lint --e{715}*/
157    SCIP_SEPADATA* sepadata;
158 
159    sepadata = SCIPsepaGetData(sepa);
160    assert(sepadata != NULL);
161    assert(sepadata->objsepa != NULL);
162 
163    /* call virtual method of sepa object */
164    SCIP_CALL( sepadata->objsepa->scip_exitsol(scip, sepa) );
165 
166    return SCIP_OKAY;
167 }
168 
169 
170 /** LP solution separation method of separator */
171 static
SCIP_DECL_SEPAEXECLP(sepaExeclpObj)172 SCIP_DECL_SEPAEXECLP(sepaExeclpObj)
173 {  /*lint --e{715}*/
174    SCIP_SEPADATA* sepadata;
175 
176    sepadata = SCIPsepaGetData(sepa);
177    assert(sepadata != NULL);
178    assert(sepadata->objsepa != NULL);
179 
180    /* call virtual method of sepa object */
181    SCIP_CALL( sepadata->objsepa->scip_execlp(scip, sepa, result, allowlocal) );
182 
183    return SCIP_OKAY;
184 }
185 
186 
187 /** arbitrary primal solution separation method of separator */
188 static
SCIP_DECL_SEPAEXECSOL(sepaExecsolObj)189 SCIP_DECL_SEPAEXECSOL(sepaExecsolObj)
190 {  /*lint --e{715}*/
191    SCIP_SEPADATA* sepadata;
192 
193    sepadata = SCIPsepaGetData(sepa);
194    assert(sepadata != NULL);
195    assert(sepadata->objsepa != NULL);
196 
197    /* call virtual method of sepa object */
198    SCIP_CALL( sepadata->objsepa->scip_execsol(scip, sepa, sol, result, allowlocal) );
199 
200    return SCIP_OKAY;
201 }
202 }
203 
204 
205 
206 /*
207  * cut separator specific interface methods
208  */
209 
210 /** creates the cut separator for the given cut separator object and includes it in SCIP */
SCIPincludeObjSepa(SCIP * scip,scip::ObjSepa * objsepa,SCIP_Bool deleteobject)211 SCIP_RETCODE SCIPincludeObjSepa(
212    SCIP*                 scip,               /**< SCIP data structure */
213    scip::ObjSepa*        objsepa,            /**< cut separator object */
214    SCIP_Bool             deleteobject        /**< should the cut separator object be deleted when cut separator is freed? */
215    )
216 {
217    SCIP_SEPADATA* sepadata;
218 
219    assert(scip != NULL);
220    assert(objsepa != NULL);
221 
222    /* create cut separator data */
223    sepadata = new SCIP_SEPADATA;
224    sepadata->objsepa = objsepa;
225    sepadata->deleteobject = deleteobject;
226 
227    /* include cut separator */
228    SCIP_CALL( SCIPincludeSepa(scip, objsepa->scip_name_, objsepa->scip_desc_, objsepa->scip_priority_,
229          objsepa->scip_freq_, objsepa->scip_maxbounddist_, objsepa->scip_usessubscip_, objsepa->scip_delay_,
230          sepaCopyObj, sepaFreeObj, sepaInitObj, sepaExitObj, sepaInitsolObj, sepaExitsolObj,
231          sepaExeclpObj, sepaExecsolObj,
232          sepadata) ); /*lint !e429*/
233 
234    return SCIP_OKAY; /*lint !e429*/
235 }
236 
237 /** returns the sepa object of the given name, or 0 if not existing */
SCIPfindObjSepa(SCIP * scip,const char * name)238 scip::ObjSepa* SCIPfindObjSepa(
239    SCIP*                 scip,               /**< SCIP data structure */
240    const char*           name                /**< name of cut separator */
241    )
242 {
243    SCIP_SEPA* sepa;
244    SCIP_SEPADATA* sepadata;
245 
246    sepa = SCIPfindSepa(scip, name);
247    if( sepa == NULL )
248       return 0;
249 
250    sepadata = SCIPsepaGetData(sepa);
251    assert(sepadata != NULL);
252 
253    return sepadata->objsepa;
254 }
255 
256 /** returns the sepa object for the given cut separator */
SCIPgetObjSepa(SCIP * scip,SCIP_SEPA * sepa)257 scip::ObjSepa* SCIPgetObjSepa(
258    SCIP*                 scip,               /**< SCIP data structure */
259    SCIP_SEPA*            sepa                /**< cut separator */
260    )
261 {
262    SCIP_SEPADATA* sepadata;
263 
264    assert(scip != NULL);
265    sepadata = SCIPsepaGetData(sepa);
266    assert(sepadata != NULL);
267 
268    return sepadata->objsepa;
269 }
270