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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c8138e4f808a95fa20e072ed897f60c1ccf271d4
4
- data.tar.gz: 7e2028969794c5fa2678be5e677d10611b10a407
3
+ metadata.gz: 7c2208cedd6acf5a8b495fe6664997783be18a85
4
+ data.tar.gz: 713602806eb17fb13a0447cefdcb0beb22701e05
5
5
  SHA512:
6
- metadata.gz: ff0f7677effadc9e48d2a241bed2abc72be56a381ac7479e0af7bf3a42bf1475219af92a3f080b5a3210561a285c6bc0faff4e74ed062e041e88054ec8ad31b5
7
- data.tar.gz: e16b25a0847b425df5b7248bd555dcadc1a60277779213670727acbe82949402a8e4762e4d74273aa350d23f963a507284e9ec68c4a26042436cf9185db9089c
6
+ metadata.gz: 085a1812e583e0693841e61ae9b8694647b1f52895344873fda6707b26f9070cf14b59cb462af20af33f01f73a72c04544b9ccb02307d826ef0ff30a366509a9
7
+ data.tar.gz: 8babb0426c64e311765bf43bf1df00a594785db015ad1edfe9b64514084ba2177b5786e84290aa3588e264880a23dcab91cfc9fd150a9620f8a55211bbfb1fb3
data/.DS_Store CHANGED
Binary file
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
+
Binary file
@@ -46,12 +46,12 @@ module RandomGraph
46
46
 
47
47
  # add edge between two nodes
48
48
  def add_edge(from, to)
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
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) if !invalid_nodes
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
- # implements useful graph algorithms
2
- module RandomGraph
3
- module GraphAlgorithms
4
-
5
-
6
- def BFS_distance(root)
7
- distance = Array.new(@size)
8
- distance.fill(Float::INFINITY)
9
-
10
- queue = []
11
-
12
- distance[root] = 0
13
- queue.unshift(root)
14
-
15
- while !queue.empty? do
16
-
17
- current = queue.pop
18
- adj = adjacent_nodes(current)
19
- adj.each do |a|
20
- if distance[a] == Float::INFINITY
21
- distance[a] = distance[current] + 1
22
- queue.unshift(a)
23
- end
24
- end
25
- end
26
- distance
27
- end
28
-
29
- def connected_component(root)
30
- distances = BFS_distance(root)
31
- adjacent = []
32
- (0...distances.size).each do |i|
33
- adjacent << i unless distances[i] == Float::INFINITY
34
- end
35
- adjacent
36
- end
37
-
38
- def number_of_components
39
- visited = Array.new(size)
40
- visited.fill(false)
41
- counter = 0
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
- next if visited[i] == true
45
- counter += 1
46
- comp = connected_component(i)
47
- comp.each do |reachable|
48
- visited[reachable] = true
49
- end
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
- def average_case_diameter
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
- end
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
- r = rand(0...n**2)
30
- # mapping from random number to edges, such that all edges
31
- # can be selected with equal probabilities
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
- added_edges[r] = true
48
- g.add_edge(from, to)
49
- end
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
@@ -1,3 +1,3 @@
1
1
  module RandomGraph
2
- VERSION = '0.1.0'
2
+ VERSION = '0.1.1'
3
3
  end
@@ -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.0
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
- description: "This gem implements the following random \n network generation models:
84
- Erdos-Renyi GNM and GNP, Watts-Strogatz,\n and preferential attachement. It also
85
- implements graph algorithms to\n study the randomly generated graphs."
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
- - graph_0.png
106
- - graph_1.png
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
Binary file
Binary file