61#define SEPA_NAME "clique"
62#define SEPA_DESC "clique separator of stable set relaxation"
63#define SEPA_PRIORITY -5000
65#define SEPA_MAXBOUNDDIST 0.0
66#define SEPA_USESSUBSCIP FALSE
67#define SEPA_DELAY FALSE
69#define DEFAULT_SCALEVAL 1000.0
70#define DEFAULT_MAXTREENODES 10000
71#define DEFAULT_BACKTRACKFREQ 1000
72#define DEFAULT_MAXSEPACUTS 10
73#define DEFAULT_MAXZEROEXTENSIONS 1000
74#define DEFAULT_CLIQUETABLEMEM 20000.0
75#define DEFAULT_CLIQUEDENSITY 0.00
95 int maxzeroextensions;
113 unsigned int* cliqueids;
114 unsigned int* cliquetable;
150 (*tcliquegraph)->adjnodesidxs[0] = 0;
151 (*tcliquegraph)->cliqueidsidxs[0] = 0;
152 (*tcliquegraph)->adjnodes =
NULL;
153 (*tcliquegraph)->cliqueids =
NULL;
154 (*tcliquegraph)->cliquetable =
NULL;
155 (*tcliquegraph)->adjnodessize = 0;
156 (*tcliquegraph)->cliqueidssize = 0;
157 (*tcliquegraph)->nnodes = 0;
158 (*tcliquegraph)->tablewidth = 0;
159 (*tcliquegraph)->maxnnodes = maxnnodes;
177 for( v = 0; v < (*tcliquegraph)->nnodes; ++v )
206 if( num > tcliquegraph->cliqueidssize )
211 assert(num <= tcliquegraph->cliqueidssize);
229 unsigned int* cliqueids;
242 if( *tcliquegraph ==
NULL )
258 nadjnodes = (*tcliquegraph)->adjnodesidxs[(*tcliquegraph)->nnodes];
259 ncliqueids = (*tcliquegraph)->cliqueidsidxs[(*tcliquegraph)->nnodes];
262 *nodeidx = (*tcliquegraph)->nnodes;
264 (*tcliquegraph)->vars[*nodeidx] = nodevar;
265 (*tcliquegraph)->weights[*nodeidx] = 0;
266 (*tcliquegraph)->nnodes++;
272 cliqueids = (*tcliquegraph)->cliqueids;
273 for(
i = 0;
i < ncliques; ++
i )
275 assert(ncliqueids < (*tcliquegraph)->cliqueidssize);
277 assert(
i == 0 || cliqueids[ncliqueids-1] <= cliqueids[ncliqueids]);
282 (*tcliquegraph)->adjnodesidxs[(*tcliquegraph)->nnodes] = nadjnodes;
283 (*tcliquegraph)->cliqueidsidxs[(*tcliquegraph)->nnodes] = ncliqueids;
316 for( value = 0; value < 2; ++value )
318 assert(cliquegraphidx[value][
i] == -1);
345 unsigned int* cliquetable;
362 nbits = 8*
sizeof(
unsigned int);
363 tcliquegraph->tablewidth = (tcliquegraph->nnodes + nbits-1) / nbits;
366 if( (
SCIP_Real)tcliquegraph->nnodes * (
SCIP_Real)tcliquegraph->tablewidth/1024.0 > cliquetablemem )
371 for(
i = 0;
i < ncliques; ++
i )
378 tablesize = tcliquegraph->nnodes * tcliquegraph->tablewidth;
379 SCIPdebugMsg(
scip,
"clique separator: constructing dense clique table (%d kb, %d cliques, %d nodes, density: %.2f)\n",
387 cliquetable = tcliquegraph->cliquetable;
388 tablewidth = tcliquegraph->tablewidth;
412 for( v = 0; v < tcliquegraph->nnodes &&
var != tcliquegraph->vars[v]; ++v )
424 unsigned int colmask;
431 rowstart = nu*tablewidth;
433 colmask = 1U << (nu % nbits);
434 for( v = u+1; v <
nvars; ++v )
444 mask = 1U << (nv % nbits);
445 cliquetable[rowstart+nv/nbits] |= mask;
446 cliquetable[nv*tablewidth+colofs] |= colmask;
452 SCIPdebugMsg(
scip,
"clique separator: finished constructing dense clique table\n");
466 int* cliquegraphidx[2];
483 cliquegraphidx[0][
i] = -1;
484 cliquegraphidx[1][
i] = -1;
520 tcliquegraph =
sepadata->tcliquegraph;
524 for(
i = 0;
i < tcliquegraph->nnodes;
i++ )
529 tcliquegraph->weights[
i] =
MAX(weight, 0);
544 return tcliquegraph->nnodes;
553 return tcliquegraph->weights;
571 if( tcliquegraph->cliquetable !=
NULL )
578 nbits = 8*
sizeof(
unsigned int);
579 mask = (1U << (node2 % nbits));
580 colofs = node2 / nbits;
581 assert(((tcliquegraph->cliquetable[node1*tcliquegraph->tablewidth + colofs] & mask) != 0)
582 == ((tcliquegraph->cliquetable[node2*tcliquegraph->tablewidth + node1/nbits] & (1U << (node1 % nbits))) != 0));
583 return ((tcliquegraph->cliquetable[node1*tcliquegraph->tablewidth + colofs] & mask) != 0);
587 unsigned int* cliqueids;
593 cliqueids = tcliquegraph->cliqueids;
594 i1 = tcliquegraph->cliqueidsidxs[node1];
595 endi1 = tcliquegraph->cliqueidsidxs[node1+1];
596 i2 = tcliquegraph->cliqueidsidxs[node2];
597 endi2 = tcliquegraph->cliqueidsidxs[node2+1];
598 while( i1 < endi1 && i2 < endi2 )
600 while( i1 < endi1 && cliqueids[i1] < cliqueids[i2] )
605 while( i2 < endi2 && cliqueids[i2] < cliqueids[i1] )
610 if( cliqueids[i1] == cliqueids[i2] )
630 left = tcliquegraph->adjnodesidxs[node1];
631 right = tcliquegraph->adjnodesidxs[node1+1]-1;
632 while( left <= right )
637 middle = (left+right)/2;
638 node = tcliquegraph->adjnodes[middle];
641 else if( node > node2 )
671 graphadjnodes = tcliquegraph->adjnodes;
672 nodeadjindex = tcliquegraph->adjnodesidxs[node];
673 nodeadjend = tcliquegraph->adjnodesidxs[node+1];
677 assert(0 <= nodes[
i] && nodes[
i] < tcliquegraph->nnodes);
679 while( nodeadjindex < nodeadjend && graphadjnodes[nodeadjindex] < nodes[
i] )
681 if( nodeadjindex < nodeadjend && graphadjnodes[nodeadjindex] == nodes[
i] )
684 adjnodes[nadjnodes] = nodes[
i];
692 adjnodes[nadjnodes] = nodes[
i];
726 assert(ncliquenodes <= sepadata->tcliquegraph->nnodes);
728 for(
i = 0;
i < ncliquenodes; ++
i )
771 *stopsolving =
FALSE;
774 minweightinc = (cliqueweight - *minweight)/10;
775 minweightinc =
MAX(minweightinc, 1);
776 *minweight += minweightinc;
779 if( cliqueweight >
sepadata->scaleval )
793 unscaledweight = 0.0;
794 for(
i = 0;
i < ncliquenodes;
i++ )
795 unscaledweight += varsolvals[cliquenodes[
i]];
855 int maxzeroextensions;
906 tcliquegraph =
sepadata->tcliquegraph;
915 maxtreenodes = (
sepadata->maxtreenodes == -1 ? INT_MAX :
sepadata->maxtreenodes);
916 maxzeroextensions = (
sepadata->maxzeroextensions == -1 ? INT_MAX :
sepadata->maxzeroextensions);
924 tcliqueMaxClique(tcliqueGetnnodesClique, tcliqueGetweightsClique, tcliqueIsedgeClique, tcliqueSelectadjnodesClique,
926 cliquenodes, &ncliquenodes, &cliqueweight, (
int)
sepadata->scaleval-1, (
int)
sepadata->scaleval+1,
927 maxtreenodes,
sepadata->backtrackfreq, maxzeroextensions, -1,
NULL, &tcliquestatus);
1075 sepaExeclpClique, sepaExecsolClique,
1088 "separating/clique/scaleval",
1089 "factor for scaling weights",
1092 "separating/clique/maxtreenodes",
1093 "maximal number of nodes in branch and bound tree (-1: no limit)",
1096 "separating/clique/backtrackfreq",
1097 "frequency for premature backtracking up to tree level 1 (0: no backtracking)",
1100 "separating/clique/maxsepacuts",
1101 "maximal number of clique cuts separated per separation round (-1: no limit)",
1104 "separating/clique/maxzeroextensions",
1105 "maximal number of zero-valued variables extending the clique (-1: no limit)",
1108 "separating/clique/cliquetablemem",
1109 "maximal memory size of dense clique table (in kb)",
1112 "separating/clique/cliquedensity",
1113 "minimal density of cliques to use a dense clique table",
#define DEFAULT_MAXSEPACUTS
#define SCIP_LONGINT_FORMAT
static const SCIP_Real density
SCIP_Bool SCIPisStopped(SCIP *scip)
SCIP_VAR ** SCIPgetVars(SCIP *scip)
int SCIPgetNBinVars(SCIP *scip)
SCIP_RETCODE SCIPaddIntParam(SCIP *scip, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
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)
int SCIPgetNLPBranchCands(SCIP *scip)
SCIP_RETCODE SCIPaddPoolCut(SCIP *scip, SCIP_ROW *row)
SCIP_Bool SCIPisEfficacious(SCIP *scip, SCIP_Real efficacy)
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
#define SCIPfreeMemoryArrayNull(scip, ptr)
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
#define SCIPreallocMemoryArray(scip, ptr, newnum)
#define SCIPallocMemoryArray(scip, ptr, num)
int SCIPcalcMemGrowSize(SCIP *scip, int num)
#define SCIPallocBufferArray(scip, ptr, num)
#define SCIPfreeBufferArray(scip, ptr)
#define SCIPallocBlockMemoryArray(scip, ptr, num)
#define SCIPfreeBlockMemory(scip, ptr)
#define SCIPallocBlockMemory(scip, ptr)
SCIP_RETCODE SCIPcacheRowExtensions(SCIP *scip, SCIP_ROW *row)
SCIP_RETCODE SCIPflushRowExtensions(SCIP *scip, SCIP_ROW *row)
SCIP_RETCODE SCIPaddVarToRow(SCIP *scip, SCIP_ROW *row, SCIP_VAR *var, SCIP_Real val)
SCIP_RETCODE SCIPreleaseRow(SCIP *scip, SCIP_ROW **row)
SCIP_RETCODE SCIPcreateEmptyRowSepa(SCIP *scip, SCIP_ROW **row, SCIP_SEPA *sepa, const char *name, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool removable)
void SCIProwChgRank(SCIP_ROW *row, int rank)
SCIP_RETCODE SCIPincludeSepaBasic(SCIP *scip, SCIP_SEPA **sepa, const char *name, const char *desc, int priority, int freq, SCIP_Real maxbounddist, SCIP_Bool usessubscip, SCIP_Bool delay, SCIP_DECL_SEPAEXECLP((*sepaexeclp)), SCIP_DECL_SEPAEXECSOL((*sepaexecsol)), SCIP_SEPADATA *sepadata)
SCIP_RETCODE SCIPsetSepaFree(SCIP *scip, SCIP_SEPA *sepa,)
const char * SCIPsepaGetName(SCIP_SEPA *sepa)
SCIP_RETCODE SCIPsetSepaExitsol(SCIP *scip, SCIP_SEPA *sepa,)
SCIP_SEPADATA * SCIPsepaGetData(SCIP_SEPA *sepa)
void SCIPsepaSetData(SCIP_SEPA *sepa, SCIP_SEPADATA *sepadata)
SCIP_RETCODE SCIPsetSepaCopy(SCIP *scip, SCIP_SEPA *sepa,)
SCIP_Longint SCIPsepaGetNCalls(SCIP_SEPA *sepa)
SCIP_RETCODE SCIPgetSolVals(SCIP *scip, SCIP_SOL *sol, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Real SCIPfeasFloor(SCIP *scip, SCIP_Real val)
SCIP_VAR * SCIPvarGetNegatedVar(SCIP_VAR *var)
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
SCIP_Bool SCIPvarIsImpliedIntegral(SCIP_VAR *var)
SCIP_CLIQUE ** SCIPgetCliques(SCIP *scip)
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
SCIP_RETCODE SCIPcleanupCliques(SCIP *scip, SCIP_Bool *infeasible)
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
SCIP_RETCODE SCIPgetNegatedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **negvar)
int SCIPvarGetNCliques(SCIP_VAR *var, SCIP_Bool varfixing)
int SCIPgetNCliques(SCIP *scip)
SCIP_CLIQUE ** SCIPvarGetCliques(SCIP_VAR *var, SCIP_Bool varfixing)
SCIP_RETCODE SCIPcaptureVar(SCIP *scip, SCIP_VAR *var)
SCIP_RETCODE SCIPincludeSepaClique(SCIP *scip)
int SCIPsnprintf(char *t, int len, const char *s,...)
assert(minobj< SCIPgetCutoffbound(scip))
SCIP_VAR ** SCIPcliqueGetVars(SCIP_CLIQUE *clique)
int SCIPcliqueGetNVars(SCIP_CLIQUE *clique)
SCIP_Bool * SCIPcliqueGetValues(SCIP_CLIQUE *clique)
unsigned int SCIPcliqueGetId(SCIP_CLIQUE *clique)
memory allocation routines
#define BMSclearMemoryArray(ptr, num)
public methods for implications, variable bounds, and cliques
public methods for LP management
public methods for message output
public data structures and miscellaneous methods
public methods for separators
public methods for problem variables
public methods for branching rule plugins and branching
public methods for cuts and aggregation rows
public methods for the LP relaxation, rows and columns
public methods for memory management
public methods for message handling
public methods for numerical tolerances
public methods for SCIP parameter handling
public methods for global and local (sub)problems
public methods for separator plugins
public methods for solutions
public methods for SCIP variables
#define SEPA_MAXBOUNDDIST
static SCIP_RETCODE tcliquegraphAddNode(SCIP *scip, TCLIQUE_GRAPH **tcliquegraph, SCIP_VAR *var, SCIP_Bool value, int *nodeidx)
#define DEFAULT_MAXTREENODES
static SCIP_RETCODE tcliquegraphCreate(SCIP *scip, TCLIQUE_GRAPH **tcliquegraph)
#define DEFAULT_CLIQUEDENSITY
static SCIP_RETCODE tcliquegraphAddCliqueVars(SCIP *scip, TCLIQUE_GRAPH **tcliquegraph, int **cliquegraphidx)
static SCIP_RETCODE tcliquegraphConstructCliqueTable(SCIP *scip, TCLIQUE_GRAPH *tcliquegraph, SCIP_Real cliquetablemem, SCIP_Real cliquedensity)
#define DEFAULT_BACKTRACKFREQ
#define DEFAULT_CLIQUETABLEMEM
#define DEFAULT_MAXZEROEXTENSIONS
static SCIP_RETCODE tcliquegraphEnsureCliqueidsSize(SCIP *scip, TCLIQUE_GRAPH *tcliquegraph, int num)
static SCIP_RETCODE newsolCliqueAddRow(SCIP *scip, SCIP_SEPA *sepa, SCIP_SEPADATA *sepadata, int ncliquenodes, int *cliquenodes)
static SCIP_Bool nodesHaveCommonClique(TCLIQUE_GRAPH *tcliquegraph, int node1, int node2)
static SCIP_RETCODE separateCuts(SCIP *scip, SCIP_SEPA *sepa, SCIP_SOL *sol, SCIP_RESULT *result)
static SCIP_RETCODE loadTcliquegraph(SCIP *scip, SCIP_SEPADATA *sepadata)
static SCIP_RETCODE tcliquegraphFree(SCIP *scip, TCLIQUE_GRAPH **tcliquegraph)
static void updateTcliquegraph(SCIP *scip, SCIP_SEPADATA *sepadata)
#define TCLIQUE_GETWEIGHTS(x)
#define TCLIQUE_GETNNODES(x)
#define TCLIQUE_ISEDGE(x)
#define TCLIQUE_SELECTADJNODES(x)
enum TCLIQUE_Status TCLIQUE_STATUS
void tcliqueMaxClique(TCLIQUE_GETNNODES((*getnnodes)), TCLIQUE_GETWEIGHTS((*getweights)), TCLIQUE_ISEDGE((*isedge)), TCLIQUE_SELECTADJNODES((*selectadjnodes)), TCLIQUE_GRAPH *tcliquegraph, TCLIQUE_NEWSOL((*newsol)), TCLIQUE_DATA *tcliquedata, int *maxcliquenodes, int *nmaxcliquenodes, TCLIQUE_WEIGHT *maxcliqueweight, TCLIQUE_WEIGHT maxfirstnodeweight, TCLIQUE_WEIGHT minweight, int maxntreenodes, int backtrackfreq, int maxnzeroextensions, int fixednode, int *ntreenodes, TCLIQUE_STATUS *status)
struct TCLIQUE_Graph TCLIQUE_GRAPH
struct TCLIQUE_Data TCLIQUE_DATA
#define TCLIQUE_NEWSOL(x)
struct SCIP_Clique SCIP_CLIQUE
enum SCIP_Result SCIP_RESULT
enum SCIP_Retcode SCIP_RETCODE
struct SCIP_SepaData SCIP_SEPADATA
#define SCIP_DECL_SEPAEXECSOL(x)
#define SCIP_DECL_SEPAEXECLP(x)
#define SCIP_DECL_SEPAFREE(x)
#define SCIP_DECL_SEPAEXITSOL(x)
struct SCIP_Sepa SCIP_SEPA
#define SCIP_DECL_SEPACOPY(x)