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