37#define HEUR_NAME "cyckerlin"
38#define HEUR_DESC "switch heuristic that tries to improve solution by trading states betweeen clusters"
39#define HEUR_DISPCHAR '@'
40#define HEUR_PRIORITY 500
43#define HEUR_MAXDEPTH -1
44#define MAXPERMUTATIONS 5
45#define DEFAULT_RANDSEED 177
46#define HEUR_TIMING SCIP_HEURTIMING_BEFORENODE
47#define HEUR_USESSUBSCIP FALSE
116 assert(nbins > 0 && ncluster > 0 && nbins > ncluster);
120 for(
i = 0;
i < nbins; ++
i )
122 for(
c = 0;
c < ncluster; ++
c )
126 if( binvars[
i][
c] !=
NULL)
162 for( cluster = 0; cluster < ncluster; ++cluster )
164 for( bin = 0; bin < nbins; ++bin )
166 if( cluster != newcluster )
168 qmatrix[newcluster][cluster] += sign * solclustering[bin][cluster] * cmatrix[newbin][bin];
169 qmatrix[cluster][newcluster] += sign * solclustering[bin][cluster] * cmatrix[bin][newbin];
175 qmatrix[newcluster][newcluster] += sign * (cmatrix[newbin][bin] + cmatrix[bin][newbin])
176 * solclustering[bin][cluster];
182 solclustering[newbin][newcluster] = (sign + 1.0) / 2.0;
200 for( k = 0; k < ncluster; ++k )
202 for( l = 0; l < ncluster; ++l )
205 for(
i = 0;
i < nbins; ++
i )
207 for( j = 0; j < nbins; ++j )
213 qmatrix[k][l] += cmatrix[
i][j] * clustering[
i][k] * clustering[j][l];
233 for(
c = 0;
c < ncluster; ++
c )
235 c2 = (
c + 1 ) % ncluster;
236 objective += ( qmatrix[
c][c2] - qmatrix[c2][
c]);
237 objective += scale * qmatrix[
c][
c];
256 int* switchedcluster,
287 for( bin = 0; bin < nbins; ++bin )
289 if( binprocessed[bin] || nbinsincluster[clusterofbin[bin]] == 1 )
291 k = clusterofbin[bin];
296 for( l = 0; l < ncluster; ++l )
298 if( binfixed[bin][k] || binfixed[bin][l] )
305 indkmin = ncluster - 1;
310 indlmin = ncluster - 1;
319 for(
i = 0;
i < nbins; ++
i )
322 irrevchg -= clustering[
i][indkmin] * (cmatrix[
i][bin] - cmatrix[bin][
i]);
323 irrevchg -= clustering[
i][(k+1) % ncluster] * (cmatrix[bin][
i] - cmatrix[
i][bin]);
325 clustering[bin][k] = 0;
326 clustering[bin][l] = 1;
328 irrevchg += clustering[
i][indlmin] * (cmatrix[
i][bin] - cmatrix[bin][
i]);
329 irrevchg += clustering[
i][(l+1) % ncluster] * (cmatrix[bin][
i] - cmatrix[
i][bin]);
331 clustering[bin][k] = 1;
332 clustering[bin][l] = 0;
337 cohchg -= clustering[
i][k] * (cmatrix[bin][
i]+ cmatrix[
i][bin]);
338 cohchg += clustering[
i][l] * (cmatrix[bin][
i]+ cmatrix[
i][bin]);
342 if( oldobjective + irrevchg + scale * cohchg > maxboundlocal )
344 maxboundlocal = oldobjective + irrevchg + scale * cohchg;
354 assert(maxbin >= 0 && maxcluster >= 0);
355 assert(maxbin < nbins && maxcluster < ncluster);\
358 setBinToCluster(clustering, cmatrix, qmatrix, maxbin, clusterofbin[maxbin],
FALSE, nbins, ncluster);
361 nbinsincluster[clusterofbin[maxbin]]--;
362 nbinsincluster[maxcluster]++;
364 clusterofbin[maxbin] = maxcluster;
365 binprocessed[maxbin] =
TRUE;
367 switchedbin[iteration] = maxbin;
368 switchedcluster[iteration] = maxcluster;
371 if( switchbound[iteration] > *maxbound )
373 *maxbound = switchbound[iteration];
374 *bestlength = iteration;
409 int* switchedcluster;
424 for(
i = 0;
i < nbins; ++
i )
431 for(
c = 0;
c < ncluster; ++
c )
433 nbinsincluster[
c] = 0;
436 for(
i = 0;
i < nbins; ++
i )
438 for(
c = 0;
c < ncluster; ++
c )
440 solclustering[
i][
c] = startclustering[
i][
c];
454 while( heurpossible )
457 for(
c = 0;
c < ncluster; ++
c )
459 nbinsincluster[
c] = 0;
462 for(
i = 0;
i < nbins; ++
i )
464 for(
c = 0;
c < ncluster; ++
c )
466 clustering[
i][
c] = solclustering[
i][
c];
486 for(
i = 0;
i < nrswitches; ++
i )
488 if( !
switchNext(
scip, cmatrix, qmatrix, clustering, binfixed, binprocessed, clusterofbin,
489 nbinsincluster, switchedbin, switchedcluster, switchbound, &maxbound, &bestlength,
i) )
497 for(
i = 0;
i <= bestlength; ++
i )
499 for(
c = 0;
c < ncluster; ++
c )
501 solclustering[switchedbin[
i]][
c] = 0;
504 solclustering[switchedbin[
i]][switchedcluster[
i]] = 1;
505 clusterofbin[switchedbin[
i]] = switchedcluster[
i];
514 if( max > objective )
532 heurpossible =
FALSE;
537 for(
i = 0;
i < nbins; ++
i )
577 for( t = 0; t < ncluster; ++t )
579 binsincluster[t] = 0;
581 for(
i = 0;
i < nbins; ++
i )
591 for(
i = 0;
i < nbins; ++
i )
601 for( t = 0; t < ncluster; ++t )
605 while(pushed < binsincluster[t] / 2)
609 if( rndcluster == nbins -1 )
614 startclustering[rndcluster][t] = 0;
615 startclustering[rndcluster][
phi(t,ncluster)] = 1;
665 for(
c = 0;
c < ncluster; ++
c )
669 for(
i = 0;
i < nbins; ++
i )
692 for(
i = 0;
i < nbins; ++
i )
698 for(
c = 0;
c < ncluster; ++
c )
#define SCIP_STRINGEQ(name, reference, retcode)
SCIP_RETCODE SCIPsetHeurFree(SCIP *scip, SCIP_HEUR *heur,)
SCIP_HEURDATA * SCIPheurGetData(SCIP_HEUR *heur)
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)
SCIP_RETCODE SCIPsetHeurCopy(SCIP *scip, SCIP_HEUR *heur,)
void SCIPheurSetTimingmask(SCIP_HEUR *heur, SCIP_HEURTIMING timingmask)
SCIP_RETCODE SCIPsetHeurExitsol(SCIP *scip, SCIP_HEUR *heur,)
SCIP_HEUR * SCIPfindHeur(SCIP *scip, const char *name)
SCIP_RETCODE SCIPsetHeurInit(SCIP *scip, SCIP_HEUR *heur,)
const char * SCIPheurGetName(SCIP_HEUR *heur)
void SCIPheurSetData(SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
#define SCIPreallocMemoryArray(scip, ptr, newnum)
#define SCIPallocMemoryArray(scip, ptr, num)
#define SCIPallocClearBufferArray(scip, ptr, num)
#define SCIPallocBufferArray(scip, ptr, num)
#define SCIPfreeBufferArray(scip, ptr)
#define SCIPfreeMemoryArray(scip, ptr)
#define SCIPfreeBlockMemory(scip, ptr)
#define SCIPallocBlockMemory(scip, ptr)
SCIP_SOL * SCIPgetBestSol(SCIP *scip)
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)
SCIP_Real SCIPgetSolOrigObj(SCIP *scip, SCIP_SOL *sol)
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
SCIP_Longint SCIPgetNNodes(SCIP *scip)
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisPositive(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
int SCIPrandomGetInt(SCIP_RANDNUMGEN *randnumgen, int minrandval, int maxrandval)
SCIPcreateSol(scip, &heurdata->sol, heur))
SCIPfreeRandom(scip, &heurdata->randnumgen)
static SCIP_Real getObjective(SCIP *scip, SCIP_Real **qmatrix, SCIP_Real scale, int ncluster)
static void setBinToCluster(SCIP_Real **solclustering, SCIP_Real **cmatrix, SCIP_Real **qmatrix, int newbin, int newcluster, SCIP_Bool setone, int nbins, int ncluster)
static void computeIrrevMat(SCIP_Real **clustering, SCIP_Real **qmatrix, SCIP_Real **cmatrix, int nbins, int ncluster)
static SCIP_RETCODE createSwitchSolution(SCIP *scip, SCIP_HEUR *heur, SCIP_Real **cmatrix, SCIP_Real **qmatrix, SCIP_Bool **binfixed, SCIP_Real **startclustering, SCIP_RESULT *result, int nbins, int ncluster)
SCIP_RETCODE SCIPincludeHeurCycKerlin(SCIP *scip)
static SCIP_RETCODE runCyckerlin(SCIP *scip, SCIP_HEUR *heur, SCIP_SOL *sol, SCIP_RESULT *result)
static SCIP_RETCODE getSolutionValues(SCIP *scip, SCIP_SOL *bestsol, SCIP_Real **solclustering, SCIP_Bool **binfixed, int *clusterofbin, int *nbinsincluster)
static SCIP_RETCODE permuteStartSolution(SCIP *scip, SCIP_Real **startclustering, SCIP_RANDNUMGEN *rnd, int nbins, int ncluster)
static SCIP_Bool switchNext(SCIP *scip, SCIP_Real **cmatrix, SCIP_Real **qmatrix, SCIP_Real **clustering, SCIP_Bool **binfixed, SCIP_Bool *binprocessed, int *clusterofbin, int *nbinsincluster, int *switchedbin, int *switchedcluster, SCIP_Real *switchbound, SCIP_Real *maxbound, int *bestlength, int iteration)
SCIP_RETCODE addCandSolCyckerlin(SCIP *scip, SCIP_SOL *sol)
Improvement heuristic that trades bin-variables between clusters.
SCIPcreateRandom(scip, &heurdata->randnumgen, DEFAULT_RANDSEED, TRUE))
assert(minobj< SCIPgetCutoffbound(scip))
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_Bool isPartition(SCIP *scip, SCIP_Real **solclustering, int nbins, int ncluster)
problem data for cycle clustering problem
public data structures and miscellaneous methods
static SCIP_Real phi(SCIP *scip, SCIP_Real val, SCIP_Real lb, SCIP_Real ub)
#define SCIP_DECL_HEURCOPY(x)
struct SCIP_HeurData SCIP_HEURDATA
struct SCIP_Heur SCIP_HEUR
#define SCIP_DECL_HEURINIT(x)
#define SCIP_DECL_HEURFREE(x)
#define SCIP_DECL_HEUREXITSOL(x)
#define SCIP_DECL_HEUREXEC(x)
struct SCIP_RandNumGen SCIP_RANDNUMGEN
enum SCIP_Result SCIP_RESULT
enum SCIP_Retcode SCIP_RETCODE