Permalink
Browse files

Merge pull request #888 from szhorvat/cliquer

Integrate Cliquer library
  • Loading branch information...
2 parents 70c755e + 67aa0ea commit 0032faab942cd2b14ac56278f334b01f285b6af5 @gaborcsardi gaborcsardi committed Apr 10, 2016
View
@@ -156,7 +156,7 @@ community.xml: community.xxml $(SRCDIR)/community.c $(SRCDIR)/clustertool.cpp $(
$(DOXROX) -t $< -e $(REGEX) -o $@ $(SRCDIR)/community.c $(SRCDIR)/clustertool.cpp $(SRCDIR)/walktrap.cpp $(SRCDIR)/fast_community.c $(SRCDIR)/optimal_modularity.c $(INCLUDEDIR)/igraph_community.h $(SRCDIR)/infomap.cc
cliques.xml: cliques.xxml $(SRCDIR)/cliques.c $(SRCDIR)/maximal_cliques.c
- $(DOXROX) -t $< -e $(REGEX) -o $@ $(SRCDIR)/cliques.c $(SRCDIR)/maximal_cliques.c
+ $(DOXROX) -t $< -e $(REGEX) -o $@ $(SRCDIR)/cliques.c $(SRCDIR)/maximal_cliques.c $(INCLUDEDIR)/igraph_cliques.h
stack.xml: stack.xxml $(SRCDIR)/stack.pmt
$(DOXROX) -t $< -e $(REGEX) -o $@ $(SRCDIR)/stack.pmt
@@ -272,4 +272,4 @@ igraph-docs.pdf: igraph-docs.xml $(DOCFIX2)
&& fop -fo igraph-docs.fo -pdf igraph-docs.pdf
CLEANFILES=$(DOCINCLUDES) html/*.html html/stamp \
- igraph-docs.{dvi,info,pdf,ps,texi,txml} igraph-docs2.xml
+ igraph-docs.{dvi,info,pdf,ps,texi,txml} igraph-docs2.xml
View
@@ -1,4 +1,4 @@
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
<!ENTITY igraph "igraph">
]>
@@ -13,12 +13,21 @@ to cliques and independent vertex sets.
<section><title>Cliques</title>
<!-- doxrox-include igraph_cliques -->
+<!-- doxrox-include igraph_clique_size_hist -->
+<!-- doxrox-include igraph_cliques_callback -->
+<!-- doxrox-include igraph_clique_handler_t -->
<!-- doxrox-include igraph_largest_cliques -->
<!-- doxrox-include igraph_maximal_cliques -->
<!-- doxrox-include igraph_maximal_cliques_count -->
<!-- doxrox-include igraph_clique_number -->
</section>
+<section><title>Weighted cliques</title>
+<!-- doxrox-include igraph_weighted_cliques -->
+<!-- doxrox-include igraph_largest_weighted_cliques -->
+<!-- doxrox-include igraph_weighted_clique_number -->
+</section>
+
<section><title>Independent Vertex Sets</title>
<!-- doxrox-include igraph_independent_vertex_sets -->
<!-- doxrox-include igraph_largest_independent_vertex_sets -->
@@ -24,7 +24,7 @@
#ifndef IGRAPH_BENCH_H
#define IGRAPH_BENCH_H
-inline void igraph_get_cpu_time(igraph_real_t *data) {
+static inline void igraph_get_cpu_time(igraph_real_t *data) {
struct rusage self, children;
getrusage(RUSAGE_SELF, &self);
@@ -0,0 +1,32 @@
+
+#include <igraph.h>
+
+#include "bench.h"
+
+int main() {
+ igraph_t g;
+ igraph_vector_ptr_t res;
+ igraph_integer_t i, n;
+
+ igraph_rng_seed(igraph_rng_default(), 42);
+
+ igraph_erdos_renyi_game(&g, IGRAPH_ERDOS_RENYI_GNM, 100, 3000, /* directed = */ 0, /* loops= */ 0);
+
+ igraph_vector_ptr_init(&res, 0);
+
+ BENCH("1 Cliques in random graph with 100 vertices and 3000 edges",
+ igraph_cliques(&g, &res, /* min_size= */ 0, /* max_size= */ 0);
+ );
+
+ igraph_destroy(&g);
+
+ n=igraph_vector_ptr_size(&res);
+ for (i=0; i<n; i++) {
+ igraph_vector_t *v=VECTOR(res)[i];
+ igraph_vector_destroy(v);
+ igraph_free(v);
+ }
+ igraph_vector_ptr_destroy(&res);
+
+ return 0;
+}
@@ -24,6 +24,37 @@
#include <igraph.h>
#include <stdlib.h>
+int compare_vectors(const void *p1, const void *p2) {
+ igraph_vector_t *v1, *v2;
+ long s1, s2, i;
+
+ v1 = *((igraph_vector_t **) p1);
+ v2 = *((igraph_vector_t **) p2);
+ s1 = igraph_vector_size(v1);
+ s2 = igraph_vector_size(v2);
+ if (s1 < s2)
+ return -1;
+ if (s1 > s2)
+ return 1;
+ for (i=0; i < s1; ++i) {
+ if (VECTOR(*v1)[i] < VECTOR(*v2)[i])
+ return -1;
+ if (VECTOR(*v1)[i] > VECTOR(*v2)[i])
+ return 1;
+ }
+ return 0;
+}
+
+/* Takes a pointer vector of vectors. Sorts each vector, then sorts the pointer vector */
+void canonicalize_list(igraph_vector_ptr_t *list) {
+ long i, len;
+ len = igraph_vector_ptr_size(list);
+ for (i=0; i<len; ++i) {
+ igraph_vector_sort((igraph_vector_t *) VECTOR(*list)[i]);
+ }
+ qsort(&(VECTOR(*list)[0]), len, sizeof(void *), &compare_vectors);
+}
+
void print_vector(igraph_vector_t *v) {
long int i, n=igraph_vector_size(v);
for (i=0; i<n; i++) {
@@ -35,6 +66,46 @@ void print_vector(igraph_vector_t *v) {
void warning_handler_ignore(const char* reason,const char* file,int line,int e) {
}
+
+struct userdata {
+ int i;
+ igraph_vector_ptr_t *list;
+};
+
+igraph_bool_t handler(igraph_vector_t *clique, void *arg) {
+ struct userdata *ud;
+ igraph_bool_t cont;
+
+ ud = (struct userdata *) arg;
+ cont = 1; /* true */
+
+ if (compare_vectors(&clique, &(VECTOR(*(ud->list))[ud->i])) != 0) {
+ printf("igraph_cliques() and igraph_cliques_callback() give different results.\n");
+ cont = 0; /* false */
+ }
+
+ igraph_vector_destroy(clique);
+ igraph_free(clique);
+
+ ud->i += 1;
+
+ return cont;
+}
+
+void test_callback(const igraph_t *graph) {
+ igraph_vector_ptr_t list;
+ struct userdata ud;
+
+ igraph_vector_ptr_init(&list, 0);
+ igraph_cliques(graph, &list, 0, 0);
+
+ ud.i = 0;
+ ud.list = &list;
+
+ igraph_cliques_callback(graph, 0, 0, &handler, (void *) &ud);
+}
+
+
int main() {
igraph_t g;
@@ -60,10 +131,10 @@ int main() {
}
n = igraph_vector_ptr_size(&result);
printf("%ld cliques found\n", (long)n);
+ canonicalize_list(&result);
for (i=0; i<n; i++) {
- igraph_vector_t* v;
- v=igraph_vector_ptr_e(&result,i);
- print_vector((igraph_vector_t*)v);
+ igraph_vector_t* v = (igraph_vector_t*) igraph_vector_ptr_e(&result,i);
+ print_vector(v);
igraph_vector_destroy(v);
free(v);
}
@@ -72,6 +143,8 @@ int main() {
igraph_clique_number(&g, &omega);
printf("omega=%ld\n", (long)omega);
+ test_callback(&g);
+
igraph_destroy(&g);
igraph_tree(&g, 5, 2, IGRAPH_TREE_OUT);
@@ -15,8 +15,8 @@
3 4
4 5
2 cliques found
- 4 1 2 5
- 4 1 2 3
+ 1 2 3 4
+ 1 2 4 5
29 cliques found
0
1
@@ -0,0 +1,169 @@
+
+#include <igraph.h>
+#include <stdlib.h>
+
+int compare_vectors(const void *p1, const void *p2) {
+ igraph_vector_t *v1, *v2;
+ long s1, s2, i;
+
+ v1 = *((igraph_vector_t **) p1);
+ v2 = *((igraph_vector_t **) p2);
+ s1 = igraph_vector_size(v1);
+ s2 = igraph_vector_size(v2);
+ if (s1 < s2)
+ return -1;
+ if (s1 > s2)
+ return 1;
+ for (i=0; i < s1; ++i) {
+ if (VECTOR(*v1)[i] < VECTOR(*v2)[i])
+ return -1;
+ if (VECTOR(*v1)[i] > VECTOR(*v2)[i])
+ return 1;
+ }
+ return 0;
+}
+
+/* Takes a pointer vector of vectors. Sorts each vector, then sorts the pointer vector */
+void canonicalize_list(igraph_vector_ptr_t *list) {
+ long i, len;
+ len = igraph_vector_ptr_size(list);
+ for (i=0; i<len; ++i) {
+ igraph_vector_sort((igraph_vector_t *) VECTOR(*list)[i]);
+ }
+ qsort(&(VECTOR(*list)[0]), len, sizeof(void *), &compare_vectors);
+}
+
+/* Prints a clique vector along with its weight */
+void print_weighted_clique(const igraph_vector_t *clique, const igraph_vector_t *vertex_weights) {
+ long int i, n=igraph_vector_size(clique);
+ igraph_real_t clique_weight = 0.0;
+ for (i=0; i<n; i++) {
+ int v = VECTOR(*clique)[i];
+ clique_weight += igraph_vector_e(vertex_weights, v);
+ printf(" %d", v);
+ }
+ printf(" w=%.1f\n", clique_weight);
+}
+
+int main() {
+ igraph_t graph;
+
+ const igraph_integer_t n = 10; /* number of vertices in test graph */
+
+ /* edges of the test graph */
+ igraph_vector_t edges;
+ igraph_real_t edge_data[] = {0., 1., 0., 6., 0., 7., 0., 8., 0., 9., 1., 2., 1., 3., 1., 4., 1.,
+ 6., 1., 7., 1., 8., 1., 9., 2., 3., 2., 5., 2., 6., 2., 7., 2., 9.,
+ 3., 5., 3., 6., 3., 7., 3., 9., 4., 5., 4., 6., 4., 7., 4., 9., 5.,
+ 8., 6., 7., 6., 8., 7., 8., 8., 9.};
+
+ /* vertex weights in test graph,
+ note that current implementation only supports integer weights */
+ igraph_vector_t vertex_weights;
+ igraph_real_t vertex_weight_data[] = {3., 2., 3., 5., 2., 3., 1., 3., 5., 5.};
+
+ igraph_vector_ptr_t result; /* result clique list */
+ igraph_integer_t count; /* number of cliques found */
+
+ igraph_real_t weighted_clique_no;
+
+ int i;
+
+
+ /* create graph */
+ igraph_vector_init_copy(&edges, edge_data, (sizeof edge_data)/sizeof(igraph_real_t));
+ igraph_create(&graph, &edges, n, /* directed= */ 0);
+
+ /* set up vertex weight vector */
+ igraph_vector_init_copy(&vertex_weights, vertex_weight_data, (sizeof vertex_weight_data)/sizeof(igraph_real_t));
+
+ /* initialize result vector_ptr */
+ igraph_vector_ptr_init(&result, 0);
+
+
+ /* all weighed cliques above weight 6 */
+ igraph_weighted_cliques(&graph, &vertex_weights, &result, 6, 0, /* maximal= */ 0);
+
+ count = igraph_vector_ptr_size(&result);
+ printf("%ld weighted cliques found above weight 6\n", (long) count);
+
+ canonicalize_list(&result);
+ for (i=0; i < count; i++) {
+ igraph_vector_t* v = (igraph_vector_t*) igraph_vector_ptr_e(&result,i);
+ print_weighted_clique(v, &vertex_weights);
+ igraph_vector_destroy(v);
+ free(v);
+ }
+
+
+ /* all weighed cliques beteen weights 5 and 10 */
+ igraph_weighted_cliques(&graph, &vertex_weights, &result, 5, 10, /* maximal= */ 0);
+
+ count = igraph_vector_ptr_size(&result);
+ printf("%ld weighted cliques found between weights 5 and 10\n", (long) count);
+
+ canonicalize_list(&result);
+ for (i=0; i < count; i++) {
+ igraph_vector_t* v = (igraph_vector_t*) igraph_vector_ptr_e(&result,i);
+ print_weighted_clique(v, &vertex_weights);
+ igraph_vector_destroy(v);
+ free(v);
+ }
+
+
+ /* maximal weighed cliques above weight 7 */
+ igraph_weighted_cliques(&graph, &vertex_weights, &result, 7, 0, /* maximal= */ 1);
+
+ count = igraph_vector_ptr_size(&result);
+ printf("%ld maximal weighted cliques found above weight 7\n", (long) count);
+
+ canonicalize_list(&result);
+ for (i=0; i < count; i++) {
+ igraph_vector_t* v = (igraph_vector_t*) igraph_vector_ptr_e(&result,i);
+ print_weighted_clique(v, &vertex_weights);
+ igraph_vector_destroy(v);
+ free(v);
+ }
+
+
+ /* maximal weighed cliques beteen weights 5 and 10 */
+ igraph_weighted_cliques(&graph, &vertex_weights, &result, 5, 10, /* maximal= */ 1);
+
+ count = igraph_vector_ptr_size(&result);
+ printf("%ld maximal weighted cliques found between weights 5 and 10\n", (long) count);
+
+ canonicalize_list(&result);
+ for (i=0; i < count; i++) {
+ igraph_vector_t* v = (igraph_vector_t*) igraph_vector_ptr_e(&result,i);
+ print_weighted_clique(v, &vertex_weights);
+ igraph_vector_destroy(v);
+ free(v);
+ }
+
+
+ /* largest weight cliques */
+ igraph_largest_weighted_cliques(&graph, &vertex_weights, &result);
+
+ count = igraph_vector_ptr_size(&result);
+ printf("%ld largest weight cliques found\n", (long) count);
+
+ canonicalize_list(&result);
+ for (i=0; i < count; i++) {
+ igraph_vector_t* v = (igraph_vector_t*) igraph_vector_ptr_e(&result,i);
+ print_weighted_clique(v, &vertex_weights);
+ igraph_vector_destroy(v);
+ free(v);
+ }
+
+ igraph_weighted_clique_number(&graph, &vertex_weights, &weighted_clique_no);
+ printf("weighted clique number: %.1f\n", weighted_clique_no);
+
+
+ /* free data structures */
+ igraph_vector_ptr_destroy(&result);
+ igraph_vector_destroy(&vertex_weights);
+ igraph_destroy(&graph);
+ igraph_vector_destroy(&edges);
+
+ return 0;
+}
Oops, something went wrong.

0 comments on commit 0032faa

Please sign in to comment.