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