Browse Source

Clique functions.

git-svn-id: http://igraph.rubyforge.org/svn/trunk@48 71f48855-0bbf-4aa5-930d-4df415e86613
master
alexgutteridge 19 years ago
parent
commit
4df5d94df3
6 changed files with 215 additions and 2 deletions
  1. +2
    -0
      Manifest.txt
  2. +5
    -0
      ext/cIGraph.c
  3. +6
    -0
      ext/cIGraph.h
  4. +178
    -0
      ext/cIGraph_cliques.c
  5. +21
    -0
      test/tc_cliques.rb
  6. +3
    -2
      test/test_all.rb

+ 2
- 0
Manifest.txt 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


+ 5
- 0
ext/cIGraph.c 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 */


+ 6
- 0
ext/cIGraph.h 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
- 0
ext/cIGraph_cliques.c 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
- 0
test/tc_cliques.rb 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

+ 3
- 2
test/test_all.rb 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'


Loading…
Cancel
Save