Esempio n. 1
0
/*
 * 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;
                }
        }
Esempio n. 2
0
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;
}
Esempio n. 3
0
// 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;
}
Esempio n. 4
0
/*
 * 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;
}
Esempio n. 5
0
/**
 * 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;
}