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 objbranchrule.h 26 * @brief C++ wrapper for branching rules 27 * @author Tobias Achterberg 28 */ 29 30 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/ 31 32 #ifndef __SCIP_OBJBRANCHRULE_H__ 33 #define __SCIP_OBJBRANCHRULE_H__ 34 35 36 #include <cassert> 37 #include <cstring> 38 #include <utility> 39 40 #include "scip/scip.h" 41 #include "objscip/objcloneable.h" 42 43 namespace scip 44 { 45 46 /** @brief C++ wrapper for branching rules 47 * 48 * This class defines the interface for branching rules implemented in C++. 49 * 50 * - \ref BRANCH "Instructions for implementing a branching rule" 51 * - \ref BRANCHINGRULES "List of available branching rules" 52 * - \ref type_branch.h "Corresponding C interface" 53 */ 54 class ObjBranchrule : public ObjCloneable 55 { 56 public: 57 /*lint --e{1540}*/ 58 59 /** SCIP data structure */ 60 SCIP* scip_; 61 62 /** name of the branching rule */ 63 char* scip_name_; 64 65 /** description of the branching rule */ 66 char* scip_desc_; 67 68 /** default priority of the branching rule */ 69 const int scip_priority_; 70 71 /** default maximal depth for applying the branching rule */ 72 const int scip_maxdepth_; 73 74 /** default maximal relative distance from current node's dual bound to primal bound 75 * compared to best node's dual bound for applying branching rule 76 * (0.0: only on current best node, 1.0: on all nodes) 77 */ 78 const SCIP_Real scip_maxbounddist_; 79 80 /** default constructor */ 81 ObjBranchrule( 82 SCIP* scip, /**< SCIP data structure */ 83 const char* name, /**< name of branching rule */ 84 const char* desc, /**< description of branching rule */ 85 int priority, /**< priority of the branching rule */ 86 int maxdepth, /**< maximal depth level, up to which this branching rule should be used (or -1) */ 87 SCIP_Real maxbounddist /**< maximal relative distance from current node's dual bound to primal bound 88 * compared to best node's dual bound for applying branching rule 89 * (0.0: only on current best node, 1.0: on all nodes) */ 90 ) 91 : scip_(scip), 92 scip_name_(0), 93 scip_desc_(0), 94 scip_priority_(priority), 95 scip_maxdepth_(maxdepth), 96 scip_maxbounddist_(maxbounddist) 97 { 98 /* the macro SCIPduplicateMemoryArray does not need the first argument: */ 99 SCIP_CALL_ABORT( SCIPduplicateMemoryArray(scip_, &scip_name_, name, std::strlen(name)+1) ); 100 SCIP_CALL_ABORT( SCIPduplicateMemoryArray(scip_, &scip_desc_, desc, std::strlen(desc)+1) ); 101 } 102 103 /** copy constructor */ 104 ObjBranchrule(const ObjBranchrule& o) 105 : ObjBranchrule(o.scip_, o.scip_name_, o.scip_desc_, o.scip_priority_, o.scip_maxdepth_, o.scip_maxbounddist_) 106 { 107 } 108 109 /** move constructor */ 110 ObjBranchrule(ObjBranchrule&& o) 111 : scip_(o.scip_), 112 scip_name_(0), 113 scip_desc_(0), 114 scip_priority_(o.scip_priority_), 115 scip_maxdepth_(o.scip_maxdepth_), 116 scip_maxbounddist_(o.scip_maxbounddist_) 117 { 118 std::swap(scip_name_, o.scip_name_); 119 std::swap(scip_desc_, o.scip_desc_); 120 } 121 122 /** destructor */ 123 virtual ~ObjBranchrule() 124 { 125 /* the macro SCIPfreeMemoryArray does not need the first argument: */ 126 /*lint --e{64}*/ 127 SCIPfreeMemoryArray(scip_, &scip_name_); 128 SCIPfreeMemoryArray(scip_, &scip_desc_); 129 } 130 131 /** assignment of polymorphic classes causes slicing and is therefore disabled. */ 132 ObjBranchrule& operator=(const ObjBranchrule& o) = delete; 133 134 /** assignment of polymorphic classes causes slicing and is therefore disabled. */ 135 ObjBranchrule& operator=(ObjBranchrule&& o) = delete; 136 137 /** destructor of branching rule to free user data (called when SCIP is exiting) 138 * 139 * @see SCIP_DECL_BRANCHFREE(x) in @ref type_branch.h 140 */ 141 virtual SCIP_DECL_BRANCHFREE(scip_free) 142 { /*lint --e{715}*/ 143 return SCIP_OKAY; 144 } 145 146 /** initialization method of branching rule (called after problem was transformed) 147 * 148 * @see SCIP_DECL_BRANCHINIT(x) in @ref type_branch.h 149 */ 150 virtual SCIP_DECL_BRANCHINIT(scip_init) 151 { /*lint --e{715}*/ 152 return SCIP_OKAY; 153 } 154 155 /** deinitialization method of branching rule (called before transformed problem is freed) 156 * 157 * @see SCIP_DECL_BRANCHEXIT(x) in @ref type_branch.h 158 */ 159 virtual SCIP_DECL_BRANCHEXIT(scip_exit) 160 { /*lint --e{715}*/ 161 return SCIP_OKAY; 162 } 163 164 /** solving process initialization method of branching rule (called when branch and bound process is about to begin) 165 * 166 * @see SCIP_DECL_BRANCHINITSOL(x) in @ref type_branch.h 167 */ 168 virtual SCIP_DECL_BRANCHINITSOL(scip_initsol) 169 { /*lint --e{715}*/ 170 return SCIP_OKAY; 171 } 172 173 /** solving process deinitialization method of branching rule (called before branch and bound process data is freed) 174 * 175 * @see SCIP_DECL_BRANCHEXITSOL(x) in @ref type_branch.h 176 */ 177 virtual SCIP_DECL_BRANCHEXITSOL(scip_exitsol) 178 { /*lint --e{715}*/ 179 return SCIP_OKAY; 180 } 181 182 /** branching execution method for fractional LP solutions 183 * 184 * @see SCIP_DECL_BRANCHEXECLP(x) in @ref type_branch.h 185 */ 186 virtual SCIP_DECL_BRANCHEXECLP(scip_execlp) 187 { /*lint --e{715}*/ 188 assert(result != NULL); 189 *result = SCIP_DIDNOTRUN; 190 return SCIP_OKAY; 191 } 192 193 /** branching execution method for external candidates 194 * 195 * @see SCIP_DECL_BRANCHEXECEXT(x) in @ref type_branch.h 196 */ 197 virtual SCIP_DECL_BRANCHEXECEXT(scip_execext) 198 { /*lint --e{715}*/ 199 assert(result != NULL); 200 *result = SCIP_DIDNOTRUN; 201 return SCIP_OKAY; 202 } 203 204 /** branching execution method for not completely fixed pseudo solutions 205 * 206 * @see SCIP_DECL_BRANCHEXECPS(x) in @ref type_branch.h 207 */ 208 virtual SCIP_DECL_BRANCHEXECPS(scip_execps) 209 { /*lint --e{715}*/ 210 assert(result != NULL); 211 *result = SCIP_DIDNOTRUN; 212 return SCIP_OKAY; 213 } 214 }; 215 216 } /* namespace scip */ 217 218 219 /** creates the branching rule for the given branching rule object and includes it in SCIP 220 * 221 * The method should be called in one of the following ways: 222 * 223 * 1. The user is resposible of deleting the object: 224 * SCIP_CALL( SCIPcreate(&scip) ); 225 * ... 226 * MyBranchrule* mybranchrule = new MyBranchrule(...); 227 * SCIP_CALL( SCIPincludeObjBranchrule(scip, &mybranchrule, FALSE) ); 228 * ... 229 * SCIP_CALL( SCIPfree(&scip) ); 230 * delete mybranchrule; // delete branchrule AFTER SCIPfree() ! 231 * 232 * 2. The object pointer is passed to SCIP and deleted by SCIP in the SCIPfree() call: 233 * SCIP_CALL( SCIPcreate(&scip) ); 234 * ... 235 * SCIP_CALL( SCIPincludeObjBranchrule(scip, new MyBranchrule(...), TRUE) ); 236 * ... 237 * SCIP_CALL( SCIPfree(&scip) ); // destructor of MyBranchrule is called here 238 */ 239 SCIP_EXPORT 240 SCIP_RETCODE SCIPincludeObjBranchrule( 241 SCIP* scip, /**< SCIP data structure */ 242 scip::ObjBranchrule* objbranchrule, /**< branching rule object */ 243 SCIP_Bool deleteobject /**< should the branching rule object be deleted when branching rule is freed? */ 244 ); 245 246 /** returns the branchrule object of the given name, or 0 if not existing */ 247 SCIP_EXPORT 248 scip::ObjBranchrule* SCIPfindObjBranchrule( 249 SCIP* scip, /**< SCIP data structure */ 250 const char* name /**< name of branching rule */ 251 ); 252 253 /** returns the branchrule object for the given branching rule */ 254 SCIP_EXPORT 255 scip::ObjBranchrule* SCIPgetObjBranchrule( 256 SCIP* scip, /**< SCIP data structure */ 257 SCIP_BRANCHRULE* branchrule /**< branching rule */ 258 ); 259 260 #endif 261