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-2024 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 
47 using namespace tsp;
48 using namespace std;
49 
50 
51 /** destructor of event handler to free user data (called when SCIP is exiting) */
52 SCIP_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) */
59 SCIP_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) */
95 SCIP_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  */
107 SCIP_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  */
120 SCIP_DECL_EVENTEXITSOL(EventhdlrNewSol::scip_exitsol)
121 {
123 
124  return SCIP_OKAY;
125 }
126 
127 
128 /** frees specific constraint data */
129 SCIP_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  */
142 SCIP_DECL_EVENTEXEC(EventhdlrNewSol::scip_exec)
143 { /*lint --e{715}*/
144  SCIP_SOL* sol = SCIPgetBestSol(scip);
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 }
struct GraphEdge * next
Definition: GomoryHuTree.h:69
#define NULL
Definition: def.h:267
int nnodes
Definition: GomoryHuTree.h:82
GRAPHNODE * nodes
Definition: GomoryHuTree.h:86
SCIP_DECL_EVENTEXIT(EventhdlrNewSol::scip_exit)
generator for global cuts in undirected graphs
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:120
SCIP_DECL_EVENTINITSOL(EventhdlrNewSol::scip_initsol)
SCIP_Bool SCIPfileExists(const char *filename)
Definition: misc.c:11079
SCIP_DECL_EVENTINIT(EventhdlrNewSol::scip_init)
SCIP_VAR * var
Definition: GomoryHuTree.h:74
SCIP_DECL_EVENTFREE(EventhdlrNewSol::scip_free)
const char * SCIPheurGetName(SCIP_HEUR *heur)
Definition: heur.c:1453
Definition: pqueue.h:37
GRAPHNODE * adjac
Definition: GomoryHuTree.h:72
struct GraphEdge * back
Definition: GomoryHuTree.h:70
struct GraphEdge * first_edge
Definition: GomoryHuTree.h:53
C++ wrapper classes for SCIP.
#define SCIP_CALL(x)
Definition: def.h:380
event handler for new solutions in TSP
GRAPH * getGraph()
Definition: ProbDataTSP.h:97
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:286
SCIP_RETCODE SCIPdropEvent(SCIP *scip, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
Definition: scip_event.c:320
SCIP_Real SCIPgetSolOrigObj(SCIP *scip, SCIP_SOL *sol)
Definition: scip_sol.c:1300
scip::ObjProbData * SCIPgetObjProbData(SCIP *scip)
#define SCIP_EVENTTYPE_BESTSOLFOUND
Definition: type_event.h:105
SCIP_SOL * SCIPgetBestSol(SCIP *scip)
Definition: scip_sol.c:2169
double x
Definition: GomoryHuTree.h:45
SCIP_DECL_EVENTEXEC(EventhdlrNewSol::scip_exec)
SCIP_HEUR * SCIPgetSolHeur(SCIP *scip, SCIP_SOL *sol)
Definition: scip_sol.c:1540
SCIP_DECL_EVENTEXITSOL(EventhdlrNewSol::scip_exitsol)
double y
Definition: GomoryHuTree.h:46
SCIP_DECL_EVENTDELETE(EventhdlrNewSol::scip_delete)
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip_sol.c:1217