rankable_graph 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/README.rdoc +30 -0
- data/VERSION +1 -1
- data/benchmark.rb +6 -10
- data/ext/rankable_graph.c +14 -0
- data/rankable_graph.gemspec +2 -3
- data/spec/rankable_graph_spec.rb +24 -0
- data/spec/spec_helper.rb +1 -1
- metadata +2 -3
- data/ext/mkmf.log +0 -5
data/.gitignore
CHANGED
data/README.rdoc
CHANGED
@@ -34,6 +34,36 @@ Which outputs
|
|
34
34
|
Node 8888 rank is 0.0375000014901161
|
35
35
|
|
36
36
|
This ranks represent the probabilities that a certain node will be visited.
|
37
|
+
|
38
|
+
If you want to calculate the rank of another graph is recommended to call the clear method and reuse the RankableGraph instance as this frees the used memory without relying in the Ruby garbage collector.
|
39
|
+
So instead of:
|
40
|
+
|
41
|
+
rankable_graph = RankableGraph.new
|
42
|
+
|
43
|
+
rankable_graph.link(0, 1)
|
44
|
+
rankable_graph.link(1, 2)
|
45
|
+
rankable_graph.rank(0.85, 0.0001){ |identifier, rank| puts "Node #{identifier} rank for graph1 is #{rank}" }
|
46
|
+
|
47
|
+
rankable_graph = RankableGraph.new
|
48
|
+
|
49
|
+
rankable_graph.link(0, 1)
|
50
|
+
rankable_graph.link(2, 1)
|
51
|
+
rankable_graph.rank(0.85, 0.0001){ |identifier, rank| puts "Node #{identifier} rank for graph2 is #{rank}" }
|
52
|
+
|
53
|
+
It's better if you do:
|
54
|
+
|
55
|
+
rankable_graph = RankableGraph.new
|
56
|
+
|
57
|
+
rankable_graph.link(0, 1)
|
58
|
+
rankable_graph.link(1, 2)
|
59
|
+
rankable_graph.rank(0.85, 0.0001){ |identifier, rank| puts "Node #{identifier} rank for graph1 is #{rank}" }
|
60
|
+
|
61
|
+
rankable_graph.clear
|
62
|
+
|
63
|
+
rankable_graph.link(0, 1)
|
64
|
+
rankable_graph.link(2, 1)
|
65
|
+
rankable_graph.rank(0.85, 0.0001){ |identifier, rank| puts "Node #{identifier} rank for graph2 is #{rank}" }
|
66
|
+
|
37
67
|
For more examples please refer to the tests.
|
38
68
|
|
39
69
|
== Requirements
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/benchmark.rb
CHANGED
@@ -1,6 +1,4 @@
|
|
1
|
-
#
|
2
|
-
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), 'ext'))
|
3
|
-
|
1
|
+
#Not a benchmark, just a very unscientific test
|
4
2
|
require 'ext/rankable_graph'
|
5
3
|
|
6
4
|
require "benchmark"
|
@@ -8,23 +6,21 @@ include Benchmark
|
|
8
6
|
|
9
7
|
n = 1000000
|
10
8
|
bmbm(12) do |test|
|
11
|
-
|
9
|
+
r = RankableGraph.new
|
10
|
+
test.report("c:") do
|
12
11
|
srand(5)
|
13
12
|
(0..(n-1)).map do |i|
|
14
13
|
#each node has an average of 30 links
|
15
14
|
rand(60).times do
|
16
15
|
j = rand(n)
|
17
|
-
#first three nodes
|
16
|
+
#first three nodes have more links than the rest
|
18
17
|
r.link(i, (j > 800000 ? rand(3) : j))
|
19
18
|
end
|
20
19
|
end
|
21
|
-
|
22
|
-
test.report("c:") do
|
23
20
|
result = []
|
24
21
|
r.rank(0.85, 0.001){|key, val| result << [key, val]}
|
25
22
|
puts "7 first values are #{result[0..6].map{|(k,v)| "[#{k}]=#{"%.4f" % (v * 100)}, "}}"
|
23
|
+
|
24
|
+
r.clear
|
26
25
|
end
|
27
26
|
end
|
28
|
-
|
29
|
-
|
30
|
-
|
data/ext/rankable_graph.c
CHANGED
@@ -213,6 +213,19 @@ static VALUE rankable_graph_init_copy(VALUE copy, VALUE orig){
|
|
213
213
|
return copy;
|
214
214
|
}
|
215
215
|
|
216
|
+
static VALUE clear(VALUE self){
|
217
|
+
RNStruct* rn;
|
218
|
+
Data_Get_Struct(self, RNStruct, rn);
|
219
|
+
|
220
|
+
rn->current_available_index = -1;
|
221
|
+
g_hash_table_remove_all(rn->index_to_key);
|
222
|
+
g_hash_table_remove_all(rn->key_to_index);
|
223
|
+
g_ptr_array_set_size(rn->number_out_links, 0);
|
224
|
+
g_ptr_array_set_size(rn->in_links, 0);
|
225
|
+
|
226
|
+
return Qnil;
|
227
|
+
}
|
228
|
+
|
216
229
|
static VALUE rb_cRankableGraph;
|
217
230
|
|
218
231
|
void Init_rankable_graph(){
|
@@ -221,6 +234,7 @@ void Init_rankable_graph(){
|
|
221
234
|
rb_define_method(rb_cRankableGraph, "initialize", init, 0);
|
222
235
|
rb_define_method(rb_cRankableGraph, "initialize_copy", rankable_graph_init_copy, 1);
|
223
236
|
rb_define_method(rb_cRankableGraph, "link", link, 2);
|
237
|
+
rb_define_method(rb_cRankableGraph, "clear", clear, 0);
|
224
238
|
rb_define_method(rb_cRankableGraph, "rank", rank, 2);
|
225
239
|
}
|
226
240
|
|
data/rankable_graph.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{rankable_graph}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Daniel Cadenas"]
|
12
|
-
s.date = %q{2010-02-
|
12
|
+
s.date = %q{2010-02-05}
|
13
13
|
s.description = %q{A Ruby Pagerank implementation}
|
14
14
|
s.email = %q{dev@cuboxsa.com}
|
15
15
|
s.extensions = ["ext/extconf.rb"]
|
@@ -27,7 +27,6 @@ Gem::Specification.new do |s|
|
|
27
27
|
"benchmark.rb",
|
28
28
|
"ext/Makefile",
|
29
29
|
"ext/extconf.rb",
|
30
|
-
"ext/mkmf.log",
|
31
30
|
"ext/rankable_graph.c",
|
32
31
|
"rankable_graph.gemspec",
|
33
32
|
"spec/rankable_graph_spec.rb",
|
data/spec/rankable_graph_spec.rb
CHANGED
@@ -12,6 +12,30 @@ def assert_rank(rankable_graph, expected_rank)
|
|
12
12
|
end
|
13
13
|
|
14
14
|
describe RankableGraph do
|
15
|
+
it "should be possible to recalculate the ranks after a new link is added" do
|
16
|
+
rankable_graph = RankableGraph.new
|
17
|
+
rankable_graph.link(0, 1)
|
18
|
+
assert_rank(rankable_graph, { 0 => 35.1, 1 => 64.9 })
|
19
|
+
rankable_graph.link(1, 2)
|
20
|
+
assert_rank(rankable_graph, { 0 => 18.4, 1 => 34.1, 2 => 47.4 })
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should be possible to clear the graph" do
|
24
|
+
rankable_graph = RankableGraph.new
|
25
|
+
rankable_graph.link(0, 1)
|
26
|
+
rankable_graph.link(1, 2)
|
27
|
+
rankable_graph.clear
|
28
|
+
rankable_graph.link(0, 1)
|
29
|
+
assert_rank(rankable_graph, { 0 => 35.1, 1 => 64.9 })
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should not raise an exception when calculating the rank of an empty graph" do
|
33
|
+
rankable_graph = RankableGraph.new
|
34
|
+
lambda do
|
35
|
+
rankable_graph.rank(0.85, 0.0001){|label, rank| raise "This should not be raised!" }
|
36
|
+
end.should_not raise_error
|
37
|
+
end
|
38
|
+
|
15
39
|
it "should return correct results when having a dangling node" do
|
16
40
|
rankable_graph = RankableGraph.new
|
17
41
|
#node 2 is a dangling node because it has no outbound links
|
data/spec/spec_helper.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
2
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
3
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'ext'))
|
4
|
-
require '
|
4
|
+
require 'rankable_graph'
|
5
5
|
require 'spec'
|
6
6
|
require 'spec/autorun'
|
7
7
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rankable_graph
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Cadenas
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-02-
|
12
|
+
date: 2010-02-05 00:00:00 -02:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -41,7 +41,6 @@ files:
|
|
41
41
|
- benchmark.rb
|
42
42
|
- ext/Makefile
|
43
43
|
- ext/extconf.rb
|
44
|
-
- ext/mkmf.log
|
45
44
|
- ext/rankable_graph.c
|
46
45
|
- rankable_graph.gemspec
|
47
46
|
- spec/rankable_graph_spec.rb
|