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   type_benders.h
17  * @ingroup TYPEDEFINITIONS
18  * @brief  type definitions for Benders' decomposition methods
19  * @author Stephen J. Maher
20  */
21 
22 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
23 
24 #ifndef __SCIP_TYPE_BENDERS_H__
25 #define __SCIP_TYPE_BENDERS_H__
26 
27 #include "scip/def.h"
28 #include "scip/type_retcode.h"
29 #include "scip/type_scip.h"
30 
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34 
35 enum SCIP_BendersEnfoType
36 {
37     SCIP_BENDERSENFOTYPE_LP      = 1,        /**< the Benders' subproblems are solved during the enforcement of an LP solution */
38     SCIP_BENDERSENFOTYPE_RELAX   = 2,        /**< the Benders' subproblems are solved during the enforcement of a relaxation solution */
39     SCIP_BENDERSENFOTYPE_PSEUDO  = 3,        /**< the Benders' subproblems are solved during the enforcement of a pseudo solution */
40     SCIP_BENDERSENFOTYPE_CHECK   = 4         /**< the Benders' subproblems are solved during the checking of a solution for feasibility */
41 };
42 typedef enum SCIP_BendersEnfoType SCIP_BENDERSENFOTYPE;  /**< indicates the callback in cons_benders and cons_benderslp that triggered the subproblem solve */
43 
44 enum SCIP_BendersSolveLoop
45 {
46    SCIP_BENDERSSOLVELOOP_CONVEX     = 0,     /**< the relaxation is solved in this iteration of the loop */
47    SCIP_BENDERSSOLVELOOP_CIP        = 1,     /**< the CIP is solved in this iteration of the loop */
48    SCIP_BENDERSSOLVELOOP_USERCONVEX = 2,     /**< the user defined solve function is called */
49    SCIP_BENDERSSOLVELOOP_USERCIP    = 3      /**< the user defined solve function is called */
50 };
51 typedef enum SCIP_BendersSolveLoop SCIP_BENDERSSOLVELOOP;   /**< identifies the type of problem solved in each solve loop */
52 
53 enum SCIP_BendersSubStatus
54 {
55    SCIP_BENDERSSUBSTATUS_UNKNOWN    = 0,     /**< the subsystem status is unknown */
56    SCIP_BENDERSSUBSTATUS_OPTIMAL    = 1,     /**< the subsystem is solved to be optimal */
57    SCIP_BENDERSSUBSTATUS_AUXVIOL    = 2,     /**< the subproblem is optimal, but the auxiliary variable is violated */
58    SCIP_BENDERSSUBSTATUS_INFEAS     = 3      /**< the subproblem is solved to be infeasible */
59 };
60 typedef enum SCIP_BendersSubStatus SCIP_BENDERSSUBSTATUS;
61 
62 enum SCIP_BendersSubType
63 {
64    SCIP_BENDERSSUBTYPE_CONVEXCONT      = 0,  /**< the subproblem has convex constraints and continuous variables */
65    SCIP_BENDERSSUBTYPE_CONVEXDIS       = 1,  /**< the subproblem has convex constraints and discrete variables */
66    SCIP_BENDERSSUBTYPE_NONCONVEXCONT   = 2,  /**< the subproblem has non-convex constraints and continuous variables */
67    SCIP_BENDERSSUBTYPE_NONCONVEXDIS    = 3,  /**< the subproblem has non-convex constraints and discrete variables */
68    SCIP_BENDERSSUBTYPE_UNKNOWN         = 4,  /**< the default type before the type is known */
69 };
70 typedef enum SCIP_BendersSubType SCIP_BENDERSSUBTYPE;
71 
72 typedef struct SCIP_Benders SCIP_BENDERS;           /**< Benders' decomposition data */
73 typedef struct SCIP_BendersData SCIP_BENDERSDATA;   /**< locally defined Benders' decomposition data */
74 typedef struct SCIP_SubproblemSolveStat SCIP_SUBPROBLEMSOLVESTAT; /**< the solving statistics of the subproblems */
75 
76 
77 /** copy method for Benders' decomposition plugins (called when SCIP copies plugins). If there is an active Benders'
78  *  decomposition, all copies are not valid. As such, there is no valid parameter that is passed to the callback
79  *  function
80  *
81  *  input:
82  *  - scip            : SCIP main data structure
83  *  - benders         : the Benders' decomposition itself
84  *  - threadsafe      : must the Benders' decomposition copy be thread safe
85  */
86 #define SCIP_DECL_BENDERSCOPY(x) SCIP_RETCODE x (SCIP* scip, SCIP_BENDERS* benders, SCIP_Bool threadsafe)
87 
88 /** destructor of Benders' decomposition to free user data (called when SCIP is exiting)
89  *
90  *  input:
91  *  - scip            : SCIP main data structure
92  *  - benders         : the Benders' decomposition itself
93  */
94 #define SCIP_DECL_BENDERSFREE(x) SCIP_RETCODE x (SCIP* scip, SCIP_BENDERS* benders)
95 
96 /** initialization method of Benders' decomposition (called after problem was transformed and the Benders' decomposition
97  * is active)
98  *
99  *  input:
100  *  - scip            : SCIP main data structure
101  *  - benders         : the Benders' decomposition itself
102  */
103 #define SCIP_DECL_BENDERSINIT(x) SCIP_RETCODE x (SCIP* scip, SCIP_BENDERS* benders)
104 
105 /** deinitialization method of Benders' decomposition (called before transformed problem is freed and the Benders'
106  * decomposition is active)
107  *
108  *  input:
109  *  - scip            : SCIP main data structure
110  *  - benders         : the Benders' decomposition itself
111  */
112 #define SCIP_DECL_BENDERSEXIT(x) SCIP_RETCODE x (SCIP* scip, SCIP_BENDERS* benders)
113 
114 /** presolving initialization method of the Benders' decomposition (called when presolving is about to begin)
115  *
116  *  This function is called immediately after the auxiliary variables are created in the master problem. The callback
117  *  provides the user an opportunity to add variable data to the auxiliary variables.
118  *
119  *  input:
120  *  - scip            : SCIP main data structure
121  *  - benders         : the Benders' decomposition itself
122  */
123 #define SCIP_DECL_BENDERSINITPRE(x) SCIP_RETCODE x (SCIP* scip, SCIP_BENDERS* benders)
124 
125 /** presolving deinitialization method of the Benders' decomposition (called after presolving has been finished)
126  *
127  *  input:
128  *  - scip            : SCIP main data structure
129  *  - benders         : the Benders' decomposition itself
130  */
131 #define SCIP_DECL_BENDERSEXITPRE(x) SCIP_RETCODE x (SCIP* scip, SCIP_BENDERS* benders)
132 
133 /** solving process initialization method of Benders' decomposition (called when branch and bound process is about to begin)
134  *
135  *  This method is called when the presolving was finished and the branch and bound process is about to begin.
136  *  The Benders' decomposition may use this call to initialize its branch and bound specific data.
137  *
138  *  input:
139  *  - scip            : SCIP main data structure
140  *  - benders         : the Benders' decomposition itself
141  */
142 #define SCIP_DECL_BENDERSINITSOL(x) SCIP_RETCODE x (SCIP* scip, SCIP_BENDERS* benders)
143 
144 /** solving process deinitialization method of Benders' decomposition (called before branch and bound process data is freed)
145  *
146  *  This method is called before the branch and bound process is freed.
147  *  The Benders' decomposition should use this call to clean up its branch and bound data.
148  *
149  *  input:
150  *  - scip            : SCIP main data structure
151  *  - benders         : the Benders' decomposition itself
152  */
153 #define SCIP_DECL_BENDERSEXITSOL(x) SCIP_RETCODE x (SCIP* scip, SCIP_BENDERS* benders)
154 
155 /** the method for creating the Benders' decomposition subproblem. This method is called during the initialisation stage
156  *  (after the master problem was transformed).
157  *
158  *  @note When the create subproblem callback is invoked, the mapping between the  master problem and subproblem
159  *  variables must be available. The create subproblem callback is invoked immediately after BENDERSINIT. So, it is
160  *  possible to construct the variable mapping within the BENDERSINIT callback.
161  *
162  *  This method must register the SCIP instance for the subproblem with the Benders' decomposition core by calling
163  *  SCIPaddBendersSubproblem. Typically, the user must create the SCIP instances for the subproblems. These can be
164  *  created within a reader or probdata and then registered with the Benders' decomposition core during the call of this
165  *  callback. If there are any settings required for solving the subproblems, then they should be set here. However,
166  *  some settings will be overridden by the standard solving method included in the Benders' decomposition framework.
167  *  If a special solving method is desired, the user can implement the bendersSolvesubXyz callback. In this latter case,
168  *  it is possible to provide a NULL pointer to SCIPaddBendersSubproblem. This will ensure that no internal solving
169  *  methods available within the Benders' decomposition core are invoked during the solving process.
170  *
171  *  If the user defines a subproblem solving method, then in BENDERSCREATESUB, the user must specify whether the
172  *  subproblem is convex. This is necessary because the dual solutions from convex problems can be used to generate cuts.
173  *  The classical Benders' optimality and feasibility cuts require that the subproblems are convex. If the subproblem is
174  *  convex, then the user must call SCIPbendersSetSubproblemIsConvex()
175  *
176  *  If the user does NOT implement a subproblem solving method, then the convexity of the problem is determined
177  *  internally.
178  *
179  *  input:
180  *  - scip            : SCIP main data structure
181  *  - benders         : the Benders' decomposition data structure
182  *  - probnumber      : the subproblem problem number
183  */
184 #define SCIP_DECL_BENDERSCREATESUB(x) SCIP_RETCODE x (SCIP* scip, SCIP_BENDERS* benders, int probnumber)
185 
186 /** called before the subproblem solving loop for Benders' decomposition. The pre subproblem solve function gives the
187  *  user an oppportunity to perform any global set up for the Benders' decomposition.
188  *
189  *  input:
190  *  - scip            : SCIP main data structure
191  *  - benders         : the Benders' decomposition data structure
192  *  - sol             : the solution that will be checked in the subproblem. Can be NULL.
193  *  - type            : the enforcement type that called the Benders' decomposition solve.
194  *  - checkint        : should the integer subproblems be checked.
195  *  - infeasible      : flag to return whether the master problem in infeasible with respect to the added cuts
196  *  - auxviol         : set to TRUE only if the solution is feasible but the aux vars are violated
197  *  - skipsolve       : flag to return whether the current subproblem solving loop should be skipped
198  *  - result          : a result to be returned to the Benders' constraint handler if the solve is skipped. If the
199  *                      solve is not skipped, then the returned result is ignored.
200  *
201  *  possible return values for *result (if more than one applies, the first in the list should be used):
202  *  - SCIP_DIDNOTRUN  : the subproblem was not solved in this iteration. Other decompositions will be checked.
203  *  - SCIP_CONSADDED  : a constraint has been added to the master problem. No other decompositions will be checked.
204  *  - SCIP_SEPARATED  : a cut has been added to the master problem. No other decompositions will be checked.
205  *  - SCIP_FEASIBLE   : feasibility of the solution is reported to SCIP. Other decompositions will be checked.
206  *  - SCIP_INFEASIBLE : infeasibility of the solution is reported to SCIP. No other decompositions will be checked.
207  */
208 #define SCIP_DECL_BENDERSPRESUBSOLVE(x) SCIP_RETCODE x (SCIP* scip, SCIP_BENDERS* benders, SCIP_SOL* sol,\
209    SCIP_BENDERSENFOTYPE type, SCIP_Bool checkint, SCIP_Bool* infeasible, SCIP_Bool* auxviol, SCIP_Bool* skipsolve,\
210    SCIP_RESULT* result)
211 
212 /** the solving method for a convex Benders' decomposition subproblem. This call back is provided to solve problems
213  *  for which the dual soluitons are used to generate Benders' decomposition cuts. In the classical Benders'
214  *  decomposition implementation, this would be an LP. However, it can be any convex problem where the dual solutions
215  *  are given by a single vector of reals.
216  *
217  *  In the Benders' decomposition subproblem solving process, there are two solving loops. The first is where the convex
218  *  subproblems, and the convex relaxations of subproblems, are solved. If no cuts are generated after this solving
219  *  loop, then the second loop solves subproblems defined as CIPs. This callback is executed during the FIRST solving
220  *  loop only.
221  *
222  *  In the classical Benders' decomposition implementation, if the subproblems are all LPs the only the
223  *  BENDERSSOLVESUBCONVEX need to be implemented. If the subproblems are MIPs, then it is useful to only implement a
224  *  single SCIP instance for the subproblem and then change the variable types of the appropriate variables to
225  *  CONTINUOUS for the CONVEX subproblem solve and to INTEGER for the CIP subproblem solve.
226  *
227  *  The solving methods are separated so that they can be called in parallel.
228  *
229  *  NOTE: The solving methods must be thread safe.
230  *
231  *  This method is called from within the execution method.
232  *
233  *  input:
234  *  - scip            : SCIP main data structure
235  *  - benders         : the Benders' decomposition data structure
236  *  - sol             : the solution that will be checked in the subproblem. Can be NULL.
237  *  - probnumber      : the subproblem problem number
238  *  - onlyconvexcheck : flag to indicate that only the convex relaxations will be checked in this solving loop. This is
239  *                      a feature of the Large Neighbourhood Benders' Search
240  *  - objective       : variable to return the objective function value of the subproblem
241  *  - result          : the result from solving the subproblem
242  *
243  *  possible return values for *result (if more than one applies, the first in the list should be used):
244  *  - SCIP_DIDNOTRUN  : the subproblem was not solved in this iteration
245  *  - SCIP_FEASIBLE   : the subproblem is solved and is feasible
246  *  - SCIP_INFEASIBLE : the subproblem is solved and is infeasible
247  *  - SCIP_UNBOUNDED  : the subproblem is solved and is unbounded
248  */
249 #define SCIP_DECL_BENDERSSOLVESUBCONVEX(x) SCIP_RETCODE x (SCIP* scip, SCIP_BENDERS* benders, SCIP_SOL* sol,\
250    int probnumber, SCIP_Bool onlyconvexcheck, SCIP_Real* objective, SCIP_RESULT* result)
251 
252 /** the solving method for a Benders' decomposition subproblem as a CIP. This call back is provided to solve problems
253  *  for which the dual solutions are not well defined. In this case, the cuts are typically generated from the primal
254  *  solution to the CIP. In the classical Benders' decomposition implementation, this would be a MIP. However, it can
255  *  be any CIP.
256  *
257  *  In the Benders' decomposition subproblem solving process, there are two solving loops. The first is where the convex
258  *  subproblems, and the convex relaxations of subproblems, are solved. If no cuts are generated after this solving
259  *  loop, then the second loop solves subproblems defined as CIPs. This callback is executed during the SECOND solving
260  *  loop only.
261  *
262  *  The solving methods are separated so that they can be called in parallel.
263  *
264  *  NOTE: The solving methods must be thread safe.
265  *
266  *  This method is called from within the execution method.
267  *
268  *  input:
269  *  - scip            : SCIP main data structure
270  *  - benders         : the Benders' decomposition data structure
271  *  - sol             : the solution that will be checked in the subproblem. Can be NULL.
272  *  - probnumber      : the subproblem problem number
273  *  - objective       : variable to return the objective function value of the subproblem
274  *  - result          : the result from solving the subproblem
275  *
276  *  possible return values for *result (if more than one applies, the first in the list should be used):
277  *  - SCIP_DIDNOTRUN  : the subproblem was not solved in this iteration
278  *  - SCIP_FEASIBLE   : the subproblem is solved and is feasible
279  *  - SCIP_INFEASIBLE : the subproblem is solved and is infeasible
280  *  - SCIP_UNBOUNDED  : the subproblem is solved and is unbounded
281  */
282 #define SCIP_DECL_BENDERSSOLVESUB(x) SCIP_RETCODE x (SCIP* scip, SCIP_BENDERS* benders, SCIP_SOL* sol, int probnumber,\
283   SCIP_Real* objective, SCIP_RESULT* result)
284 
285 /** the post-solve method for Benders' decomposition. The post-solve method is called after the subproblems have
286  * been solved but before they have been freed. After the solving of the Benders' decomposition subproblems, the
287  * subproblem solving data is freed in the SCIP_DECL_BENDERSFREESUB callback. However, it is not necessary to implement
288  * SCIP_DECL_BENDERSFREESUB.
289  *
290  * If SCIP_DECL_BENDERSFREESUB is not implemented, then the Benders' decomposition framework will perform a default
291  * freeing of the subproblems. If a subproblem is an LP, then they will be in probing mode for the subproblem
292  * solve. So the freeing process involves ending the probing mode. If the subproblem is a MIP, then the subproblem is
293  * solved by calling SCIPsolve. As such, the transformed problem must be freed after each subproblem solve.
294  *
295  * This callback provides the opportunity for the user to clean up any data structures that should not exist beyond the current
296  * iteration.
297  * The user has full access to the master and subproblems in this callback. So it is possible to construct solution for
298  * the master problem in the method.
299  * Additionally, if there are any subproblems that are infeasibility and this can not be resolved, then the it is
300  * possible to merge these subproblems into the master problem. The subproblem indices are given in the mergecands
301  * array. The merging can be perform by a user defined function or by calling SCIPmergeBendersSubproblemIntoMaster. If a
302  * subproblem was merged into the master problem, then the merged flag must be set to TRUE.
303  *
304  *  input:
305  *  - scip            : SCIP main data structure
306  *  - benders         : the Benders' decomposition data structure
307  *  - sol             : the solution that was checked by solving the subproblems. Can be NULL.
308  *  - type            : the enforcement type that called the Benders' decomposition solve.
309  *  - mergecands      : the subproblems that are candidates for merging into the master problem, the first
310  *                      npriomergecands are the priority candidates (they should be merged). The remaining
311  *                      (nmergecands - npriomergecands) are subproblems that could be merged if desired.
312  *  - npriomergecands : the number of priority merge candidates.
313  *  - nmergecands     : the total number of subproblems that are candidates for merging into the master problem
314  *  - checkint        : should the integer subproblems be checked.
315  *  - infeasible      : indicates whether at least one subproblem is infeasible
316  *  - merged          : flag to indicate whether a subproblem was merged into the master problem.
317  */
318 #define SCIP_DECL_BENDERSPOSTSOLVE(x) SCIP_RETCODE x (SCIP* scip, SCIP_BENDERS* benders, SCIP_SOL* sol,\
319    SCIP_BENDERSENFOTYPE type, int* mergecands, int npriomergecands, int nmergecands, SCIP_Bool checkint,\
320    SCIP_Bool infeasible, SCIP_Bool* merged)
321 
322 /** frees the subproblem so that it can be resolved in the next iteration. As stated above, it is not necessary to
323  *  implement this callback. If the callback is implemented, the subproblems should be freed by calling
324  *  SCIPfreeTransform(). However, if the subproblems are LPs, then it could be more efficient to put the subproblem
325  *  into probing mode prior to solving and then exiting the probing mode during the callback. To put the subproblem into
326  *  probing mode, the subproblem must be in SCIP_STAGE_SOLVING. This can be achieved by using eventhandlers.
327  *
328  *  If SCIP_DECL_BENDERSFREESUB is not implemented, then the Benders' decomposition framework will perform a default
329  *  freeing of the subproblems. If a subproblem is an LP, then they will be in probing mode for the subproblem
330  *  solve. So the freeing process involves ending the probing mode. If the subproblem is a MIP, then the subproblem is
331  *  solved by calling SCIPsolve. As such, the transformed problem must be freed after each subproblem solve.
332  *
333  *  NOTE: The freeing methods must be thread safe.
334  *
335  *  input:
336  *  - scip            : SCIP main data structure
337  *  - benders         : the Benders' decomposition data structure
338  *  - probnumber      : the subproblem problem number
339  */
340 #define SCIP_DECL_BENDERSFREESUB(x) SCIP_RETCODE x (SCIP* scip, SCIP_BENDERS* benders, int probnumber)
341 
342 /** the variable mapping from the subproblem to the master problem. It is neccessary to have a mapping between every
343  *  master problem variable and its counterpart in the subproblem. This mapping must go both ways: from master to sub
344  *  and sub to master.
345  *
346  *  This method is called when generating the cuts. The cuts are generated by using the solution to the subproblem to
347  *  eliminate a solution to the master problem.
348  *
349  *  input:
350  *  - scip            : SCIP main data structure
351  *  - benders         : the Benders' decomposition structure
352  *  - var             : the variable for which the corresponding variable in the master or subproblem is required
353  *  - mappedvar       : pointer to store the variable that is mapped to var
354  *  - probnumber      : the number of the subproblem that the desired variable belongs to, -1 for the master problem
355  */
356 #define SCIP_DECL_BENDERSGETVAR(x) SCIP_RETCODE x (SCIP* scip, SCIP_BENDERS* benders, SCIP_VAR* var,\
357    SCIP_VAR** mappedvar, int probnumber)
358 
359 #ifdef __cplusplus
360 }
361 #endif
362 
363 #endif
364