/* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see */ #include #include #include #include #include"misc.h" #include"LinkedList.h" #include"MemoryManager.h" /*! \file misc.c \brief A collection of useful comparators and print functions \author Darren Strash (first name DOT last name AT gmail DOT com) \copyright Copyright (c) 2011 Darren Strash. This code is released under the GNU Public License (GPL) 3.0. \image html gplv3-127x51.png \htmlonly
See GPL 3.0 here
\endhtmlonly */ /*! \brief compare integers return -1,0,1 for <,=,> \param node1 an integer \param node2 an integer \return -1 if <, 0 if =, and 1 if >. */ int nodeComparator(void* node1, void* node2) { if ((int)node1 < (int)node2) return -1; if((int)node1 > (int)node2) return 1; return 0; } /*! \brief compare integer pointers; return -1,0,1 for <,=,>; used for calling sort(). \param node1 a pointer to an integer \param node2 a pointer to an integer \return -1 if <, 0 if =, and 1 if >. */ int sortComparator(void* node1, void* node2) { if (*(int*)node1 < *(int*)node2) return -1; if(*(int*)node1 > *(int*)node2) return 1; return 0; } /*! \brief print an array of integers to standard out. \param array the array to print \param size the length of the array */ void printArray(int* array, int size) { int i = 0; while(ihead->next; while(!isTail(curr)) { int* clique = (int*)curr->data; #ifdef DEBUG int i=0; while(clique[i] != -1) { printf("%d", clique[i]); if(clique[i+1] != -1) printf(" "); i++; } printf("\n"); #endif Free(clique); curr = curr->next; } destroyLinkedList(cliques); } /*! \brief read in a graph from stdin and return an adjacency list, as an array of linked lists of integers. \param n this will be the number of vertices in the graph when this function returns. \param m this will be 2x the number of edges in the graph when this function returns. \return an array of linked lists of integers (adjacency list) representation of the graph */ LinkedList** readInGraphAdjList(int* n, int* m) { int u, v; // endvertices, to read edges. if(scanf("%d", n)!=1) { fprintf(stderr, "problem with line 1 in input file\n"); exit(1); } if(scanf("%d", m)!=1) { fprintf(stderr, "problem with line 2 in input file\n"); exit(1); } //#ifdef DEBUG printf("%d ", *n); // vertices printf("%d ", *m/2); // edges //#endif LinkedList** adjList = Calloc(*n, sizeof(LinkedList*)); int i = 0; while(i < *n) { adjList[i] = createLinkedList(); i++; } i = 0; while(i < *m) { if(scanf("%d,%d", &u, &v)!=2) { printf("problem with line %d in input file\n", i+2); exit(1); } assert(u < *n && u > -1); assert(v < *n && v > -1); if(u==v) printf("%d=%d\n", u, v); assert(u != v); addLast(adjList[u], (void*)v); i++; } #ifdef DEBUG printArrayOfLinkedLists(adjList, *n); #endif return adjList; } /*! \brief execute an maximal clique listing algorithm that takes an adjacency matrix as input, time it, and print the number of maximal cliques found along with time information. \param function a function that computes all maximal cliques and returns the number of maximal cliques found \param algName a zero-terminated character string that will be printed with the statistics of the algorithm run. \param adjMatrix the input graph in the adjacency matrix format. \param cliques A linked list of cliques to return. (only available when compiled with RETURN_CLIQUES_ONE_BY_ONE defined) \param n the number of vertices in the input graph */ void runAndPrintStatsMatrix(long (*function)(char**, #ifdef RETURN_CLIQUES_ONE_BY_ONE LinkedList*, #endif int), const char* algName, char** adjMatrix, #ifdef RETURN_CLIQUES_ONE_BY_ONE LinkedList* cliques, #endif int n ) { //fprintf(stdout, "%s: ", algName); fflush(stderr); clock_t start = clock(); long cliqueCount = function(adjMatrix, #ifdef RETURN_CLIQUES_ONE_BY_ONE cliques, #endif n); clock_t end = clock(); //fprintf(stderr, "%ld maximal cliques, ", cliqueCount); fprintf(stdout, "%ld 0 0 ", cliqueCount); //fprintf(stdout, "%f \n", (double)(end-start)/(double)(CLOCKS_PER_SEC)); fprintf(stdout, "%ld \n", (end-start)/1000); fflush(stderr); } /*! \brief execute an maximal clique listing algorithm that takes an adjacency list as input, time it, and print the number of maximal cliques found along with time information. \param function a function that computes all maximal cliques and returns the number of maximal cliques found \param algName a zero-terminated character string that will be printed with the statistics of the algorithm run. \param adjListLinked the input graph in the array of linked lists (adjacency list) format. \param adjListArray the input graph in the array of arrays (adjacency list) format. \param cliques A linked list of cliques to return. (only available when compiled with RETURN_CLIQUES_ONE_BY_ONE defined) \param degree An array, indexed by vertex, containing the degree of that vertex. \param n the number of vertices in the input graph */ void runAndPrintStatsListList( long (*function)(LinkedList**, int**, #ifdef RETURN_CLIQUES_ONE_BY_ONE LinkedList*, #endif int*, int), const char* algName, LinkedList** adjListLinked, int** adjListArray, #ifdef RETURN_CLIQUES_ONE_BY_ONE LinkedList* cliques, #endif int* degree, int n ) { //fprintf(stdout, "%s: ", algName); fflush(stderr); clock_t start = clock(); long cliqueCount = function(adjListLinked, adjListArray, #ifdef RETURN_CLIQUES_ONE_BY_ONE cliques, #endif degree, n); clock_t end = clock(); fprintf(stdout,"%ld 0 0 ", cliqueCount); //fprintf(stdout, "%f \n", (double)(end-start)/(double)(CLOCKS_PER_SEC)); fprintf(stdout, "%ld \n", (end-start)/1000); fflush(stderr); } /*! \brief process a clique, which may include printing it in one of several formats and/or adding the clique to a linked list. \param cliques A linked list of cliques to return. (only available when compiled with RETURN_CLIQUES_ONE_BY_ONE defined) \param clique the clique to add to the linked list */ inline void processClique( #ifdef RETURN_CLIQUES_ONE_BY_ONE LinkedList *cliques, #endif LinkedList *clique) { #ifdef PRINT_CLIQUES_TOMITA_STYLE printf("c "); #endif #ifdef PRINT_CLIQUES_ONE_BY_ONE printList(clique, &printInt); #endif #ifdef RETURN_CLIQUES_ONE_BY_ONE { int* cliqueArray = Calloc(length(clique) + 1, sizeof(int)); int i = 0; Link* curr = clique->head->next; while(!isTail(curr)) { cliqueArray[i] = (int)curr->data; i++; curr = curr->next; } cliqueArray[i] = -1; addLast(cliques, (void*)cliqueArray); } #endif }