mpath_graph 0.0.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 ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ YTdmNTQ4NDUyNzgzNGE4YWE1NWZmN2E2ZDhkZDFmNTljODNhZTVlNQ==
5
+ data.tar.gz: !binary |-
6
+ YzU1MjkzOWRhZWYyNDkyMmI0MjA0MDMzNzMxZjVlOTRkNDMzZmQ0MQ==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ ZDc4MTA4YzYzMDgxNzY5MzVlYzAwYzhkNmY2ZmZmY2FjMjY2MDkxOTIwOTAy
10
+ YWNiZjM2YmJjYTNkZjIzMTc3YzA2ZDNhNGEyZjk0YTdkOGU5Y2M0OTY4MzUw
11
+ YjlkNjhjMDM3OGE3ZGI3YjNhMDk2Y2ZiMzc0YmI4YzJlODJkZDk=
12
+ data.tar.gz: !binary |-
13
+ ZTU5ODFkMzI5NzQ4MDYzNjhhZGQwNTYzYjYzZmRkODYyZjc3ZTQxMzQ5Njdk
14
+ ZjMxMDE1MGI1NDQ5ODgwZjE0N2Y5NzdhODVjNzMwNjFhYWQ2MDVlMzI5OGRk
15
+ MDNhYmZlNThkMzY0ZjNiNjgzN2E5ZDVjMzQzMzgwYzA0ZTc3YmE=
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mpath_graph.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Israel Buitron
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # MpathGraph
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'mpath_graph'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install mpath_graph
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,3 @@
1
+ module MPathGraph
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,194 @@
1
+ require "mpath_graph/version"
2
+ require 'ruby-progressbar'
3
+ require 'csv'
4
+ require 'json'
5
+
6
+ module MPathGraph
7
+ # Given a set of edges, checks if there is an edged that relates
8
+ # two vertices of a graph.
9
+ #
10
+ # @param i [Integer] Vertex i in a graph.
11
+ # @param j [Integer] Vertex j in a graph.
12
+ # @param edges [Array<Array<Integer>>] Set of edges of a graph.
13
+ #
14
+ # @return [Boolean]
15
+ def self.is_edge?(i, j, edges)
16
+ edges.include?([i,j]) || edges.include?([j,i])
17
+ end
18
+
19
+ # Given a cycle checks if it has induced cycles.
20
+ #
21
+ # @param worm [Array<Integer>] Sequence of vertices.
22
+ # @param edges [Array<Array<Integer>>] Set of edges.
23
+ #
24
+ # @return [Boolean]
25
+ def self.has_cycles?(worm, edges, options = {})
26
+ if is_edge? worm[0], worm[-1], edges
27
+ # Check edges
28
+ (0..worm.length-2).each do |i|
29
+ (i+2..worm.length-1).each do |j|
30
+ unless i==0 && j==worm.length-1 # Avoid check endpoints
31
+ if is_edge? worm[i], worm[j], edges
32
+ if options[:verbose] # Verbose cycle
33
+ puts "Cycle\t#{worm[i]},#{worm[j]}"
34
+ end
35
+
36
+ return true
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ false
43
+ end
44
+
45
+ def self.find_cycles(worm, edges)
46
+ if is_edge? worm[0], worm[-1], edges
47
+ # Check edges
48
+ (0..worm.length-2).each do |i|
49
+ (i+2..worm.length-1).each do |j|
50
+ unless i==0 && j==worm.length-1 # Avoid check endpoints
51
+ return [worm[i],worm[j]] if is_edge? worm[i], worm[j], edges
52
+ end
53
+ end
54
+ end
55
+ end
56
+ nil
57
+ end
58
+
59
+ def self.random_walk(edges, options = {})
60
+ worm = []
61
+ neighbors = nil
62
+ steps_walked = 0
63
+ initial = options[:initial_vertex] || 0
64
+ worm_size = options[:worm_size] || 5
65
+ walk_limit = options[:walk_limit] || -1
66
+ pause = options[:pause] || false
67
+ induced_cycles_limit = options[:induced_cycles_limit] || -1
68
+
69
+ # Initialize worm with initial vertex
70
+ worm << initial
71
+
72
+ # Initialize pseudo-random number generator
73
+ prng = Random.new
74
+
75
+ # Flush csv row headers to STDIN
76
+ puts ["k-path","Induced cycle","Steps walked"].to_csv
77
+
78
+ # Fill worm
79
+ while worm.size < worm_size
80
+ # Find neighbors of last vertex
81
+ neighbors = find_neighbors(worm.last, edges) unless neighbors
82
+
83
+ rnd_idx = prng.rand(neighbors.size) # Compute random index
84
+
85
+ # Avoid cycles in worm
86
+ if worm.include?(neighbors[rnd_idx])
87
+ # Delete non-valid neighbors for current last vertex
88
+ neighbors.delete(neighbors[rnd_idx])
89
+
90
+ # Useless last vertex in worm, drop it!
91
+ if neighbors.empty?
92
+ worm.pop # Drop last vertex
93
+ neighbors = nil # Clean neighbors
94
+ end
95
+ else
96
+ worm << neighbors[rnd_idx] # Append vertex
97
+ neighbors = nil # Clean neighbors
98
+
99
+ if worm.size == worm_size # When worm is full
100
+ steps_walked += 1 # Increment worm steps walked
101
+
102
+ # Output well-formed worm
103
+ # puts "Checking\t#{worm.inspect}"
104
+ csv_row = [worm]
105
+
106
+ # if has_cycles?(worm, edges, verbose: options[:verbose])
107
+ if (cycle = find_cycles(worm, edges))
108
+ csv_row << cycle
109
+ csv_row << steps_walked
110
+
111
+ # if options[:verbose] # Verbose worm with cycle
112
+ # puts "Worm\t#{worm.inspect}"
113
+ # puts "Steps walked\t#{steps_walked}"
114
+ # end
115
+
116
+ # Pause when verbose
117
+ # if pause
118
+ # STDERR.puts "Press a key to continue..."
119
+ # STDIN.getc
120
+ # end
121
+
122
+ # Check induced cycles counter limit
123
+ return if induced_cycles_limit==0
124
+ induced_cycles_limit-=1
125
+ else
126
+ csv_row << nil
127
+ csv_row << steps_walked
128
+ end
129
+
130
+ # Flush csv row data to STDIN
131
+ puts csv_row.to_csv
132
+
133
+ worm.shift # Drop first vertex in worm (as queue)
134
+ break if steps_walked > walk_limit && walk_limit > 0 # Stop walking
135
+ end
136
+ end
137
+ end
138
+ end
139
+
140
+ def self.find_neighbors(vertex, edges)
141
+ neighbors = []
142
+
143
+ edges.each do |e|
144
+ if vertex == e[0]
145
+ neighbors << e[1]
146
+ elsif vertex == e[1]
147
+ neighbors << e[0]
148
+ end
149
+ end
150
+
151
+ neighbors
152
+ end
153
+
154
+ # Given a set of paths it computes a graphs of paths.
155
+ # For each path in set, it compares with all other paths in set
156
+ # and if both share inner then there is an edge that
157
+ # links these vertices.
158
+ #
159
+ # This method is recommended for big _paths_ arrays because it
160
+ # flush to outputstream instead of keep them in memory which is
161
+ # very space-expensive.
162
+ #
163
+ # @param paths [Array<Array<Integer>>] Set of paths.
164
+ # @param output_stream Outputstream.
165
+ # @param options [Hash] Options map.
166
+ def self.compute_paths_graph(paths, output_stream, options = {})
167
+ len = paths.size - 1
168
+
169
+ (0..len).each do |i|
170
+ (i+1..len).each do |j|
171
+ unless (paths[i][1...-1] & paths[j]).empty?
172
+ output_stream << [i,j]
173
+ next
174
+ end
175
+ end
176
+ options[:progress_bar].increment unless options[:progress_bar].nil?
177
+ end
178
+ end
179
+
180
+ def self.from_csv(file)
181
+ pbar = ProgressBar.create(
182
+ title: "Reading paths graph",
183
+ starting_at: 1,
184
+ total: nil)
185
+
186
+ paths = []
187
+ CSV.foreach(file) do |row|
188
+ paths << JSON.parse(row[0])
189
+ pbar.increment
190
+ end
191
+
192
+ paths
193
+ end
194
+ end
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'mpath_graph/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "mpath_graph"
8
+ spec.version = MPathGraph::VERSION
9
+ spec.authors = ["Israel Buitron"]
10
+ spec.email = ["ibuitron@computacion.cs.cinvestav.mx"]
11
+ spec.description = %q{m-Path graphs library}
12
+ spec.summary = %q{m-Path graphs library}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec"
24
+ end
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mpath_graph
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Israel Buitron
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-07-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: m-Path graphs library
56
+ email:
57
+ - ibuitron@computacion.cs.cinvestav.mx
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - .gitignore
63
+ - Gemfile
64
+ - LICENSE.txt
65
+ - README.md
66
+ - Rakefile
67
+ - lib/mpath_graph.rb
68
+ - lib/mpath_graph/version.rb
69
+ - mpath_graph.gemspec
70
+ homepage: ''
71
+ licenses:
72
+ - MIT
73
+ metadata: {}
74
+ post_install_message:
75
+ rdoc_options: []
76
+ require_paths:
77
+ - lib
78
+ required_ruby_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ requirements: []
89
+ rubyforge_project:
90
+ rubygems_version: 2.3.0
91
+ signing_key:
92
+ specification_version: 4
93
+ summary: m-Path graphs library
94
+ test_files: []