1    	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2    	/*                                                                           */
3    	/*                  This file is part of the program and library             */
4    	/*         SCIP --- Solving Constraint Integer Programs                      */
5    	/*                                                                           */
6    	/*  Copyright (c) 2002-2023 Zuse Institute Berlin (ZIB)                      */
7    	/*                                                                           */
8    	/*  Licensed under the Apache License, Version 2.0 (the "License");          */
9    	/*  you may not use this file except in compliance with the License.         */
10   	/*  You may obtain a copy of the License at                                  */
11   	/*                                                                           */
12   	/*      http://www.apache.org/licenses/LICENSE-2.0                           */
13   	/*                                                                           */
14   	/*  Unless required by applicable law or agreed to in writing, software      */
15   	/*  distributed under the License is distributed on an "AS IS" BASIS,        */
16   	/*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17   	/*  See the License for the specific language governing permissions and      */
18   	/*  limitations under the License.                                           */
19   	/*                                                                           */
20   	/*  You should have received a copy of the Apache-2.0 license                */
21   	/*  along with SCIP; see the file LICENSE. If not visit scipopt.org.         */
22   	/*                                                                           */
23   	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24   	
25   	/**@file   objrelax.h
26   	 * @brief  C++ wrapper for relaxation handlers
27   	 * @author Tobias Achterberg
28   	 */
29   	
30   	/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
31   	
32   	#ifndef __SCIP_OBJRELAX_H__
33   	#define __SCIP_OBJRELAX_H__
34   	
35   	#include <cstring>
36   	#include <utility>
37   	
38   	#include "scip/scip.h"
39   	#include "objscip/objcloneable.h"
40   	
41   	namespace scip
42   	{
43   	
44   	/** @brief C++ wrapper for relaxation handlers
45   	 *
46   	 *  This class defines the interface for relaxation handlers implemented in C++. Note that there is a pure virtual
47   	 *  function (this function has to be implemented). This function is: scip_exec().
48   	 *
49   	 *  - \ref RELAX "Instructions for implementing a relaxation handler"
50   	 *  - \ref type_relax.h "Corresponding C interface"
51   	 */
52   	class ObjRelax : public ObjCloneable
53   	{
54   	public:
55   	   /*lint --e{1540}*/
56   	
57   	   /** SCIP data structure */
58   	   SCIP* scip_;
59   	
60   	   /** name of the relaxator */
61   	   char* scip_name_;
62   	
63   	   /** description of the relaxator */
64   	   char* scip_desc_;
65   	
66   	   /** default priority of the relaxator (negative: call after LP, non-negative: call before LP) */
67   	   const int scip_priority_;
68   	
69   	   /** frequency for calling relaxator */
70   	   const int scip_freq_;
71   	
72   	   /** does the relaxator contain all cuts in the LP? */
73   	   const SCIP_Bool scip_includeslp_;
74   	
75   	   /** default constructor */
76   	   ObjRelax(
77   	      SCIP*              scip,               /**< SCIP data structure */
78   	      const char*        name,               /**< name of relaxator */
79   	      const char*        desc,               /**< description of relaxator */
80   	      int                priority,           /**< priority of the relaxator (negative: after LP, non-negative: before LP) */
81   	      int                freq,               /**< frequency for calling relaxator */
82   	      SCIP_Bool          includeslp          /**< Does the relaxator contain all cuts in the LP? */
83   	      )
84   	      : scip_(scip),
85   	        scip_name_(0),
86   	        scip_desc_(0),
87   	        scip_priority_(priority),
88   	        scip_freq_(freq),
89   	        scip_includeslp_(includeslp)
90   	   {
91   	      /* the macro SCIPduplicateMemoryArray does not need the first argument: */
92   	      SCIP_CALL_ABORT( SCIPduplicateMemoryArray(scip_, &scip_name_, name, std::strlen(name)+1) );
93   	      SCIP_CALL_ABORT( SCIPduplicateMemoryArray(scip_, &scip_desc_, desc, std::strlen(desc)+1) );
94   	   }
95   	
96   	   /** copy constructor */
97   	   ObjRelax(const ObjRelax& o)
98   	       : ObjRelax(o.scip_, o.scip_name_, o.scip_desc_, o.scip_priority_, o.scip_priority_, o.scip_includeslp_)
99   	   {
100  	   }
101  	
102  	   /** move constructor */
103  	   ObjRelax(ObjRelax&& o)
104  	       : scip_(o.scip_),
105  	         scip_name_(0),
106  	         scip_desc_(0),
107  	         scip_priority_(o.scip_priority_),
108  	         scip_freq_(o.scip_freq_),
109  	         scip_includeslp_(o.scip_includeslp_)
110  	   {
111  	      std::swap(scip_name_, o.scip_name_);
112  	      std::swap(scip_desc_, o.scip_desc_);
113  	   }
114  	
115  	   /** destructor */
116  	   virtual ~ObjRelax()
117  	   {
118  	      /* the macro SCIPfreeMemoryArray does not need the first argument: */
119  	      /*lint --e{64}*/
120  	      SCIPfreeMemoryArray(scip_, &scip_name_);
121  	      SCIPfreeMemoryArray(scip_, &scip_desc_);
122  	   }
123  	
124  	   /** assignment of polymorphic classes causes slicing and is therefore disabled. */
125  	   ObjRelax& operator=(const ObjRelax& o) = delete;
126  	
127  	   /** assignment of polymorphic classes causes slicing and is therefore disabled. */
128  	   ObjRelax& operator=(ObjRelax&& o) = delete;
129  	
130  	   /** destructor of relaxator to free user data (called when SCIP is exiting)
131  	    *
132  	    *  @see SCIP_DECL_RELAXFREE(x) in @ref type_relax.h
133  	    */
134  	   virtual SCIP_DECL_RELAXFREE(scip_free)
135  	   {  /*lint --e{715}*/
136  	      return SCIP_OKAY;
137  	   }
138  	
139  	   /** initialization method of relaxator (called after problem was transformed)
140  	    *
141  	    *  @see SCIP_DECL_RELAXINIT(x) in @ref type_relax.h
142  	    */
143  	   virtual SCIP_DECL_RELAXINIT(scip_init)
144  	   {  /*lint --e{715}*/
145  	      return SCIP_OKAY;
146  	   }
147  	
148  	   /** deinitialization method of relaxator (called before transformed problem is freed)
149  	    *
150  	    *  @see SCIP_DECL_RELAXEXIT(x) in @ref type_relax.h
151  	    */
152  	   virtual SCIP_DECL_RELAXEXIT(scip_exit)
153  	   {  /*lint --e{715}*/
154  	      return SCIP_OKAY;
155  	   }
156  	
157  	   /** solving process initialization method of relaxator (called when branch and bound process is about to begin)
158  	    *
159  	    *  @see SCIP_DECL_RELAXINITSOL(x) in @ref type_relax.h
160  	    */
161  	   virtual SCIP_DECL_RELAXINITSOL(scip_initsol)
162  	   {  /*lint --e{715}*/
163  	      return SCIP_OKAY;
164  	   }
165  	
166  	   /** solving process deinitialization method of relaxator (called before branch and bound process data is freed)
167  	    *
168  	    *  @see SCIP_DECL_RELAXEXITSOL(x) in @ref type_relax.h
169  	    */
170  	   virtual SCIP_DECL_RELAXEXITSOL(scip_exitsol)
171  	   {  /*lint --e{715}*/
172  	      return SCIP_OKAY;
173  	   }
174  	
175  	   /** execution method of relaxator
176  	    *
177  	    *  @see SCIP_DECL_RELAXEXEC(x) in @ref type_relax.h
178  	    */
179  	   virtual SCIP_DECL_RELAXEXEC(scip_exec) = 0;
180  	};
181  	
182  	} /* namespace scip */
183  	
184  	
185  	
186  	/** creates the relaxator for the given relaxator object and includes it in SCIP
187  	 *
188  	 *  The method should be called in one of the following ways:
189  	 *
190  	 *   1. The user is resposible of deleting the object:
191  	 *       SCIP_CALL( SCIPcreate(&scip) );
192  	 *       ...
193  	 *       MyRelax* myrelax = new MyRelax(...);
194  	 *       SCIP_CALL( SCIPincludeObjRelax(scip, &myrelax, FALSE) );
195  	 *       ...
196  	 *       SCIP_CALL( SCIPfree(&scip) );
197  	 *       delete myrelax;    // delete relax AFTER SCIPfree() !
198  	 *
199  	 *   2. The object pointer is passed to SCIP and deleted by SCIP in the SCIPfree() call:
200  	 *       SCIP_CALL( SCIPcreate(&scip) );
201  	 *       ...
202  	 *       SCIP_CALL( SCIPincludeObjRelax(scip, new MyRelax(...), TRUE) );
203  	 *       ...
204  	 *       SCIP_CALL( SCIPfree(&scip) );  // destructor of MyRelax is called here
205  	 */
206  	SCIP_EXPORT
207  	SCIP_RETCODE SCIPincludeObjRelax(
208  	   SCIP*                 scip,               /**< SCIP data structure */
209  	   scip::ObjRelax*  objrelax,           /**< relaxator object */
210  	   SCIP_Bool             deleteobject        /**< should the relaxator object be deleted when relaxator is freed? */
211  	   );
212  	
213  	/** returns the relax object of the given name, or 0 if not existing */
214  	SCIP_EXPORT
215  	scip::ObjRelax* SCIPfindObjRelax(
216  	   SCIP*                 scip,               /**< SCIP data structure */
217  	   const char*           name                /**< name of relaxator */
218  	   );
219  	
220  	/** returns the relax object for the given relaxator */
221  	SCIP_EXPORT
222  	scip::ObjRelax* SCIPgetObjRelax(
223  	   SCIP*                 scip,               /**< SCIP data structure */
224  	   SCIP_RELAX*           relax               /**< relaxator */
225  	   );
226  	
227  	#endif
228