random_graph 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|