Clique functions.

This commit is contained in:
alexgutteridge 2007-09-04 09:40:29 +00:00
parent fdae1b7e07
commit d6ff8c61fc
6 changed files with 215 additions and 2 deletions

View File

@ -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

View File

@ -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 */

View File

@ -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);

178
ext/cIGraph_cliques.c Normal file
View File

@ -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<igraph_vector_ptr_size(&res); i++){
clique = rb_ary_new();
rb_ary_push(cliques,clique);
vec = VECTOR(res)[i];
for(j=0; j<igraph_vector_size(vec); j++){
vec = VECTOR(res)[i];
object = cIGraph_get_vertex_object(self,VECTOR(*vec)[j]);
rb_ary_push(clique,object);
}
}
for(i=0;i<igraph_vector_ptr_size(&res);i++){
igraph_vector_destroy(VECTOR(res)[i]);
free(VECTOR(res)[i]);
}
igraph_vector_ptr_destroy(&res);
return cliques;
}
/* call-seq:
* graph.largest_cliques() -> 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<igraph_vector_ptr_size(&res); i++){
clique = rb_ary_new();
rb_ary_push(cliques,clique);
vec = VECTOR(res)[i];
for(j=0; j<igraph_vector_size(vec); j++){
vec = VECTOR(res)[i];
object = cIGraph_get_vertex_object(self,VECTOR(*vec)[j]);
rb_ary_push(clique,object);
}
}
for(i=0;i<igraph_vector_ptr_size(&res);i++){
igraph_vector_destroy(VECTOR(res)[i]);
free(VECTOR(res)[i]);
}
igraph_vector_ptr_destroy(&res);
return cliques;
}
/* call-seq:
* graph.maximal_cliques() -> 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<igraph_vector_ptr_size(&res); i++){
clique = rb_ary_new();
rb_ary_push(cliques,clique);
vec = VECTOR(res)[i];
for(j=0; j<igraph_vector_size(vec); j++){
vec = VECTOR(res)[i];
object = cIGraph_get_vertex_object(self,VECTOR(*vec)[j]);
rb_ary_push(clique,object);
}
}
for(i=0;i<igraph_vector_ptr_size(&res);i++){
igraph_vector_destroy(VECTOR(res)[i]);
free(VECTOR(res)[i]);
}
igraph_vector_ptr_destroy(&res);
return cliques;
}
/* call-seq:
* graph.clique_number() -> 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);
}

21
test/tc_cliques.rb Normal file
View File

@ -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

View File

@ -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'