Scippy

GCG

Branch-and-Price & Column Generation for Everyone

event_relaxsol.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program */
4 /* GCG --- Generic Column Generation */
5 /* a Dantzig-Wolfe decomposition based extension */
6 /* of the branch-cut-and-price framework */
7 /* SCIP --- Solving Constraint Integer Programs */
8 /* */
9 /* Copyright (C) 2010-2021 Operations Research, RWTH Aachen University */
10 /* Zuse Institute Berlin (ZIB) */
11 /* */
12 /* This program is free software; you can redistribute it and/or */
13 /* modify it under the terms of the GNU Lesser General Public License */
14 /* as published by the Free Software Foundation; either version 3 */
15 /* of the License, or (at your option) any later version. */
16 /* */
17 /* This program is distributed in the hope that it will be useful, */
18 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
19 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
20 /* GNU Lesser General Public License for more details. */
21 /* */
22 /* You should have received a copy of the GNU Lesser General Public License */
23 /* along with this program; if not, write to the Free Software */
24 /* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.*/
25 /* */
26 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
27 
28 /**@file event_relaxsol.c
29  * @brief eventhandler to update the relaxation solution in the original problem when the master LP has been solved
30  * @author Christian Puchert
31  */
32 
33 /*--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
34 
35 #include <string.h>
36 #include "event_relaxsol.h"
37 #include "relax_gcg.h"
38 #include "pricer_gcg.h"
39 #include "gcg.h"
40 #include "event_mastersol.h"
41 
42 #define EVENTHDLR_NAME "relaxsol"
43 #define EVENTHDLR_DESC "eventhandler to update the relaxation solution in the original problem when the master LP has been solved"
44 
45 
46 /*
47  * Data structures
48  */
49 
50 /** event handler data */
51 struct SCIP_EventhdlrData
52 {
53  SCIP_Bool triggered; /**< flag to indicate whether event has been triggered */
54 };
55 
56 
57 /*
58  * Callback methods of event handler
59  */
60 
61 /** destructor of event handler to free user data (called when SCIP is exiting) */
62 static
63 SCIP_DECL_EVENTFREE(eventFreeRelaxsol)
64 { /*lint --e{715}*/
65  SCIP_EVENTHDLRDATA* eventhdlrdata;
66 
67  assert(scip != NULL);
68  assert(eventhdlr != NULL);
69  assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
70 
71  eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
72  assert(eventhdlrdata != NULL);
73 
74  SCIPfreeMemory(scip, &eventhdlrdata);
75  SCIPeventhdlrSetData(eventhdlr, NULL);
76 
77  return SCIP_OKAY;
78 }
79 
80 /** initialization method of event handler (called after problem was transformed) */
81 static
82 SCIP_DECL_EVENTINIT(eventInitRelaxsol)
83 { /*lint --e{715}*/
84  SCIP_EVENTHDLRDATA* eventhdlrdata;
85 
86  eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
87  assert(eventhdlrdata != NULL);
88 
89  /* notify SCIP that your event handler wants to react on the event type lp solved and solution found */
90  SCIP_CALL( SCIPcatchEvent(scip, SCIP_EVENTTYPE_LPSOLVED | SCIP_EVENTTYPE_SOLFOUND, eventhdlr, NULL, NULL) );
91  eventhdlrdata->triggered = FALSE;
92 
93  return SCIP_OKAY;
94 }
95 
96 /** deinitialization method of event handler (called before transformed problem is freed) */
97 static
98 SCIP_DECL_EVENTEXIT(eventExitRelaxsol)
99 { /*lint --e{715}*/
100 
101  /* notify SCIP that your event handler wants to drop the event type lp solved and solution found */
102  SCIP_CALL( SCIPdropEvent(scip, SCIP_EVENTTYPE_LPSOLVED | SCIP_EVENTTYPE_SOLFOUND, eventhdlr, NULL, -1) );
103 
104  return SCIP_OKAY;
105 }
106 
107 /** execution method of event handler */
108 static
109 SCIP_DECL_EVENTEXEC(eventExecRelaxsol)
110 { /*lint --e{715}*/
111  SCIP* origprob;
112  SCIP_EVENTHDLRDATA* eventhdlrdata;
113 
114  /* get original problem */
115  origprob = GCGmasterGetOrigprob(scip);
116  assert(origprob != NULL);
117 
118  eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
119  assert(eventhdlrdata != NULL);
120 
121  /* Only transfer the master solution if it is an LP solution or if it is a feasible solution that
122  * comes from a master heuristic; otherwise it is assumed to already come from the original problem
123  */
124  if( (SCIPeventGetType(event) & SCIP_EVENTTYPE_SOLFOUND) && SCIPsolGetHeur(SCIPeventGetSol(event)) == NULL
125  && GCGeventhdlrMastersolIsTriggered(origprob) )
126  return SCIP_OKAY;
127 
128  eventhdlrdata->triggered = TRUE;
129 
130  if( SCIPeventGetType(event) & SCIP_EVENTTYPE_LPSOLVED )
131  {
132  SCIPdebugMessage("Transferring master LP solution to the original problem\n");
133  SCIP_CALL( GCGrelaxUpdateCurrentSol(origprob) );
134  }
135  else if( SCIPeventGetType(event) & SCIP_EVENTTYPE_SOLFOUND )
136  {
137  SCIP_SOL* sol = SCIPeventGetSol(event);
138  SCIP_SOL* origsol;
139  SCIP_Bool stored;
140 
141  SCIPdebugMessage("Master feasible solution found by <%s> -- transferring to original problem\n",
142  SCIPsolGetHeur(sol) == NULL ? "relaxation" : SCIPheurGetName(SCIPsolGetHeur(sol)));
143 
144  /* transform the master solution to the original variable space */
145  SCIP_CALL( GCGtransformMastersolToOrigsol(origprob, sol, &origsol) );
146 
147  SCIP_CALL( SCIPtrySolFree(origprob, &origsol, FALSE, FALSE, TRUE, TRUE, TRUE, &stored) );
148  SCIPdebugMessage(" ->%s stored\n", stored ? "" : " not");
149  }
150 
151  eventhdlrdata->triggered = FALSE;
152 
153  return SCIP_OKAY;
154 }
155 
156 /** creates event handler for relaxsol event */
158  SCIP* scip /**< SCIP data structure */
159  )
160 {
161  SCIP_EVENTHDLR* eventhdlr;
162  SCIP_EVENTHDLRDATA* eventhdlrdata;
163 
164  eventhdlr = NULL;
165 
166  SCIP_CALL( SCIPallocMemory(scip, &eventhdlrdata) );
167  assert(eventhdlrdata != NULL);
168 
169  /* include event handler into GCG */
170  SCIP_CALL( SCIPincludeEventhdlrBasic(scip, &eventhdlr, EVENTHDLR_NAME, EVENTHDLR_DESC,
171  eventExecRelaxsol, eventhdlrdata) );
172  assert(eventhdlr != NULL);
173 
174  /* set non fundamental callbacks via setter functions */
175  SCIP_CALL( SCIPsetEventhdlrFree(scip, eventhdlr, eventFreeRelaxsol) );
176  SCIP_CALL( SCIPsetEventhdlrInit(scip, eventhdlr, eventInitRelaxsol) );
177  SCIP_CALL( SCIPsetEventhdlrExit(scip, eventhdlr, eventExitRelaxsol) );
178 
179  return SCIP_OKAY;
180 }
181 
182 /** return whether event has been triggered */
184  SCIP* scip, /**< SCIP data structure */
185  SCIP* masterprob /**< the SCIP data structure for the master problem */
186  )
187 {
188  SCIP_EVENTHDLR* eventhdlr;
189  SCIP_EVENTHDLRDATA* eventhdlrdata;
190 
191  assert(scip != NULL);
192  assert(masterprob != NULL);
193 
194  /* the relaxation solution event handler is not included if BENDERS or ORIGINAL mode is used. As such, it will
195  * never be triggered. In this case, it will always return FALSE.
196  */
198  return FALSE;
199 
200  eventhdlr = SCIPfindEventhdlr(masterprob, EVENTHDLR_NAME);
201  assert(eventhdlr != NULL);
202 
203  eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
204  assert(eventhdlrdata != NULL);
205 
206  return eventhdlrdata->triggered;
207 }
@ DEC_DECMODE_BENDERS
Definition: type_decomp.h:62
GCG interface methods.
@ DEC_DECMODE_ORIGINAL
Definition: type_decomp.h:63
GCG variable pricer.
SCIP_RETCODE GCGrelaxUpdateCurrentSol(SCIP *scip)
Definition: relax_gcg.c:4796
SCIP_Bool GCGeventhdlrRelaxsolIsTriggered(SCIP *scip, SCIP *masterprob)
static SCIP_DECL_EVENTEXIT(eventExitRelaxsol)
SCIP_Bool GCGeventhdlrMastersolIsTriggered(SCIP *scip)
SCIP_RETCODE GCGtransformMastersolToOrigsol(SCIP *scip, SCIP_SOL *mastersol, SCIP_SOL **origsol)
Definition: misc.c:120
DEC_DECMODE GCGgetDecompositionMode(SCIP *scip)
Definition: relax_gcg.c:5123
static SCIP_DECL_EVENTINIT(eventInitRelaxsol)
SCIP_RETCODE SCIPincludeEventHdlrRelaxsol(SCIP *scip)
SCIP * GCGmasterGetOrigprob(SCIP *scip)
eventhdlr to transfer solutions found in the original problem to the master problem
#define EVENTHDLR_DESC
eventhandler to update the relaxation solution in the original problem when the master LP has been so...
GCG relaxator.
static SCIP_DECL_EVENTEXEC(eventExecRelaxsol)
#define EVENTHDLR_NAME
static SCIP_DECL_EVENTFREE(eventFreeRelaxsol)