SCIP Doxygen Documentation
Loading...
Searching...
No Matches
heur_redsize.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-2026 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_redsize.c
26 * @brief primal heuristic that solves the problem with a sparser matrix as a submip
27 * @author Leon Eifler
28 */
29/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
30
31#include "heur_redsize.h"
32#include "cycplugins.h"
33#include "probdata_cyc.h"
34
35#define HEUR_NAME "redsize"
36#define HEUR_DESC "primal heuristic that solves the problem with a sparser matrix as a submip"
37#define HEUR_DISPCHAR 'u'
38#define HEUR_PRIORITY 536870911
39#define HEUR_FREQ 0
40#define HEUR_FREQOFS 0
41#define HEUR_MAXDEPTH -1
42#define HEUR_TIMING SCIP_HEURTIMING_BEFORENODE
43#define HEUR_USESSUBSCIP TRUE /**< does the heuristic use a secondary SCIP instance? */
44
45#define DEFAULT_REDUCTIONRATE 0.75 /**< default percentile of transition that gets deleted */
46
47struct SCIP_HeurData
48{
49 SCIP_Real reductionrate; /**< percentile of transition that gets deleted */
50};
51
52/*
53 * Local methods
54 */
55
56/** Add incomplete solution to main scip */
57static
59 SCIP* scip, /**< SCIP data structure */
60 SCIP* subscip, /**< SCIP data structure of subscip */
61 SCIP_HEUR* heur, /**< pointer to heuristic */
62 SCIP_SOL* subsol, /**< solution of subscip */
63 SCIP_RESULT* result /**< result pointer */
64 )
65{
66 SCIP_VAR*** binvars;
67 SCIP_Real** solclustering;
68 SCIP_SOL* newsol;
69 SCIP_Bool feasible;
70 int nbins;
71 int ncluster;
72 int i;
73 int t;
74
75 nbins = SCIPcycGetNBins(scip);
76 ncluster = SCIPcycGetNCluster(scip);
77 binvars = SCIPcycGetBinvars(subscip);
78
79 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &solclustering, nbins) );
80
81 SCIP_CALL( SCIPcreateSol(scip, &newsol, heur) );
82
83 for( i = 0; i < nbins; ++i )
84 {
85 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &solclustering[i], ncluster) );
86
87 for( t = 0; t < ncluster; ++t )
88 {
89 solclustering[i][t] = SCIPgetSolVal(subscip, subsol, binvars[i][t]);
90 }
91 }
92
93 SCIP_CALL( assignVars(scip, newsol, solclustering, nbins, ncluster) );
94
95 SCIP_CALL( SCIPtrySolFree(scip, &newsol, FALSE, TRUE, TRUE, TRUE, TRUE, &feasible) );
96
97 if( feasible )
99
100 for( i = 0; i < nbins; ++i )
101 {
102 SCIPfreeBlockMemoryArray(scip, &solclustering[i], ncluster);
103 }
104
105 SCIPfreeBlockMemoryArray(scip, &solclustering, nbins);
106
107 return SCIP_OKAY;
108}
109
110/** set all the given percentile of nonzeros to zero */
111static
113 SCIP* scip, /**< SCIP data structure */
114 SCIP_Real** matrix, /**< the matrix */
115 SCIP_Real percentile, /**< the percentile of entries to be deleted */
116 SCIP_Real scale, /**< scaling between net flow and coherence */
117 int size /**< the size of the matrix */
118 )
119{
120 SCIP_Real* nonzeros;
121 int* idxnonzeros;
122 int nnonzeros;
123 int currentsize;
124 int i;
125 int j;
126 int k;
127
128 nnonzeros = 0;
129 currentsize = size;
130
131 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &nonzeros, size) );
132 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &idxnonzeros, size) );
133
134 for( i = 0; i < size; ++i )
135 {
136 for( j = 0; j < i; ++j )
137 {
138 if( !SCIPisZero(scip, matrix[i][j]) || !SCIPisZero(scip, matrix[j][i]) )
139 {
140 /* if we have non-zero entry, compute the impact and save it */
141 nonzeros[nnonzeros] = MAX(scale * (matrix[i][j]+matrix[j][i]), matrix[i][j] - matrix[j][i]);
142 idxnonzeros[nnonzeros] = i * size + j;
143
144 nnonzeros++;
145
146 /* realloc if necessary */
147 if( currentsize < nnonzeros + 2 )
148 {
149 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &nonzeros, currentsize, currentsize + size) );
150 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &idxnonzeros, currentsize, currentsize + size) );
151 currentsize += size;
152 }
153 }
154 }
155 }
156
157 /* sort by the least impact */
158 SCIPsortRealInt(nonzeros, idxnonzeros, nnonzeros);
159
160 /* recompute the indizes and set them to 0 */
161 for( i = 0; i < nnonzeros * percentile; ++i )
162 {
163 j = idxnonzeros[i] % size;
164 k = idxnonzeros[i] / size;
165
166 matrix[j][k] = 0.0;
167 matrix[k][j] = 0.0;
168 }
169
170 SCIPfreeBlockMemoryArray(scip, &nonzeros, currentsize);
171 SCIPfreeBlockMemoryArray(scip, &idxnonzeros, currentsize);
172
173 return SCIP_OKAY;
174}
175
176/** main procedure of the heuristic, creates and solves a sub-SCIP */
177static
179 SCIP* scip, /**< original SCIP data structure */
180 SCIP_HEUR* heur, /**< heuristic data structure */
181 SCIP_RESULT* result, /**< result data structure */
182 SCIP_Real reductionrate, /**< minimum percentage of integer variables that have to be fixed */
183 SCIP_Longint maxnodes /**< maximum number of nodes for the subproblem */
184 )
185{
186 SCIP* subscip;
187 SCIP_Real** cmatrix_orig;
188 SCIP_Real** cmatrix_red;
189 SCIP_SOL** subsols;
190
191 SCIP_Real scale;
192
193 int nbins;
194 int ncluster;
195 int nsubsols;
196 int i;
197 int j;
198
199 assert(scip != NULL);
200 assert(heur != NULL);
201 assert(result != NULL);
202
203 assert(maxnodes >= 0);
204
205 assert(0.0 <= reductionrate && reductionrate <= 1.0);
206
207 nbins = SCIPcycGetNBins(scip);
208 ncluster = SCIPcycGetNCluster(scip);
209 cmatrix_orig = SCIPcycGetCmatrix(scip);
210 scale = SCIPcycGetScale(scip);
211
212 assert(nbins > 0 && ncluster > 0 && nbins >= ncluster);
213 assert(cmatrix_orig != NULL);
214
216
217 /* create subscip */
218 SCIP_CALL( SCIPcreate(&subscip) );
220
221#ifdef SCIP_DEBUG
222 /* for debugging, enable full output */
223 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 5) );
224 SCIP_CALL( SCIPsetIntParam(subscip, "display/freq", -1) );
225#else
226 /* disable statistic timing inside sub SCIP and output to console */
227 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 0) );
228 SCIP_CALL( SCIPsetBoolParam(subscip, "timing/statistictiming", FALSE) );
229#endif
230
231 /* copy the original cmatrix */
232 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &cmatrix_red, nbins) );
233 for( i = 0; i < nbins; ++i )
234 {
235 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &cmatrix_red[i], nbins) );
236 for( j = 0; j < nbins; ++j )
237 {
238 cmatrix_red[i][j] = cmatrix_orig[i][j];
239 }
240 }
241
242 /* delete entries from the copied cmatrix */
243 SCIP_CALL( SCIPreduceMatrixSize(subscip, cmatrix_red, reductionrate, scale, nbins) );
244
245 /* create probdata for the subscip */
246 SCIP_CALL( SCIPcreateProbCyc(subscip, "subscip", nbins, ncluster, cmatrix_red) );
247
248 /* forbid recursive call of heuristics and separators solving sub-SCIPs */
249 SCIP_CALL( SCIPsetSubscipsOff(subscip, TRUE) );
250
251 /* set nodelimit */
252 SCIP_CALL( SCIPsetLongintParam(subscip, "limits/nodes", maxnodes) );
253
254 /* disable cutting plane separation */
256
257 /* disable expensive presolving */
259
260 /* use best estimate node selection */
261 if( SCIPfindNodesel(subscip, "estimate") != NULL && !SCIPisParamFixed(subscip, "nodeselection/estimate/stdpriority") )
262 {
263 SCIP_CALL( SCIPsetIntParam(subscip, "nodeselection/estimate/stdpriority", INT_MAX/4) );
264 }
265
266 /* use inference branching */
267 if( SCIPfindBranchrule(subscip, "inference") != NULL && !SCIPisParamFixed(subscip, "branching/inference/priority") )
268 {
269 SCIP_CALL( SCIPsetIntParam(subscip, "branching/inference/priority", INT_MAX/4) );
270 }
271
272 /* enable conflict analysis, disable analysis of boundexceeding LPs, and restrict conflict pool */
273 if( !SCIPisParamFixed(subscip, "conflict/enable") )
274 {
275 SCIP_CALL( SCIPsetBoolParam(subscip, "conflict/enable", TRUE) );
276 }
277 if( !SCIPisParamFixed(subscip, "conflict/useboundlp") )
278 {
279 SCIP_CALL( SCIPsetCharParam(subscip, "conflict/useboundlp", 'o') );
280 }
281 if( !SCIPisParamFixed(subscip, "conflict/maxstoresize") )
282 {
283 SCIP_CALL( SCIPsetIntParam(subscip, "conflict/maxstoresize", 100) );
284 }
285
286 /* solve the subproblem */
287 SCIP_CALL_ABORT( SCIPsolve(subscip) );
288
289 /* print solving statistics of subproblem if we are in SCIP's debug mode */
291
292 /* check, whether a solution was found; due to numerics, it might happen that not all solutions are feasible -> try
293 * all solutions until one was accepted
294 */
295 nsubsols = SCIPgetNSols(subscip);
296 subsols = SCIPgetSols(subscip);
297
298 for( i = 0; i < nsubsols; ++i )
299 SCIP_CALL( SCIPcycAddIncompleteSol(scip, subscip, heur, subsols[i], result) );
300
301 SCIP_CALL( SCIPfree(&subscip) );
302
303 /* free memory */
304 for( i = 0; i < nbins; ++i )
305 {
306 SCIPfreeBlockMemoryArray(scip, &cmatrix_red[i], nbins);
307 }
308 SCIPfreeBlockMemoryArray(scip, &cmatrix_red, nbins);
309
310 return SCIP_OKAY;
311}
312
313/*
314 * Callback methods of primal heuristic
315 */
316
317/** copy method for primal heuristic plugins (called when SCIP copies plugins) */
318static
319SCIP_DECL_HEURCOPY(heurCopyRedsize)
320{ /*lint --e{715}*/
321 assert(scip != NULL);
322 assert(heur != NULL);
323
325
326 /* call inclusion method of primal heuristic */
328
329 return SCIP_OKAY;
330}
331
332/** destructor of primal heuristic to free user data (called when SCIP is exiting) */
333static
334SCIP_DECL_HEURFREE(heurFreeRedsize)
335{ /*lint --e{715}*/
337
338 assert(heur != NULL);
339 assert(scip != NULL);
340
341 /* get heuristic data */
343 assert(heurdata != NULL);
344
345 /* free heuristic data */
347 SCIPheurSetData(heur, NULL);
348
349 return SCIP_OKAY;
350}
351
352/** execution method of primal heuristic */
353static
354SCIP_DECL_HEUREXEC(heurExecRedsize)
355{ /*lint --e{715}*/
357
358 assert(heur != NULL);
359 assert(scip != NULL);
360 assert(result != NULL);
361
363
365
366 assert(heurdata != NULL);
367
369
370 SCIP_CALL( SCIPapplyRedSize(scip, heur, result, heurdata->reductionrate, (SCIP_Longint) 1) );
371
372 return SCIP_OKAY;
373}
374
375/*
376 * primal heuristic specific interface methods
377 */
378
379/** creates the oneopt primal heuristic and includes it in SCIP */
381 SCIP* scip /**< SCIP data structure */
382 )
383{
385 SCIP_HEUR* heur;
386
387 /* create redsize primal heuristic data */
389
390 /* include primal heuristic */
393 HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecRedsize, heurdata) );
394
395 assert(heur != NULL);
396
397 /* set non-NULL pointers to callback methods */
398 SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyRedsize) );
399 SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeRedsize) );
400
401 /* add param */
402 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/reduction-rate",
403 "percentile of transition probabilities that gets deleted in the submip",
404 &heurdata->reductionrate, FALSE, DEFAULT_REDUCTIONRATE, 0.0, 1.0, NULL , NULL) );
405
406 return SCIP_OKAY;
407}
SCIP_RETCODE SCIPincludeCycPlugins(SCIP *scip)
Definition cycplugins.c:45
SCIP plugins for cycle clustering.
#define NULL
Definition def.h:257
#define SCIP_Longint
Definition def.h:150
#define SCIP_Bool
Definition def.h:100
#define SCIP_STRINGEQ(name, reference, retcode)
Definition def.h:454
#define SCIP_Real
Definition def.h:165
#define TRUE
Definition def.h:102
#define FALSE
Definition def.h:103
#define MAX(x, y)
Definition def.h:229
#define SCIP_CALL_ABORT(x)
Definition def.h:343
#define SCIP_CALL(x)
Definition def.h:364
SCIP_RETCODE SCIPfree(SCIP **scip)
SCIP_RETCODE SCIPcreate(SCIP **scip)
SCIP_Bool SCIPisParamFixed(SCIP *scip, const char *name)
Definition scip_param.c:219
SCIP_RETCODE SCIPsetLongintParam(SCIP *scip, const char *name, SCIP_Longint value)
Definition scip_param.c:545
SCIP_RETCODE SCIPaddRealParam(SCIP *scip, const char *name, const char *desc, SCIP_Real *valueptr, SCIP_Bool isadvanced, SCIP_Real defaultvalue, SCIP_Real minvalue, SCIP_Real maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition scip_param.c:139
SCIP_RETCODE SCIPsetIntParam(SCIP *scip, const char *name, int value)
Definition scip_param.c:487
SCIP_RETCODE SCIPsetSubscipsOff(SCIP *scip, SCIP_Bool quiet)
Definition scip_param.c:904
SCIP_RETCODE SCIPsetPresolving(SCIP *scip, SCIP_PARAMSETTING paramsetting, SCIP_Bool quiet)
Definition scip_param.c:956
SCIP_RETCODE SCIPsetCharParam(SCIP *scip, const char *name, char value)
Definition scip_param.c:661
SCIP_RETCODE SCIPsetBoolParam(SCIP *scip, const char *name, SCIP_Bool value)
Definition scip_param.c:429
SCIP_RETCODE SCIPsetSeparating(SCIP *scip, SCIP_PARAMSETTING paramsetting, SCIP_Bool quiet)
Definition scip_param.c:985
SCIP_BRANCHRULE * SCIPfindBranchrule(SCIP *scip, const char *name)
SCIP_RETCODE SCIPsetHeurFree(SCIP *scip, SCIP_HEUR *heur,)
Definition scip_heur.c:183
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 SCIPsetHeurCopy(SCIP *scip, SCIP_HEUR *heur,)
Definition scip_heur.c:167
const char * SCIPheurGetName(SCIP_HEUR *heur)
Definition heur.c:1467
void SCIPheurSetData(SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
Definition heur.c:1378
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition scip_mem.h:110
#define SCIPallocBlockMemoryArray(scip, ptr, num)
Definition scip_mem.h:93
#define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
Definition scip_mem.h:99
#define SCIPfreeBlockMemory(scip, ptr)
Definition scip_mem.h:108
#define SCIPallocBlockMemory(scip, ptr)
Definition scip_mem.h:89
SCIP_NODESEL * SCIPfindNodesel(SCIP *scip, const char *name)
int SCIPgetNSols(SCIP *scip)
Definition scip_sol.c:2887
SCIP_SOL ** SCIPgetSols(SCIP *scip)
Definition scip_sol.c:2936
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:4114
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition scip_sol.c:1763
SCIP_RETCODE SCIPsolve(SCIP *scip)
SCIP_RETCODE SCIPprintStatistics(SCIP *scip, FILE *file)
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
void SCIPsortRealInt(SCIP_Real *realarray, int *intarray, int len)
#define HEUR_TIMING
return SCIP_OKAY
#define HEUR_FREQOFS
#define HEUR_DESC
#define HEUR_DISPCHAR
#define HEUR_MAXDEPTH
#define HEUR_PRIORITY
#define HEUR_NAME
#define HEUR_FREQ
#define HEUR_USESSUBSCIP
SCIPcreateSol(scip, &heurdata->sol, heur))
assert(minobj< SCIPgetCutoffbound(scip))
static SCIP_RETCODE SCIPreduceMatrixSize(SCIP *scip, SCIP_Real **matrix, SCIP_Real percentile, SCIP_Real scale, int size)
SCIP_RETCODE SCIPincludeHeurRedsize(SCIP *scip)
static SCIP_RETCODE SCIPapplyRedSize(SCIP *scip, SCIP_HEUR *heur, SCIP_RESULT *result, SCIP_Real reductionrate, SCIP_Longint maxnodes)
#define DEFAULT_REDUCTIONRATE
static SCIP_RETCODE SCIPcycAddIncompleteSol(SCIP *scip, SCIP *subscip, SCIP_HEUR *heur, SCIP_SOL *subsol, SCIP_RESULT *result)
primal heuristic that solves the problem with a sparser matrix as a submip
SCIP_RETCODE assignVars(SCIP *scip, SCIP_SOL *sol, SCIP_Real **clustering, int nbins, int ncluster)
int SCIPcycGetNBins(SCIP *scip)
SCIP_Real SCIPcycGetScale(SCIP *scip)
int SCIPcycGetNCluster(SCIP *scip)
SCIP_VAR *** SCIPcycGetBinvars(SCIP *scip)
SCIP_Real ** SCIPcycGetCmatrix(SCIP *scip)
SCIP_RETCODE SCIPcreateProbCyc(SCIP *scip, const char *name, int nbins, int ncluster, SCIP_Real **cmatrix)
problem data for cycle clustering problem
#define SCIPdebug(x)
Definition pub_message.h:93
#define SCIP_DECL_HEURCOPY(x)
Definition type_heur.h:97
struct SCIP_HeurData SCIP_HEURDATA
Definition type_heur.h:77
struct SCIP_Heur SCIP_HEUR
Definition type_heur.h:76
#define SCIP_DECL_HEURFREE(x)
Definition type_heur.h:105
#define SCIP_DECL_HEUREXEC(x)
Definition type_heur.h:163
@ SCIP_PARAMSETTING_OFF
@ SCIP_PARAMSETTING_FAST
@ SCIP_DIDNOTRUN
Definition type_result.h:42
@ SCIP_FOUNDSOL
Definition type_result.h:56
enum SCIP_Result SCIP_RESULT
Definition type_result.h:61
@ SCIP_INVALIDCALL
enum SCIP_Retcode SCIP_RETCODE
struct Scip SCIP
Definition type_scip.h:39
struct SCIP_Sol SCIP_SOL
Definition type_sol.h:57
struct SCIP_Var SCIP_VAR
Definition type_var.h:166