random_graph 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.DS_Store +0 -0
- data/examples/.DS_Store +0 -0
- data/examples/sample01.rb +39 -0
- data/examples/sample02.rb +41 -0
- data/examples/sample03.png +0 -0
- data/examples/sample03.rb +43 -0
- data/examples/sample04.png +0 -0
- data/examples/sample04.rb +43 -0
- data/lib/.DS_Store +0 -0
- data/lib/random_graph/graph.rb +7 -8
- data/lib/random_graph/graph_algorithms.rb +80 -87
- data/lib/random_graph/random_generators.rb +7 -22
- data/lib/random_graph/version.rb +1 -1
- data/random_graph.gemspec +2 -1
- metadata +27 -6
- data/graph_0.png +0 -0
- data/graph_1.png +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7c2208cedd6acf5a8b495fe6664997783be18a85
|
4
|
+
data.tar.gz: 713602806eb17fb13a0447cefdcb0beb22701e05
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 085a1812e583e0693841e61ae9b8694647b1f52895344873fda6707b26f9070cf14b59cb462af20af33f01f73a72c04544b9ccb02307d826ef0ff30a366509a9
|
7
|
+
data.tar.gz: 8babb0426c64e311765bf43bf1df00a594785db015ad1edfe9b64514084ba2177b5786e84290aa3588e264880a23dcab91cfc9fd150a9620f8a55211bbfb1fb3
|
data/.DS_Store
CHANGED
Binary file
|
data/examples/.DS_Store
ADDED
Binary file
|
@@ -0,0 +1,39 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
require 'random_graph'
|
4
|
+
require 'gruff'
|
5
|
+
|
6
|
+
include RandomGraph
|
7
|
+
|
8
|
+
probability = []
|
9
|
+
data = []
|
10
|
+
|
11
|
+
size = 900
|
12
|
+
trials = 1
|
13
|
+
(0..100).step(1) do |int|
|
14
|
+
puts "progress! #{int}" if int % 5 == 0
|
15
|
+
# puts int
|
16
|
+
p = int.to_f / 100
|
17
|
+
probability << p
|
18
|
+
total_number_comp = 0
|
19
|
+
(0...trials).each do |_x|
|
20
|
+
g = Graph.erdos_renyi_gnp(size, p)
|
21
|
+
total_number_comp += g.number_of_components
|
22
|
+
end
|
23
|
+
avg_num = total_number_comp.to_f / trials
|
24
|
+
data << avg_num
|
25
|
+
end
|
26
|
+
|
27
|
+
g = Gruff::Bar.new
|
28
|
+
g.sort = false
|
29
|
+
g.title = 'probability vs. Number of connected components '
|
30
|
+
g.data('number of componetns', data)
|
31
|
+
g.y_axis_increment = 1 # Points shown on the Y axis
|
32
|
+
g.x_axis_label = "p value"
|
33
|
+
g.y_axis_label = "number of connected components "
|
34
|
+
g.y_axis_increment = 10
|
35
|
+
|
36
|
+
|
37
|
+
|
38
|
+
g.write('sample02.png')
|
39
|
+
|
@@ -0,0 +1,41 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
require 'random_graph'
|
4
|
+
require 'gruff'
|
5
|
+
|
6
|
+
include RandomGraph
|
7
|
+
|
8
|
+
|
9
|
+
size = 900
|
10
|
+
p = 0.1
|
11
|
+
g = Graph.erdos_renyi_gnp(size, p)
|
12
|
+
frequency = Array.new(size)
|
13
|
+
frequency.fill(0)
|
14
|
+
(0...size).each do |i|
|
15
|
+
deg = g.degree(i)
|
16
|
+
frequency[deg] += 1
|
17
|
+
end
|
18
|
+
|
19
|
+
max = 0
|
20
|
+
(0...size).each do |i|
|
21
|
+
max = i if frequency[i] > 0
|
22
|
+
end
|
23
|
+
|
24
|
+
new_freq = Array.new(max+1)
|
25
|
+
(0...max+1).each do |i|
|
26
|
+
new_freq[i] = frequency[i]
|
27
|
+
end
|
28
|
+
|
29
|
+
g = Gruff::Bar.new
|
30
|
+
g.sort = false
|
31
|
+
g.title = 'Degree distribution'
|
32
|
+
g.data('Frequency', new_freq)
|
33
|
+
g.y_axis_increment = 1 # Points shown on the Y axis
|
34
|
+
g.x_axis_label = "Node Degree"
|
35
|
+
g.y_axis_label = "Frequency"
|
36
|
+
g.y_axis_increment = 5
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
g.write('sample02.png')
|
41
|
+
|
Binary file
|
@@ -0,0 +1,43 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
require 'random_graph'
|
4
|
+
require 'gruff'
|
5
|
+
|
6
|
+
include RandomGraph
|
7
|
+
|
8
|
+
the_hash = {}
|
9
|
+
|
10
|
+
(0...300000).each do |i|
|
11
|
+
|
12
|
+
g = Graph.erdos_renyi_gnm(4, 3)
|
13
|
+
x = 0b000000
|
14
|
+
x ^= 0b100000 if g.edge?(0,1)
|
15
|
+
x ^= 0b010000 if g.edge?(0,2)
|
16
|
+
x ^= 0b001000 if g.edge?(0,3)
|
17
|
+
x ^= 0b000100 if g.edge?(1,2)
|
18
|
+
x ^= 0b000010 if g.edge?(1,3)
|
19
|
+
x ^= 0b000001 if g.edge?(2,3)
|
20
|
+
|
21
|
+
if the_hash.has_key?(x)
|
22
|
+
the_hash[x] = 1 + the_hash[x]
|
23
|
+
else
|
24
|
+
the_hash[x] = 1
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
data = []
|
29
|
+
the_hash.each_value {|v| data << v }
|
30
|
+
|
31
|
+
|
32
|
+
g = Gruff::Bar.new
|
33
|
+
g.sort = false
|
34
|
+
g.title = '4 node, 3 edge distribution'
|
35
|
+
g.data('Frequency', data)
|
36
|
+
g.y_axis_increment = 10000 # Points shown on the Y axis
|
37
|
+
g.x_axis_label = "graph layout"
|
38
|
+
g.y_axis_label = "Frequency"
|
39
|
+
|
40
|
+
|
41
|
+
|
42
|
+
g.write('sample03.png')
|
43
|
+
|
Binary file
|
@@ -0,0 +1,43 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
require 'random_graph'
|
4
|
+
require 'gruff'
|
5
|
+
|
6
|
+
include RandomGraph
|
7
|
+
|
8
|
+
the_hash = {}
|
9
|
+
|
10
|
+
(0...30000).each do |i|
|
11
|
+
|
12
|
+
g = Graph.erdos_renyi_gnm(4, 5)
|
13
|
+
x = 0b000000
|
14
|
+
x ^= 0b100000 if g.edge?(0,1)
|
15
|
+
x ^= 0b010000 if g.edge?(0,2)
|
16
|
+
x ^= 0b001000 if g.edge?(0,3)
|
17
|
+
x ^= 0b000100 if g.edge?(1,2)
|
18
|
+
x ^= 0b000010 if g.edge?(1,3)
|
19
|
+
x ^= 0b000001 if g.edge?(2,3)
|
20
|
+
|
21
|
+
if the_hash.has_key?(x)
|
22
|
+
the_hash[x] = 1 + the_hash[x]
|
23
|
+
else
|
24
|
+
the_hash[x] = 1
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
data = []
|
29
|
+
the_hash.each_value {|v| data << v }
|
30
|
+
|
31
|
+
|
32
|
+
g = Gruff::Bar.new
|
33
|
+
g.sort = false
|
34
|
+
g.title = '4 node, 5 edge distribution'
|
35
|
+
g.data('Frequency', data)
|
36
|
+
g.y_axis_increment = 10000 # Points shown on the Y axis
|
37
|
+
g.x_axis_label = "graph layout"
|
38
|
+
g.y_axis_label = "Frequency"
|
39
|
+
|
40
|
+
|
41
|
+
|
42
|
+
g.write('sample04.png')
|
43
|
+
|
data/lib/.DS_Store
CHANGED
Binary file
|
data/lib/random_graph/graph.rb
CHANGED
@@ -46,12 +46,12 @@ module RandomGraph
|
|
46
46
|
|
47
47
|
# add edge between two nodes
|
48
48
|
def add_edge(from, to)
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
49
|
+
fail ArgumentError.new('invalid node') if from >= @size || from < 0
|
50
|
+
fail ArgumentError.new('invalid node') if to >= @size || to < 0
|
51
|
+
unless to == from
|
52
|
+
@nodes[from] << to unless @nodes[from].include?(to)
|
53
|
+
@nodes[to] << from unless @nodes[to].include?(from)
|
54
|
+
end
|
55
55
|
end
|
56
56
|
|
57
57
|
def remove_edge(from, to)
|
@@ -79,7 +79,7 @@ module RandomGraph
|
|
79
79
|
def edge?(from, to)
|
80
80
|
# check if nodes are valid?
|
81
81
|
invalid_nodes = from >= @size || from < 0 || to >= @size || to < 0
|
82
|
-
@nodes[from].include?(to)
|
82
|
+
@nodes[from].include?(to) unless invalid_nodes
|
83
83
|
end
|
84
84
|
|
85
85
|
def edge_number
|
@@ -93,6 +93,5 @@ module RandomGraph
|
|
93
93
|
def average_degree
|
94
94
|
2.0 * edge_number / size
|
95
95
|
end
|
96
|
-
|
97
96
|
end
|
98
97
|
end
|
@@ -1,103 +1,96 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
adjacent
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
1
|
+
# implements useful graph algorithms
|
2
|
+
module RandomGraph
|
3
|
+
module GraphAlgorithms
|
4
|
+
def BFS_distance(root)
|
5
|
+
distance = Array.new(@size)
|
6
|
+
distance.fill(Float::INFINITY)
|
7
|
+
|
8
|
+
queue = []
|
9
|
+
|
10
|
+
distance[root] = 0
|
11
|
+
queue.unshift(root)
|
12
|
+
|
13
|
+
until queue.empty?
|
14
|
+
|
15
|
+
current = queue.pop
|
16
|
+
adj = adjacent_nodes(current)
|
17
|
+
adj.each do |a|
|
18
|
+
if distance[a] == Float::INFINITY
|
19
|
+
distance[a] = distance[current] + 1
|
20
|
+
queue.unshift(a)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
distance
|
25
|
+
end
|
26
|
+
|
27
|
+
def connected_component(root)
|
28
|
+
distances = BFS_distance(root)
|
29
|
+
adjacent = []
|
30
|
+
(0...distances.size).each do |i|
|
31
|
+
adjacent << i unless distances[i] == Float::INFINITY
|
32
|
+
end
|
33
|
+
adjacent
|
34
|
+
end
|
35
|
+
|
36
|
+
def number_of_components
|
37
|
+
visited = Array.new(size)
|
38
|
+
visited.fill(false)
|
39
|
+
counter = 0
|
40
|
+
(0...size).each do |i|
|
41
|
+
next if visited[i] == true
|
42
|
+
counter += 1
|
43
|
+
comp = connected_component(i)
|
44
|
+
comp.each do |reachable|
|
45
|
+
visited[reachable] = true
|
46
|
+
end
|
47
|
+
end
|
48
|
+
counter
|
49
|
+
end
|
50
|
+
|
51
|
+
def worst_case_diameter
|
52
|
+
real_bad = number_of_components > 1 ? Float::INFINITY : 0
|
53
|
+
worst = 0
|
54
|
+
if real_bad == 0
|
43
55
|
(0...size).each do |i|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
end
|
51
|
-
counter
|
52
|
-
end
|
53
|
-
|
54
|
-
def worst_case_diameter
|
55
|
-
real_bad = number_of_components > 1 ? Float::INFINITY : 0
|
56
|
-
worst = 0
|
57
|
-
if real_bad == 0
|
58
|
-
(0...size).each do |i|
|
59
|
-
distances = BFS_distance(i)
|
60
|
-
worst = [distances.max, worst].max
|
61
|
-
end
|
62
|
-
end
|
63
|
-
[worst, real_bad].max
|
64
|
-
end
|
56
|
+
distances = BFS_distance(i)
|
57
|
+
worst = [distances.max, worst].max
|
58
|
+
end
|
59
|
+
end
|
60
|
+
[worst, real_bad].max
|
61
|
+
end
|
65
62
|
|
66
|
-
|
63
|
+
def average_case_diameter
|
67
64
|
real_bad = number_of_components > 1 ? Float::INFINITY : 0
|
68
65
|
total = 0
|
69
66
|
if real_bad == 0
|
70
67
|
(0...size).each do |i|
|
71
68
|
distances = BFS_distance(i)
|
72
|
-
average = distances.inject(:+).to_f / (size - 1)
|
73
|
-
total += average
|
74
|
-
end
|
75
|
-
end
|
76
|
-
total / size
|
77
|
-
|
78
|
-
|
79
|
-
def clustering_coefficient
|
69
|
+
average = distances.inject(:+).to_f / (size - 1)
|
70
|
+
total += average
|
71
|
+
end
|
72
|
+
end
|
73
|
+
total / size
|
74
|
+
end
|
75
|
+
|
76
|
+
def clustering_coefficient
|
80
77
|
total_cluster = 0
|
81
78
|
(0...size).each do |i|
|
82
79
|
neighbors = adjacent_nodes(i)
|
83
|
-
k = neighbors.size
|
84
|
-
possible_connections = k.to_f * (k - 1) / 2
|
80
|
+
k = neighbors.size
|
81
|
+
possible_connections = k.to_f * (k - 1) / 2
|
85
82
|
actual_connections = 0
|
86
83
|
(0...k).each do |l|
|
87
|
-
(i+1...k).each do |j|
|
84
|
+
(i + 1...k).each do |j|
|
88
85
|
actual_connections += 1 if edge?(neighbors[l], neighbors[j])
|
89
|
-
end
|
90
|
-
end
|
86
|
+
end
|
87
|
+
end
|
91
88
|
if possible_connections == 0 then clustering = 0
|
92
89
|
else clustering = actual_connections.to_f / possible_connections
|
93
|
-
end
|
94
|
-
total_cluster += clustering
|
95
|
-
end
|
96
|
-
total_cluster / size
|
97
|
-
end
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
end
|
90
|
+
end
|
91
|
+
total_cluster += clustering
|
92
|
+
end
|
93
|
+
total_cluster / size
|
94
|
+
end
|
95
|
+
end
|
103
96
|
end
|
@@ -26,28 +26,13 @@ module RandomGraph
|
|
26
26
|
to = 0
|
27
27
|
begin
|
28
28
|
# select a random number, representing on of the possible edges
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
from = r / n
|
33
|
-
to = r % n
|
34
|
-
|
35
|
-
# Keeps adjacency matrix upper triangular by mapping equivalent
|
36
|
-
# r values
|
37
|
-
if from < to
|
38
|
-
temp = from
|
39
|
-
from = to
|
40
|
-
to = temp
|
41
|
-
r = (from * n) + to
|
42
|
-
end
|
43
|
-
# make sure edge has not been slescted, and that it is not a
|
44
|
-
# self loop
|
45
|
-
valid_edge = !added_edges.key?(r) && (from != to)
|
29
|
+
from = rand(0...n)
|
30
|
+
to = rand(0...n)
|
31
|
+
valid_edge = !g.edge?(from, to) && (from != to)
|
46
32
|
end until valid_edge == true
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
g
|
33
|
+
g.add_edge(from, to)
|
34
|
+
end
|
35
|
+
g
|
51
36
|
end
|
52
37
|
|
53
38
|
# Create a graph with n nodes, where all edges have a probability p
|
@@ -139,7 +124,7 @@ module RandomGraph
|
|
139
124
|
g.add_edge(i, right)
|
140
125
|
end
|
141
126
|
(0...n**2).each do |i|
|
142
|
-
next if rand > p
|
127
|
+
next if rand > p
|
143
128
|
top = i - n
|
144
129
|
top += n**2 if top < 0
|
145
130
|
bottom = (i + n) % n**2
|
data/lib/random_graph/version.rb
CHANGED
data/random_graph.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.email = ['fsel@sas.upenn.edu']
|
11
11
|
|
12
12
|
spec.summary = 'Gem for generating random graphs'
|
13
|
-
spec.description = 'This gem implements the following random
|
13
|
+
spec.description = 'This gem implements the following random
|
14
14
|
network generation models: Erdos-Renyi GNM and GNP, Watts-Strogatz,
|
15
15
|
and preferential attachement. It also implements graph algorithms to
|
16
16
|
study the randomly generated graphs.'
|
@@ -27,4 +27,5 @@ Gem::Specification.new do |spec|
|
|
27
27
|
spec.add_development_dependency 'rspec', '~> 3.4'
|
28
28
|
spec.add_development_dependency 'simplecov', '~> 0.10'
|
29
29
|
spec.add_runtime_dependency 'ruby-graphviz', '~> 1.2'
|
30
|
+
spec.add_runtime_dependency 'gruff', '~> 0.6'
|
30
31
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: random_graph
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- fselame
|
@@ -80,9 +80,25 @@ dependencies:
|
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '1.2'
|
83
|
-
|
84
|
-
|
85
|
-
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: gruff
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.6'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0.6'
|
97
|
+
description: |-
|
98
|
+
This gem implements the following random
|
99
|
+
network generation models: Erdos-Renyi GNM and GNP, Watts-Strogatz,
|
100
|
+
and preferential attachement. It also implements graph algorithms to
|
101
|
+
study the randomly generated graphs.
|
86
102
|
email:
|
87
103
|
- fsel@sas.upenn.edu
|
88
104
|
executables: []
|
@@ -102,8 +118,13 @@ files:
|
|
102
118
|
- bin/.DS_Store
|
103
119
|
- bin/console
|
104
120
|
- bin/setup
|
105
|
-
-
|
106
|
-
-
|
121
|
+
- examples/.DS_Store
|
122
|
+
- examples/sample01.rb
|
123
|
+
- examples/sample02.rb
|
124
|
+
- examples/sample03.png
|
125
|
+
- examples/sample03.rb
|
126
|
+
- examples/sample04.png
|
127
|
+
- examples/sample04.rb
|
107
128
|
- lib/.DS_Store
|
108
129
|
- lib/random_graph.rb
|
109
130
|
- lib/random_graph/.DS_Store
|
data/graph_0.png
DELETED
Binary file
|
data/graph_1.png
DELETED
Binary file
|