From d6ff8c61fc429287cf6ebe63d78b86c2a86571ad Mon Sep 17 00:00:00 2001 From: alexgutteridge Date: Tue, 4 Sep 2007 09:40:29 +0000 Subject: [PATCH] Clique functions. --- Manifest.txt | 2 + ext/cIGraph.c | 5 ++ ext/cIGraph.h | 6 ++ ext/cIGraph_cliques.c | 178 ++++++++++++++++++++++++++++++++++++++++++ test/tc_cliques.rb | 21 +++++ test/test_all.rb | 5 +- 6 files changed, 215 insertions(+), 2 deletions(-) create mode 100644 ext/cIGraph_cliques.c create mode 100644 test/tc_cliques.rb diff --git a/Manifest.txt b/Manifest.txt index 2e5816f..80a2b2e 100644 --- a/Manifest.txt +++ b/Manifest.txt @@ -10,6 +10,7 @@ ext/cIGraph_attribute_handler.c ext/cIGraph_basic_properties.c ext/cIGraph_basic_query.c ext/cIGraph_centrality.c +ext/cIGraph_cliques.c ext/cIGraph_components.c ext/cIGraph_direction.c ext/cIGraph_error_handlers.c @@ -34,6 +35,7 @@ test/tc_attributes.rb test/tc_basic_properties.rb test/tc_basic_query.rb test/tc_centrality.rb +test/tc_cliques.rb test/tc_components.rb test/tc_copy.rb test/tc_cores.rb diff --git a/ext/cIGraph.c b/ext/cIGraph.c index b223626..e6a4112 100644 --- a/ext/cIGraph.c +++ b/ext/cIGraph.c @@ -296,6 +296,11 @@ void Init_igraph(){ rb_define_method(cIGraph, "cocitation", cIGraph_cocitation, 1); /* in cIGraph_other_ops.c */ rb_define_method(cIGraph, "get_adjacency", cIGraph_get_adjacency, 1); /* in cIGraph_other_ops.c */ + rb_define_method(cIGraph, "cliques", cIGraph_cliques, 2); /* in cIGraph_cliques.c */ + rb_define_method(cIGraph, "largest_cliques", cIGraph_largest_cliques, 0); /* in cIGraph_cliques.c */ + rb_define_method(cIGraph, "maximal_cliques", cIGraph_maximal_cliques, 0); /* in cIGraph_cliques.c */ + rb_define_method(cIGraph, "clique_number", cIGraph_clique_number, 0); /* in cIGraph_cliques.c */ + rb_define_method(cIGraph, "topological_sorting", cIGraph_topological_sorting, 1); /* in cIGraph_topological_sort.c */ rb_define_singleton_method(cIGraph, "read_graph_edgelist", cIGraph_read_graph_edgelist, 2); /* in cIGraph_file.c */ diff --git a/ext/cIGraph.h b/ext/cIGraph.h index 222d41d..5da8386 100644 --- a/ext/cIGraph.h +++ b/ext/cIGraph.h @@ -130,6 +130,12 @@ VALUE cIGraph_bibcoupling (VALUE self, VALUE vs); VALUE cIGraph_cocitation (VALUE self, VALUE vs); VALUE cIGraph_get_adjacency(VALUE self, VALUE mode); +//Cliques +VALUE cIGraph_cliques(VALUE self, VALUE min, VALUE max); +VALUE cIGraph_largest_cliques(VALUE self); +VALUE cIGraph_maximal_cliques(VALUE self); +VALUE cIGraph_clique_number(VALUE self); + //File handling VALUE cIGraph_read_graph_edgelist (VALUE self, VALUE file, VALUE mode); VALUE cIGraph_write_graph_edgelist(VALUE self, VALUE file); diff --git a/ext/cIGraph_cliques.c b/ext/cIGraph_cliques.c new file mode 100644 index 0000000..69b74bd --- /dev/null +++ b/ext/cIGraph_cliques.c @@ -0,0 +1,178 @@ +#include "igraph.h" +#include "ruby.h" +#include "cIGraph.h" + +/* call-seq: + * graph.cliques(min_size,max_size) -> Array + * + * Find all or some cliques in a graph + * + * Cliques are fully connected subgraphs of a graph. + * + * If you are only interested in the size of the largest clique in the + * graph, use IGraph#clique_number instead. + */ + +VALUE cIGraph_cliques(VALUE self, VALUE min, VALUE max){ + + igraph_t *graph; + igraph_vector_ptr_t res; + igraph_vector_t *vec; + int i; + int j; + VALUE clique; + VALUE object; + VALUE cliques = rb_ary_new(); + + Data_Get_Struct(self, igraph_t, graph); + + igraph_vector_ptr_init(&res,0); + + igraph_cliques(graph, &res, NUM2INT(min), NUM2INT(max)); + + for(i=0; i Array + * + * Finds the largest clique(s) in a graph. + * + * A clique is largest (quite intuitively) if there is no other clique in + * the graph which contains more vertices. + * + * Note that this is not neccessarily the same as a maximal clique, ie. + * the largest cliques are always maximal but a maximal clique is not always + * largest. + */ + +VALUE cIGraph_largest_cliques(VALUE self){ + + igraph_t *graph; + igraph_vector_ptr_t res; + igraph_vector_t *vec; + int i; + int j; + VALUE clique; + VALUE object; + VALUE cliques = rb_ary_new(); + + Data_Get_Struct(self, igraph_t, graph); + + igraph_vector_ptr_init(&res,0); + + igraph_largest_cliques(graph, &res); + + for(i=0; i Array + * + * Find all maximal cliques of a graph + * + * A maximal clique is a clique which can't be extended any more by adding a + * new vertex to it. This is actually implemented by looking for a maximal + * independent vertex set in the complementer of the graph. + * + * If you are only interested in the size of the largest clique in the + * graph, use IGraph#clique_number instead. + */ + +VALUE cIGraph_maximal_cliques(VALUE self){ + + igraph_t *graph; + igraph_vector_ptr_t res; + igraph_vector_t *vec; + int i; + int j; + VALUE clique; + VALUE object; + VALUE cliques = rb_ary_new(); + + Data_Get_Struct(self, igraph_t, graph); + + igraph_vector_ptr_init(&res,0); + + igraph_maximal_cliques(graph, &res); + + for(i=0; i Integer + * + * Find the clique number of the graph + * + * The clique number of a graph is the size of the largest clique. + */ + +VALUE cIGraph_clique_number(VALUE self){ + + igraph_t *graph; + igraph_integer_t res; + + Data_Get_Struct(self, igraph_t, graph); + + igraph_clique_number(graph, &res); + + return INT2NUM(res); + +} diff --git a/test/tc_cliques.rb b/test/tc_cliques.rb new file mode 100644 index 0000000..8689116 --- /dev/null +++ b/test/tc_cliques.rb @@ -0,0 +1,21 @@ +require 'test/unit' +require 'igraph' + +class TestGraph < Test::Unit::TestCase + def test_cliques + g = IGraph.new([1,2,3,4],false) + assert_equal [[1,2],[3,4]], g.cliques(2,0) + end + def test_largest_cliques + g = IGraph.new(['A','B','C','D','A','E','B','E'],false) + assert_equal [['A','B','E','B','E']], g.largest_cliques() + end + def test_maximal_cliques + g = IGraph.new(['A','B','C','D','A','E','B','E'],false) + assert_equal [['A','B','E'],['C','D']], g.maximal_cliques() + end + def test_clique_number + g = IGraph.new(['A','B','C','D','A','E','B','E'],false) + assert_equal 3, g.clique_number + end + end diff --git a/test/test_all.rb b/test/test_all.rb index 07891e8..c836dfe 100644 --- a/test/test_all.rb +++ b/test/test_all.rb @@ -3,9 +3,8 @@ require 'test/unit' require 'tc_attributes' +require 'tc_cliques' require 'tc_create' -require 'tc_iterators' -require 'tc_selectors' require 'tc_add_delete' require 'tc_basic_query' require 'tc_basic_properties' @@ -16,9 +15,11 @@ require 'tc_cores' require 'tc_directedness' require 'tc_error_handling' require 'tc_file_read_write' +require 'tc_iterators' require 'tc_layout' require 'tc_matrix' require 'tc_other_ops' +require 'tc_selectors' require 'tc_shortest_paths' require 'tc_spanning' require 'tc_spectral'