SCIP Doxygen Documentation
Loading...
Searching...
No Matches
nodesel_restartdfs.c
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the program and library */
4/* SCIP --- Solving Constraint Integer Programs */
5/* */
6/* Copyright (c) 2002-2026 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 nodesel_restartdfs.c
26 * @ingroup DEFPLUGINS_NODESEL
27 * @brief node selector for depth first search with periodical selection of the best node
28 * @author Tobias Achterberg
29 * @author Stefan Heinz
30 */
31
32/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
33
35#include "scip/pub_message.h"
36#include "scip/pub_nodesel.h"
37#include "scip/pub_tree.h"
38#include "scip/scip_mem.h"
39#include "scip/scip_nodesel.h"
40#include "scip/scip_param.h"
42#include "scip/scip_tree.h"
43
44
45#define NODESEL_NAME "restartdfs"
46#define NODESEL_DESC "depth first search with periodical selection of the best node"
47#define NODESEL_STDPRIORITY 10000
48#define NODESEL_MEMSAVEPRIORITY 50000
49
50
51/*
52 * Default parameter settings
53 */
54
55#define SELECTBESTFREQ 100 /**< frequency for selecting the best node instead of the deepest one */
56#define COUNTONLYLEAVES TRUE /**< only count leaf nodes or all nodes */
57
58
59/** node selector data for best first search node selection */
60struct SCIP_NodeselData
61{
62 SCIP_Longint lastrestart; /**< node number where the last best node was selected */
63 SCIP_Longint nprocessedleaves; /**< number of processed leafs since the last restart */
64 int selectbestfreq; /**< frequency for selecting the best node instead of the deepest one */
65 SCIP_Bool countonlyleaves; /**< only count leaf nodes or all nodes */
66};
67
68
69/*
70 * Callback methods
71 */
72
73/** copy method for node selector plugins (called when SCIP copies plugins) */
74static
75SCIP_DECL_NODESELCOPY(nodeselCopyRestartdfs)
76{ /*lint --e{715}*/
77 assert(scip != NULL);
78 assert(nodesel != NULL);
79
81
82 /* call inclusion method of node selector */
84
85 return SCIP_OKAY;
86}
87
88/** destructor of node selector to free user data (called when SCIP is exiting) */
89static
90SCIP_DECL_NODESELFREE(nodeselFreeRestartdfs)
91{ /*lint --e{715}*/
92 SCIP_NODESELDATA* nodeseldata;
93
95
96 /* free user data of node selector */
97 nodeseldata = SCIPnodeselGetData(nodesel);
98 assert(nodeseldata != NULL);
99 SCIPfreeBlockMemory(scip, &nodeseldata);
100 SCIPnodeselSetData(nodesel, nodeseldata);
101
102 return SCIP_OKAY;
103}
104
105
106/** solving process initialization method of node selector (called when branch and bound process is about to begin) */
107static
108SCIP_DECL_NODESELINITSOL(nodeselInitsolRestartdfs)
109{
110 SCIP_NODESELDATA* nodeseldata;
111
113
114 nodeseldata = SCIPnodeselGetData(nodesel);
115 assert(nodeseldata != NULL);
116
117 /* reset counters */
118 nodeseldata->lastrestart = 0;
119 nodeseldata->nprocessedleaves = 0;
120
121 return SCIP_OKAY;
122}
123
124
125/** node selection method of node selector */
126static
127SCIP_DECL_NODESELSELECT(nodeselSelectRestartdfs)
128{ /*lint --e{715}*/
129
130 assert(selnode != NULL);
131
133
134 /* decide if we want to select the node with lowest bound or the deepest node; finish the current dive in any case */
135 *selnode = SCIPgetPrioChild(scip);
136 if( *selnode == NULL )
137 {
138 SCIP_NODESELDATA* nodeseldata;
140
141 /* get node selector user data */
142 nodeseldata = SCIPnodeselGetData(nodesel);
143 assert(nodeseldata != NULL);
144
145 /* increase the number of processed leafs since we are in a leaf */
146 nodeseldata->nprocessedleaves++;
147
149
150 /* check if in case of "only leaves" the number processed leaves exceeds the frequency or in the other case the
151 * number of processed node does it
152 */
153 if( (nodeseldata->countonlyleaves && nodeseldata->nprocessedleaves >= nodeseldata->selectbestfreq)
154 || (!nodeseldata->countonlyleaves && nnodes - nodeseldata->lastrestart >= nodeseldata->selectbestfreq ) )
155 {
156 nodeseldata->lastrestart = nnodes;
157 nodeseldata->nprocessedleaves = 0;
158 *selnode = SCIPgetBestboundNode(scip);
159 }
160 else
161 {
162 *selnode = SCIPgetPrioSibling(scip);
163 if( *selnode == NULL )
164 *selnode = SCIPgetBestLeaf(scip);
165 }
166 }
167
168 return SCIP_OKAY;
169}
170
171
172/** node comparison method of node selector */
173static
174SCIP_DECL_NODESELCOMP(nodeselCompRestartdfs)
175{ /*lint --e{715}*/
176 return (int)(SCIPnodeGetNumber(node2) - SCIPnodeGetNumber(node1));
177}
178
179
180/*
181 * restartdfs specific interface methods
182 */
183
184/** creates the node selector for restarting depth first search and includes it in SCIP */
186 SCIP* scip /**< SCIP data structure */
187 )
188{
189 SCIP_NODESELDATA* nodeseldata;
190 SCIP_NODESEL* nodesel;
191
192 /* allocate and initialize node selector data; this has to be freed in the destructor */
193 SCIP_CALL( SCIPallocBlockMemory(scip, &nodeseldata) );
194 nodeseldata->lastrestart = 0;
195 nodeseldata->nprocessedleaves = 0;
196 nodeseldata->selectbestfreq = SELECTBESTFREQ;
197 nodeseldata->countonlyleaves = COUNTONLYLEAVES;
198
199 /* include node selector */
201 nodeselSelectRestartdfs, nodeselCompRestartdfs, nodeseldata) );
202
203 assert(nodesel != NULL);
204
205 SCIP_CALL( SCIPsetNodeselCopy(scip, nodesel, nodeselCopyRestartdfs) );
206 SCIP_CALL( SCIPsetNodeselFree(scip, nodesel, nodeselFreeRestartdfs) );
207 SCIP_CALL( SCIPsetNodeselInitsol(scip, nodesel, nodeselInitsolRestartdfs) );
208
209 /* add node selector parameters */
211 "nodeselection/restartdfs/selectbestfreq",
212 "frequency for selecting the best node instead of the deepest one",
213 &nodeseldata->selectbestfreq, FALSE, SELECTBESTFREQ, 0, INT_MAX, NULL, NULL) );
214
215 /* add node selector parameters */
217 "nodeselection/restartdfs/countonlyleaves",
218 "count only leaf nodes (otherwise all nodes)?",
219 &nodeseldata->countonlyleaves, FALSE, COUNTONLYLEAVES, NULL, NULL) );
220
221 return SCIP_OKAY;
222}
223
#define NULL
Definition def.h:257
#define SCIP_Longint
Definition def.h:150
#define SCIP_Bool
Definition def.h:100
#define SCIP_STRINGEQ(name, reference, retcode)
Definition def.h:454
#define FALSE
Definition def.h:103
#define SCIP_CALL(x)
Definition def.h:364
#define nnodes
Definition gastrans.c:74
SCIP_RETCODE SCIPincludeNodeselRestartdfs(SCIP *scip)
SCIP_RETCODE SCIPaddIntParam(SCIP *scip, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition scip_param.c:83
SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition scip_param.c:57
#define SCIPfreeBlockMemory(scip, ptr)
Definition scip_mem.h:108
#define SCIPallocBlockMemory(scip, ptr)
Definition scip_mem.h:89
SCIP_Longint SCIPnodeGetNumber(SCIP_NODE *node)
Definition tree.c:8513
SCIP_RETCODE SCIPincludeNodeselBasic(SCIP *scip, SCIP_NODESEL **nodesel, const char *name, const char *desc, int stdpriority, int memsavepriority, SCIP_DECL_NODESELSELECT((*nodeselselect)), SCIP_DECL_NODESELCOMP((*nodeselcomp)), SCIP_NODESELDATA *nodeseldata)
void SCIPnodeselSetData(SCIP_NODESEL *nodesel, SCIP_NODESELDATA *nodeseldata)
Definition nodesel.c:1273
SCIP_RETCODE SCIPsetNodeselFree(SCIP *scip, SCIP_NODESEL *nodesel,)
SCIP_RETCODE SCIPsetNodeselInitsol(SCIP *scip, SCIP_NODESEL *nodesel,)
SCIP_NODESELDATA * SCIPnodeselGetData(SCIP_NODESEL *nodesel)
Definition nodesel.c:1263
SCIP_RETCODE SCIPsetNodeselCopy(SCIP *scip, SCIP_NODESEL *nodesel,)
const char * SCIPnodeselGetName(SCIP_NODESEL *nodesel)
Definition nodesel.c:1195
SCIP_Longint SCIPgetNNodes(SCIP *scip)
SCIP_NODE * SCIPgetPrioSibling(SCIP *scip)
Definition scip_tree.c:304
SCIP_NODE * SCIPgetBestboundNode(SCIP *scip)
Definition scip_tree.c:384
SCIP_NODE * SCIPgetPrioChild(SCIP *scip)
Definition scip_tree.c:288
SCIP_NODE * SCIPgetBestLeaf(SCIP *scip)
Definition scip_tree.c:352
return SCIP_OKAY
assert(minobj< SCIPgetCutoffbound(scip))
#define NODESEL_NAME
Definition nodesel_bfs.c:47
#define NODESEL_MEMSAVEPRIORITY
Definition nodesel_bfs.c:50
#define NODESEL_STDPRIORITY
Definition nodesel_bfs.c:49
#define NODESEL_DESC
Definition nodesel_bfs.c:48
#define SELECTBESTFREQ
#define COUNTONLYLEAVES
node selector for depth first search with periodical selection of the best node
public methods for message output
public methods for node selectors
public methods for branch and bound tree
public methods for memory management
public methods for node selector plugins
public methods for SCIP parameter handling
public methods for querying solving statistics
public methods for the branch-and-bound tree
#define SCIP_DECL_NODESELCOMP(x)
#define SCIP_DECL_NODESELINITSOL(x)
struct SCIP_Nodesel SCIP_NODESEL
#define SCIP_DECL_NODESELCOPY(x)
#define SCIP_DECL_NODESELSELECT(x)
#define SCIP_DECL_NODESELFREE(x)
struct SCIP_NodeselData SCIP_NODESELDATA
@ SCIP_INVALIDCALL
enum SCIP_Retcode SCIP_RETCODE
struct Scip SCIP
Definition type_scip.h:39