Scippy

SCIP

Solving Constraint Integer Programs

heur_sync.c
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 heur_sync.c
26 * @ingroup DEFPLUGINS_HEUR
27 * @brief primal heuristic that adds solutions from synchronization
28 * @author Leona Gottwald
29 *
30 * This heuristic takes solutions during synchronization and then adds them.
31 */
32
33/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
34
35#include <assert.h>
36#include <string.h>
37
38#include "scip/heur_sync.h"
39#include "scip/scip.h"
40
41
42#define HEUR_NAME "sync"
43#define HEUR_DESC "heuristic for synchronizing solution"
44#define HEUR_DISPCHAR 'S'
45#define HEUR_PRIORITY -3000000 /* should process after all other heuristics */
46#define HEUR_FREQ -1
47#define HEUR_FREQOFS 0
48#define HEUR_MAXDEPTH -1
49#define HEUR_TIMING SCIP_HEURTIMING_DURINGLPLOOP | SCIP_HEURTIMING_BEFOREPRESOL | SCIP_HEURTIMING_BEFORENODE
50#define HEUR_USESSUBSCIP FALSE /**< does the heuristic use a secondary SCIP instance? */
51
52
53/*
54 * Data structures
55 */
56
57
58/** primal heuristic data */
59struct SCIP_HeurData
60{
61 SCIP_SOL** sols; /**< storing solutions passed to heuristic sorted by objective value */
62 int nsols; /**< number of soluions stored */
63 int maxnsols; /**< maximum number of solutions that can be stored */
64};
65
66
67/*
68 * Callback methods of primal heuristic
69 */
70
71/** destructor of primal heuristic to free user data (called when SCIP is exiting) */
72static
73SCIP_DECL_HEURFREE(heurFreeSync)
74{ /*lint --e{715}*/
75 SCIP_HEURDATA* heurdata;
76
77 assert( heur != NULL );
78 assert( strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0 );
79 assert( scip != NULL );
80
81 SCIPdebugMessage("free method of sync primal heuristic.\n");
82
83 /* get heuristic data */
84 heurdata = SCIPheurGetData(heur);
85 assert(heurdata != NULL);
86 assert(heurdata->nsols == 0);
87 SCIPfreeBlockMemoryArray(scip, &heurdata->sols, heurdata->maxnsols);
88 SCIPfreeBlockMemory(scip, &heurdata);
89
90 return SCIP_OKAY;
91}
92
93
94/** deinitialization method of primal heuristic (called before transformed problem is freed) */
95static
97{ /*lint --e{715}*/
98 SCIP_HEURDATA* heurdata;
99 int i;
100
101 assert( heur != NULL );
102 assert( strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0 );
103 assert( scip != NULL );
104
105 SCIPdebugMessage("exit method of sync primal heuristic.\n");
106
107 /* get heuristic data */
108 heurdata = SCIPheurGetData(heur);
109 assert(heurdata != NULL);
110
111 /* free solution if one is still present */
112 for( i = 0; i < heurdata->nsols; ++i )
113 {
114 SCIP_CALL( SCIPfreeSol(scip, &heurdata->sols[i]) );
115 }
116 heurdata->nsols = 0;
117
118 return SCIP_OKAY;
119}
120
121
122/** execution method of primal heuristic */
123static
125{ /*lint --e{715}*/
126 SCIP_HEURDATA* heurdata;
127 SCIP_Bool stored;
128 int i;
129
130 assert(heur != NULL);
131 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
132 assert(scip != NULL);
133 assert(result != NULL);
134 assert(SCIPheurGetFreq(heur) == 1);
135
136 SCIPheurSetFreq(heur, -1);
137
138 /* get heuristic data */
139 heurdata = SCIPheurGetData(heur);
140 assert(heurdata != NULL);
141 assert(heurdata->nsols > 0);
142
143 SCIPdebugMessage("exec method of sync primal heuristic.\n");
144 *result = SCIP_DIDNOTFIND;
145 for( i = 0; i < heurdata->nsols; ++i )
146 {
147 SCIP_CALL( SCIPtrySolFree(scip, &heurdata->sols[i], FALSE, FALSE, FALSE, FALSE, FALSE, &stored) );
148 if( stored )
149 *result = SCIP_FOUNDSOL;
150 }
151
152 heurdata->nsols = 0;
153
154 return SCIP_OKAY;
155}
156
157/*
158 * primal heuristic specific interface methods
159 */
160
161/** creates the sync primal heuristic and includes it in SCIP */
163 SCIP* scip /**< SCIP data structure */
164 )
165{
166 SCIP_HEURDATA* heurdata;
167 SCIP_HEUR* heur;
168
169 /* create heuristic data */
170 SCIP_CALL( SCIPallocBlockMemory(scip, &heurdata) );
171 SCIP_CALL( SCIPgetIntParam(scip, "concurrent/sync/maxnsols", &heurdata->maxnsols) );
172 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &heurdata->sols, heurdata->maxnsols) );
173 heurdata->nsols = 0;
174
175 /* include primal heuristic */
178 HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecSync, heurdata) );
179
180 assert(heur != NULL);
181
182 /* primal heuristic is safe to use in exact solving mode */
183 SCIPheurMarkExact(heur);
184
185 /* set non-NULL pointers to callback methods */
186 SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeSync) );
187 SCIP_CALL( SCIPsetHeurExit(scip, heur, heurExitSync) );
188
189 return SCIP_OKAY;
190}
191
192
193/** pass solution to sync heuristic */
195 SCIP* scip, /**< SCIP data structure */
196 SCIP_HEUR* heur, /**< sync heuristic */
197 SCIP_SOL* sol /**< solution to be passed */
198 )
199{
200 SCIP_HEURDATA* heurdata;
201 SCIP_Real solobj;
202 int i;
203 assert(scip != NULL);
204 assert(heur != NULL);
205 assert(sol != NULL);
206 assert(strcmp(HEUR_NAME, SCIPheurGetName(heur)) == 0);
207
208 /* get heuristic data */
209 heurdata = SCIPheurGetData(heur);
210 assert(heurdata != NULL);
211
212 SCIPsolSetHeur(sol, heur);
213 solobj = SCIPgetSolTransObj(scip, sol);
214
215 /* check if we have an empty space in the solution array or
216 * if we need to discard the worst solution
217 */
218 if( heurdata->nsols < heurdata->maxnsols )
219 {
220 /* if the maximum number of solutions is not yet reached just
221 * insert the solution sorted by its objective value */
222 i = heurdata->nsols++;
223 while( i > 0 && solobj > SCIPgetSolTransObj(scip, heurdata->sols[i - 1]) )
224 {
225 heurdata->sols[i] = heurdata->sols[i - 1];
226 --i;
227 }
228 heurdata->sols[i] = sol;
229 }
230 else
231 {
232 /* already have reached the maximum number of solutions so
233 * we need to check if the solution is better than a previous
234 * one and free the worst solution to make room for it if that
235 * is the case
236 */
237 for( i = 0; i < heurdata->nsols && solobj < SCIPgetSolTransObj(scip, heurdata->sols[i]); ++i )
238 {
239 if( i > 0 )
240 {
241 heurdata->sols[i - 1] = heurdata->sols[i];
242 }
243 else
244 {
245 SCIP_CALL( SCIPfreeSol(scip, &heurdata->sols[i]) );
246 }
247 }
248
249 /* check if solution must be inserted or discarded */
250 if( i > 0)
251 {
252 /* found position to insert the solution sorted by objective value */
253 heurdata->sols[i-1] = sol;
254 }
255 else
256 {
257 /* solution is not better just discard it */
258 SCIP_CALL( SCIPfreeSol(scip, &sol) );
259 }
260 }
261 assert(heurdata->nsols > 0);
262 assert(heurdata->nsols <= heurdata->maxnsols);
263
264 SCIPheurSetFreq(heur, 1);
265
266 return SCIP_OKAY;
267}
#define NULL
Definition: def.h:248
#define SCIP_Bool
Definition: def.h:91
#define SCIP_Real
Definition: def.h:156
#define FALSE
Definition: def.h:94
#define SCIP_CALL(x)
Definition: def.h:355
SCIP_RETCODE SCIPheurSyncPassSol(SCIP *scip, SCIP_HEUR *heur, SCIP_SOL *sol)
Definition: heur_sync.c:194
SCIP_RETCODE SCIPgetIntParam(SCIP *scip, const char *name, int *value)
Definition: scip_param.c:269
SCIP_RETCODE SCIPincludeHeurSync(SCIP *scip)
Definition: heur_sync.c:162
SCIP_HEURDATA * SCIPheurGetData(SCIP_HEUR *heur)
Definition: heur.c:1368
SCIP_RETCODE SCIPincludeHeurBasic(SCIP *scip, SCIP_HEUR **heur, const char *name, const char *desc, char dispchar, int priority, int freq, int freqofs, int maxdepth, SCIP_HEURTIMING timingmask, SCIP_Bool usessubscip, SCIP_DECL_HEUREXEC((*heurexec)), SCIP_HEURDATA *heurdata)
Definition: scip_heur.c:122
SCIP_RETCODE SCIPsetHeurFree(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURFREE((*heurfree)))
Definition: scip_heur.c:183
SCIP_RETCODE SCIPsetHeurExit(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEUREXIT((*heurexit)))
Definition: scip_heur.c:215
void SCIPheurSetFreq(SCIP_HEUR *heur, int freq)
Definition: heur.c:1562
void SCIPheurMarkExact(SCIP_HEUR *heur)
Definition: heur.c:1457
int SCIPheurGetFreq(SCIP_HEUR *heur)
Definition: heur.c:1552
const char * SCIPheurGetName(SCIP_HEUR *heur)
Definition: heur.c:1467
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:110
#define SCIPallocBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:93
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip_mem.h:108
#define SCIPallocBlockMemory(scip, ptr)
Definition: scip_mem.h:89
SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
Definition: scip_sol.c:1252
SCIP_RETCODE SCIPtrySolFree(SCIP *scip, SCIP_SOL **sol, SCIP_Bool printreason, SCIP_Bool completely, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *stored)
Definition: scip_sol.c:4109
SCIP_Real SCIPgetSolTransObj(SCIP *scip, SCIP_SOL *sol)
Definition: scip_sol.c:2005
void SCIPsolSetHeur(SCIP_SOL *sol, SCIP_HEUR *heur)
Definition: sol.c:4304
#define HEUR_TIMING
Definition: heur_sync.c:49
#define HEUR_FREQOFS
Definition: heur_sync.c:47
#define HEUR_DESC
Definition: heur_sync.c:43
static SCIP_DECL_HEUREXITSOL(heurExitSync)
Definition: heur_sync.c:96
#define HEUR_DISPCHAR
Definition: heur_sync.c:44
#define HEUR_MAXDEPTH
Definition: heur_sync.c:48
#define HEUR_PRIORITY
Definition: heur_sync.c:45
static SCIP_DECL_HEURFREE(heurFreeSync)
Definition: heur_sync.c:73
#define HEUR_NAME
Definition: heur_sync.c:42
static SCIP_DECL_HEUREXEC(heurExecSync)
Definition: heur_sync.c:124
#define HEUR_FREQ
Definition: heur_sync.c:46
#define HEUR_USESSUBSCIP
Definition: heur_sync.c:50
primal heuristic that adds given solutions
#define SCIPdebugMessage
Definition: pub_message.h:96
SCIP callable library.
struct SCIP_HeurData SCIP_HEURDATA
Definition: type_heur.h:77
@ SCIP_DIDNOTFIND
Definition: type_result.h:44
@ SCIP_FOUNDSOL
Definition: type_result.h:56
@ SCIP_OKAY
Definition: type_retcode.h:42
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63