SCIP

    Solving Constraint Integer Programs

    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)
    Definition: scip_nodesel.c:111
    void SCIPnodeselSetData(SCIP_NODESEL *nodesel, SCIP_NODESELDATA *nodeseldata)
    Definition: nodesel.c:1273
    SCIP_RETCODE SCIPsetNodeselFree(SCIP *scip, SCIP_NODESEL *nodesel, SCIP_DECL_NODESELFREE((*nodeselfree)))
    Definition: scip_nodesel.c:162
    SCIP_NODESELDATA * SCIPnodeselGetData(SCIP_NODESEL *nodesel)
    Definition: nodesel.c:1263
    SCIP_RETCODE SCIPsetNodeselCopy(SCIP *scip, SCIP_NODESEL *nodesel, SCIP_DECL_NODESELCOPY((*nodeselcopy)))
    Definition: scip_nodesel.c:146
    const char * SCIPnodeselGetName(SCIP_NODESEL *nodesel)
    Definition: nodesel.c:1195
    SCIP_RETCODE SCIPsetNodeselInitsol(SCIP *scip, SCIP_NODESEL *nodesel, SCIP_DECL_NODESELINITSOL((*nodeselinitsol)))
    Definition: scip_nodesel.c:210
    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
    static SCIP_DECL_NODESELCOMP(nodeselCompRestartdfs)
    #define SELECTBESTFREQ
    static SCIP_DECL_NODESELCOPY(nodeselCopyRestartdfs)
    #define NODESEL_NAME
    static SCIP_DECL_NODESELFREE(nodeselFreeRestartdfs)
    static SCIP_DECL_NODESELSELECT(nodeselSelectRestartdfs)
    #define NODESEL_MEMSAVEPRIORITY
    #define NODESEL_STDPRIORITY
    #define COUNTONLYLEAVES
    #define NODESEL_DESC
    static SCIP_DECL_NODESELINITSOL(nodeselInitsolRestartdfs)
    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
    struct SCIP_NodeselData SCIP_NODESELDATA
    Definition: type_nodesel.h:52
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    @ SCIP_INVALIDCALL
    Definition: type_retcode.h:51
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63