Scippy

    SCIP

    Solving Constraint Integer Programs

    EventhdlrNewSol.cpp
    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-2025 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 EventhdlrNewSol.cpp
    26 * @brief event handler for new solutions in TSP
    27 * @author Timo Berthold
    28 */
    29
    30/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    31
    32#include <cassert>
    33#include <fstream>
    34#include <iostream>
    35#ifndef _MSC_VER
    36#include <unistd.h>
    37#else
    38#include <windows.h>
    39#define sleep Sleep
    40#endif
    41
    42#include "objscip/objscip.h"
    43#include "EventhdlrNewSol.h"
    44#include "ProbDataTSP.h"
    45#include "GomoryHuTree.h"
    46
    47using namespace tsp;
    48using namespace std;
    49
    50
    51/** destructor of event handler to free user data (called when SCIP is exiting) */
    52SCIP_DECL_EVENTFREE(EventhdlrNewSol::scip_free)
    53{ /*lint --e{715}*/
    54 return SCIP_OKAY;
    55}
    56
    57
    58/** initialization method of event handler (called after problem was transformed) */
    59SCIP_DECL_EVENTINIT(EventhdlrNewSol::scip_init)
    60{ /*lint --e{715}*/
    61 int lockwaits = 0;
    62
    63 while( SCIPfileExists("temp.tour.lock") && lockwaits < 10 )
    64 {
    65 /* wait one second and try again */
    66 (void) sleep(1);
    67 lockwaits++;
    68 }
    69
    70 if( SCIPfileExists("temp.tour.lock") )
    71 {
    72 SCIPwarningMessage(scip, "cannot reset, because lockfile <temp.tour.lock> is still existing\n");
    73 return SCIP_OKAY;
    74 }
    75
    76 /* create lock file */
    77 ofstream lockfile("temp.tour.lock");
    78 lockfile << "lock" << endl;
    79 lockfile.close();
    80
    81 // create output file which can be read by TSPViewer
    82 ofstream filedata("temp.tour");
    83 filedata << "RESET" << endl;
    84 filedata.close();
    85
    86 /* delete lock file */
    87 (void) unlink("temp.tour.lock");
    88 (void) sleep(1); /* wait for the Java TSPViewer */
    89
    90 return SCIP_OKAY;
    91}
    92
    93
    94/** deinitialization method of event handler (called before transformed problem is freed) */
    95SCIP_DECL_EVENTEXIT(EventhdlrNewSol::scip_exit)
    96{ /*lint --e{715}*/
    97 return SCIP_OKAY;
    98}
    99
    100
    101/** solving process initialization method of event handler (called when branch and bound process is about to begin)
    102 *
    103 * This method is called when the presolving was finished and the branch and bound process is about to begin.
    104 * The event handler may use this call to initialize its branch and bound specific data.
    105 *
    106 */
    107SCIP_DECL_EVENTINITSOL(EventhdlrNewSol::scip_initsol)
    108{
    110
    111 return SCIP_OKAY;
    112}
    113
    114
    115/** solving process deinitialization method of event handler (called before branch and bound process data is freed)
    116 *
    117 * This method is called before the branch and bound process is freed.
    118 * The event handler should use this call to clean up its branch and bound data.
    119 */
    120SCIP_DECL_EVENTEXITSOL(EventhdlrNewSol::scip_exitsol)
    121{
    123
    124 return SCIP_OKAY;
    125}
    126
    127
    128/** frees specific constraint data */
    129SCIP_DECL_EVENTDELETE(EventhdlrNewSol::scip_delete)
    130{ /*lint --e{715}*/
    131 return SCIP_OKAY;
    132}
    133
    134
    135/** execution method of event handler
    136 *
    137 * Processes the event. The method is called every time an event occurs, for which the event handler
    138 * is responsible. Event handlers may declare themselves resposible for events by calling the
    139 * corresponding SCIPcatch...() method. This method creates an event filter object to point to the
    140 * given event handler and event data.
    141 */
    142SCIP_DECL_EVENTEXEC(EventhdlrNewSol::scip_exec)
    143{ /*lint --e{715}*/
    145 ProbDataTSP* probdata = dynamic_cast<ProbDataTSP*>(SCIPgetObjProbData(scip));
    146 GRAPH* graph = probdata->getGraph(); /*lint !e613*/
    147 GRAPHNODE* node = &graph->nodes[0];
    148 GRAPHEDGE* lastedge = NULL;
    149 int lockwaits = 0;
    150
    151 /* wait for lock file to disappear */
    152 while( SCIPfileExists("temp.tour.lock") && lockwaits < 10 )
    153 {
    154 /* wait one second and try again */
    155 (void) sleep(1);
    156 lockwaits++;
    157 }
    158
    159 if( SCIPfileExists("temp.tour.lock") )
    160 {
    161 SCIPwarningMessage(scip, "cannot output tour in file, because lockfile <temp.tour.lock> is still existing\n");
    162 return SCIP_OKAY;
    163 }
    164
    165 /* create lock file */
    166 ofstream lockfile("temp.tour.lock");
    167 lockfile << "lock" << endl;
    168 lockfile.close();
    169
    170 // create output file which can be read by TSPViewer
    171 ofstream filedata("temp.tour");
    172 filedata << graph->nnodes << endl;
    173
    174 SCIP_HEUR* heur = SCIPgetSolHeur(scip, sol);
    175 if ( heur == NULL)
    176 filedata << "relaxation" << endl;
    177 else
    178 filedata << SCIPheurGetName(heur) << endl;
    179
    180 filedata << SCIPgetSolOrigObj(scip,sol) << endl;
    181 do
    182 {
    183 // output the number of nodes
    184 filedata << node->id << " " << node->x << " " << node->y << endl;
    185 GRAPHEDGE* edge = node->first_edge;
    186
    187 // output the id and the coordinates of the nodes in the order they appear in the tour
    188
    189 while( edge != NULL)
    190 {
    191 if( edge->back != lastedge && SCIPgetSolVal(scip, sol, edge->var) > 0.5 )
    192 {
    193 node = edge->adjac;
    194 lastedge = edge;
    195 break;
    196 }
    197 edge = edge->next;
    198 }
    199 }
    200 while ( node != &graph->nodes[0] );
    201
    202 filedata.close();
    203
    204 /* delete lock file */
    205 (void) unlink("temp.tour.lock");
    206 (void) sleep(1); /* wait for the Java TSPViewer */
    207
    208 return SCIP_OKAY;
    209}
    SCIP_DECL_EVENTDELETE(EventhdlrNewSol::scip_delete)
    SCIP_DECL_EVENTEXEC(EventhdlrNewSol::scip_exec)
    SCIP_DECL_EVENTINIT(EventhdlrNewSol::scip_init)
    SCIP_DECL_EVENTINITSOL(EventhdlrNewSol::scip_initsol)
    SCIP_DECL_EVENTEXIT(EventhdlrNewSol::scip_exit)
    SCIP_DECL_EVENTEXITSOL(EventhdlrNewSol::scip_exitsol)
    SCIP_DECL_EVENTFREE(EventhdlrNewSol::scip_free)
    event handler for new solutions in TSP
    generator for global cuts in undirected graphs
    C++ problem data for TSP.
    GRAPH * getGraph()
    Definition: ProbDataTSP.h:97
    #define NULL
    Definition: def.h:248
    #define SCIP_CALL(x)
    Definition: def.h:355
    SCIP_Bool SCIPfileExists(const char *filename)
    Definition: misc.c:11057
    void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
    Definition: scip_message.c:120
    SCIP_RETCODE SCIPcatchEvent(SCIP *scip, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
    Definition: scip_event.c:293
    SCIP_RETCODE SCIPdropEvent(SCIP *scip, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
    Definition: scip_event.c:333
    const char * SCIPheurGetName(SCIP_HEUR *heur)
    Definition: heur.c:1467
    SCIP_SOL * SCIPgetBestSol(SCIP *scip)
    Definition: scip_sol.c:2981
    SCIP_HEUR * SCIPgetSolHeur(SCIP *scip, SCIP_SOL *sol)
    Definition: scip_sol.c:2249
    SCIP_Real SCIPgetSolOrigObj(SCIP *scip, SCIP_SOL *sol)
    Definition: scip_sol.c:1892
    SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
    Definition: scip_sol.c:1765
    Definition: pqueue.h:38
    scip::ObjProbData * SCIPgetObjProbData(SCIP *scip)
    C++ wrapper classes for SCIP.
    struct GraphEdge * back
    Definition: GomoryHuTree.h:70
    GRAPHNODE * adjac
    Definition: GomoryHuTree.h:72
    SCIP_VAR * var
    Definition: GomoryHuTree.h:74
    struct GraphEdge * next
    Definition: GomoryHuTree.h:69
    struct GraphEdge * first_edge
    Definition: GomoryHuTree.h:53
    double y
    Definition: GomoryHuTree.h:46
    double x
    Definition: GomoryHuTree.h:45
    GRAPHNODE * nodes
    Definition: GomoryHuTree.h:86
    int nnodes
    Definition: GomoryHuTree.h:82
    #define SCIP_EVENTTYPE_BESTSOLFOUND
    Definition: type_event.h:106
    @ SCIP_OKAY
    Definition: type_retcode.h:42