/* * reorder_set() * * Reorders the set s with a function i -> order[i]. * * Note: Assumes that order is the same size as SET_MAX_SIZE(s). */ void reorder_set(set_t s,int *order) { set_t tmp; int i,j; setelement e; ASSERT(reorder_is_bijection(order,SET_MAX_SIZE(s))); tmp=set_new(SET_MAX_SIZE(s)); for (i=0; i<(SET_MAX_SIZE(s)/ELEMENTSIZE); i++) { e=s[i]; if (e==0) continue; for (j=0; j<ELEMENTSIZE; j++) { if (e&1) { SET_ADD_ELEMENT(tmp,order[i*ELEMENTSIZE+j]); } e = e>>1; } } if (SET_MAX_SIZE(s)%ELEMENTSIZE) { e=s[i]; for (j=0; j<(SET_MAX_SIZE(s)%ELEMENTSIZE); j++) { if (e&1) { SET_ADD_ELEMENT(tmp,order[i*ELEMENTSIZE+j]); } e = e>>1; } }
int sage_all_clique_max(graph_t *g,int **list){ sage_reset_global_variables(); quiet++; maximal=TRUE; int i,j,l; clique_options *opts = sage_init_clique_opt(); clique_unweighted_find_all(g,/*min_weight*/0,/*max_weight*/0, maximal,opts); free(opts); int size=set_size(sage_clique_list[0]); *list=malloc(sizeof(int)*(size+1)*sage_clique_count); l=0; for (j=0; j<sage_clique_count; j++) { for (i=0; i<SET_MAX_SIZE(sage_clique_list[j]); i++) { if (SET_CONTAINS(sage_clique_list[j],i)) { *((*list)+l)=i; l++; } } set_free(sage_clique_list[j]); *((*list)+l)=-1; l++; } return (1+size)*sage_clique_count; }
// Computes a maximum clique of the graph g and return its size // The table list contains the ID of the vertices int sage_clique_max(graph_t *g,int **list){ sage_reset_global_variables(); quiet++; set_t s; int i,l; clique_options *opts = sage_init_clique_opt(); s=clique_unweighted_find_single(g,/*min_weight*/0, /*max_weight*/0,/*maximal*/TRUE, opts); free(opts); // Writing the answer into a int [] to be read by Sage int size=set_size(s); *list=malloc(sizeof(int)*size); l=0; for (i=0; i<SET_MAX_SIZE(s); i++) { if (SET_CONTAINS(s,i)) { *((*list)+l)=i; l++; } } return size; }
/* * graph_test() * * Tests graph g to be valid. Checks that g is non-NULL, the edges are * symmetric and anti-reflexive, and that all vertex weights are positive. * If output is non-NULL, prints a few lines telling the status of the graph * to file descriptor output. * * Returns TRUE if the graph is valid, FALSE otherwise. */ boolean graph_test(graph_t *g,FILE *output) { int i,j; int edges=0; int asymm=0; int nonpos=0; int refl=0; int extra=0; unsigned int weight=0; boolean weighted; ASSERT((sizeof(setelement)*8)==ELEMENTSIZE); if (g==NULL) { if (output) fprintf(output," WARNING: Graph pointer is NULL!\n"); return FALSE; } weighted=graph_weighted(g); for (i=0; i < g->n; i++) { if (g->edges[i]==NULL) { if (output) fprintf(output," WARNING: Graph edge set " "NULL!\n" " (further warning suppressed)\n"); return FALSE; } if (SET_MAX_SIZE(g->edges[i]) < g->n) { if (output) fprintf(output," WARNING: Graph edge set " "too small!\n" " (further warnings suppressed)\n"); return FALSE; } for (j=0; j < g->n; j++) { if (SET_CONTAINS_FAST(g->edges[i],j)) { edges++; if (i==j) { refl++; } if (!SET_CONTAINS_FAST(g->edges[j],i)) { asymm++; } } } for (j=g->n; j < SET_ARRAY_LENGTH(g->edges[i])*ELEMENTSIZE; j++) { if (SET_CONTAINS_FAST(g->edges[i],j)) extra++; } if (g->weights[i] <= 0) nonpos++; if (weight<INT_MAX) weight += g->weights[i]; } edges/=2; /* Each is counted twice. */ if (output) { /* Semi-weighted means all weights are equal, but not 1. */ fprintf(output,"%s graph has %d vertices, %d edges " "(density %.2f).\n", weighted?"Weighted": ((g->weights[0]==1)?"Unweighted":"Semi-weighted"), g->n,edges,(float)edges/((float)(g->n - 1)*(g->n)/2)); if (asymm) fprintf(output," WARNING: Graph contained %d " "asymmetric edges!\n",asymm); if (refl) fprintf(output," WARNING: Graph contained %d " "reflexive edges!\n",refl); if (nonpos) fprintf(output," WARNING: Graph contained %d " "non-positive vertex weights!\n",nonpos); if (extra) fprintf(output," WARNING: Graph contained %d edges " "to non-existent vertices!\n",extra); if (weight>=INT_MAX) fprintf(output," WARNING: Total graph weight >= " "INT_MAX!\n"); if (asymm==0 && refl==0 && nonpos==0 && extra==0 && weight<INT_MAX) fprintf(output,"Graph OK.\n"); } if (asymm || refl || nonpos || extra || weight>=INT_MAX) return FALSE; return TRUE; }
/** * Find all of the maximal cliques in the provided matlab matrix, which * should represent an adjacency matrix. Most of this function just * translates from MATLAB input for processing with Cliquer and then * translates the output of Cliquer back into MATLAB data. * * The MATLAB arguments are as follows: * prhs[0] mtxAdj The input adjacency matrix. Only the upper- * triangular part of this is used. * prhs[1] iMinWeight The minimum weight of cliques to find. * prhs[2] iMaxWeight The maximum weight of cliques to find. * prhs[3] bOnlyMaximal If `false` (i.e., zero), return all cliques; * otherwise, return only maximal cliques. * prhs[4] iMaxNumCliques The maximum number of cliques to be returned * (due to a [perceived] limitation of Cliquer). */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { /* Ensure that an appropriate number of arguments were provided and that an * an appropriate number of return variables were requested. */ if (nrhs != 5) mexErrMsgTxt("Exactly five input arguments are required."); else if (nlhs > 2) mexErrMsgTxt("Too many output arguments were requested."); /* Retrieve and store the size of the input adjacency matrix for size * checking and later use. */ mwSize iRows = mxGetM(prhs[0]); mwSize iCols = mxGetN(prhs[0]); /* Perform size- and type-checking on the input values. */ if ((iRows != iCols) || !mxIsNumeric(prhs[0]) || mxIsComplex(prhs[0])) mexErrMsgTxt("The first argument must be an integer-valued square matrix."); else if (mxGetM(prhs[1]) != 1 || mxGetN(prhs[1]) != 1 || !mxIsNumeric(prhs[1])) mexErrMsgTxt("The second argument must be an integer."); else if (mxGetM(prhs[2]) != 1 || mxGetN(prhs[2]) != 1 || !mxIsNumeric(prhs[2])) mexErrMsgTxt("The third argument must be an integer."); else if (mxGetM(prhs[3]) != 1 || mxGetN(prhs[3]) != 1 || !mxIsLogical(prhs[3])) mexErrMsgTxt("The fourth argument must be a logical scalar."); else if (mxGetM(prhs[4]) != 1 || mxGetN(prhs[4]) != 1 || !mxIsNumeric(prhs[4])) mexErrMsgTxt("The fifth argument must be an integer."); /* Declare variables to hold the input arguments (except the first). Each * of these can be retrieved by indexing `prhs`. */ int iMinWeight = MAX(0, (int) mxGetScalar(prhs[1])); int iMaxWeight = MIN(iCols, (int) mxGetScalar(prhs[2])); int bOnlyMaximal = (mxGetScalar(prhs[3]) == 0) ? FALSE : TRUE; int iMaxNumCliques = (int) mxGetScalar(prhs[4]); /* These variables are for storing the graph corresponding to the input * adjacency matrix, the list of cliques found in that graph, and the return * value for this MATLAB function. */ graph_t *ptrGraph; set_t arrCliqueList[iMaxNumCliques]; double *ptrOutputMatrix; /* Miscellaneous variable declarations. */ int i, j, idx, iNumCliques, iNumCliquesReturned; /* Create a graph from the adjacency matrix `prhs[0]`. */ ptrGraph = MatrixToGraph(mxGetPr(prhs[0]), iCols); /* Find the cliques in the associated graph. */ iNumCliques = FindCliques(ptrGraph, iMinWeight, iMaxWeight, bOnlyMaximal, iMaxNumCliques, arrCliqueList, iMaxNumCliques); /* We are done with the graph. Free the memory used to store it. */ graph_free(ptrGraph); /* Retrieve the number of cliques returned by the function, which is bounded * above by `iMaxNumCliques`. */ iNumCliquesReturned = MIN(iNumCliques, iMaxNumCliques); /* Output the total number of cliques found. */ plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL); mxGetPr(plhs[0])[0] = iNumCliques; /* Create the output matrix, which will have one row for each clique and * one column for each node of the graph. */ plhs[1] = mxCreateDoubleMatrix(iNumCliquesReturned, iCols, mxREAL); ptrOutputMatrix = mxGetPr(plhs[1]); /* Fill in the rows of the output matrix by looping through the cliques * that were found. */ for (i = 0; i < iNumCliquesReturned; i++) { /* Fill in the entries of this row by looping through the corresponding * clique to find the vertices contained in the clique. */ for (j = 0; j < SET_MAX_SIZE(arrCliqueList[i]); j++) { /* The entries of the output matrix are initialized to zeros. If * the vertex 'j' is in clique 'i', place a 1 in the (i, j) entry * of the output matrix. */ if (SET_CONTAINS(arrCliqueList[i], j)) { /* Matrices in Matlab are stored column-wise (i.e., the columns * of the matrix are stacked and stored as a column vector); so, * we must access the output as a 1-dimensional array. The index * of the entry corresponding to the (i, j) position in this * matrix is calculated in 'idx' below. */ idx = j * iNumCliques + i; ptrOutputMatrix[idx] = 1; } } /* Now that we've stored this clique as a row in a matrix, we can free * the memory used to store the clique. */ set_free(arrCliqueList[i]); } return; }