mvgraph 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.
data/Gemfile ADDED
File without changes
@@ -0,0 +1,10 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ ruby-graphviz (0.9.21)
5
+
6
+ PLATFORMS
7
+ ruby
8
+
9
+ DEPENDENCIES
10
+ ruby-graphviz
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2011 Daniel Vingo, Jonathan McKenzie
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,2 @@
1
+ mvGraph is an implementation of the graph data structure in Ruby. It was created to solve
2
+ some classic AI search problems; as such, it currently supports BFS, DFS, any user-defined heuristic search, as well as A*.
@@ -0,0 +1,26 @@
1
+ require 'rake/gempackagetask'
2
+
3
+ spec = Gem::Specification.new do |s|
4
+ s.name = "mvgraph"
5
+ s.summary = "A generic graph implementation, useful for solving problems where some sort of search is needed."
6
+ s.description = File.read(File.join(File.dirname(__FILE__), 'README'))
7
+ s.requirements = [ 'None' ]
8
+ s.version = "0.0.1"
9
+ s.author = "Jon Mckenzie, Dan Vingo"
10
+ s.email = "danvingo@gmail.com"
11
+ s.homepage = ""
12
+ s.platform = Gem::Platform::RUBY
13
+ s.required_ruby_version = '>=1.9.2p180'
14
+ s.files = Dir['**/**']
15
+ s.executables = []
16
+ s.test_files = Dir["test/test*.rb"]
17
+ s.has_rdoc = false
18
+ end
19
+ Rake::GemPackageTask.new(spec).define
20
+
21
+ task :default => [:test]
22
+
23
+ task :test do
24
+ ruby "test/test_mvQueue.rb"
25
+ ruby "test/test_mvGraph.rb"
26
+ end
@@ -0,0 +1,42 @@
1
+ The graph is currently implemented in an undirected manner, such that
2
+ adding an edge will add edges in both directions, this can easily be changed
3
+ for example to implement a directed graph, or if you desire the behavior to
4
+ explicitly set edges in both directions for two vertices.
5
+ ==============
6
+ New Features
7
+ ==============
8
+ -Graph Visualization
9
+ -Output
10
+ -ASCII
11
+ -JSON
12
+ -OpenGL/WebGL
13
+ -Static image (png, jpeg, etc.)
14
+ -Graph Methods
15
+ -Search
16
+ *-Breadth-first
17
+ *-Shortest-path
18
+ *-Depth-first
19
+ -Iterative Depth-first
20
+ *-Best-first
21
+ -Greedy
22
+ -A*
23
+ -Database
24
+ -Back-end representation
25
+ -Give the option to use adjacency list or adjacency matrix to use more memory but make the search faster
26
+ -Sub/Supertypes
27
+ -Simple
28
+ -Directed
29
+ -Weighted-edges
30
+ -Hypergraph
31
+ -Toy implementations
32
+ -Slide puzzle
33
+ -Chess/checkers
34
+ -Perfomance enhancements
35
+ -Hash function to compare states instead of nxn linear search of the grid size when testing equality.
36
+
37
+ ======
38
+ TODO
39
+ ======
40
+ - Add a README
41
+ - Setup Rake tasks for testing with nPuzzle and mvGraph together.
42
+
@@ -0,0 +1,202 @@
1
+ require_relative 'mvQueue.rb'
2
+ class Graph
3
+ include Enumerable
4
+ def each
5
+ @adj_matrix.keys.each do |vertex|
6
+ yield vertex
7
+ end
8
+ end
9
+
10
+ def neighbors_of(vertex)
11
+ @adj_matrix[vertex].select { |v| has_edge?(vertex, v) }.keys
12
+ end
13
+
14
+ def initialize
15
+ @adj_matrix = Hash.new
16
+ end
17
+
18
+ def add_vertex(v)
19
+ @adj_matrix[v] = Hash.new
20
+ end
21
+
22
+ def vertex(v)
23
+ @adj_matrix.find { |vertex| vertex[0] == v }[0]
24
+ end
25
+
26
+ def add_edge(v1, v2)
27
+ if @adj_matrix[v1].nil?
28
+ @adj_matrix[v1] = Hash.new
29
+ end
30
+ if @adj_matrix[v2].nil?
31
+ @adj_matrix[v2] = Hash.new
32
+ end
33
+ @adj_matrix[v2][v1] = 1
34
+ @adj_matrix[v1][v2] = 1
35
+ end
36
+
37
+ def update_vertex(v)
38
+ @adj_matrix[v] = @adj_matrix[vertex(v)]
39
+ end
40
+
41
+ def has_edge?(v1, v2)
42
+ unless @adj_matrix[v1].nil? or @adj_matrix[v1][v2].nil?
43
+ @adj_matrix[v1][v2] == 1
44
+ end
45
+ end
46
+
47
+ #
48
+ # queue_type is one of fifo or lifo
49
+ #
50
+ # Look into passing a hash of arguments
51
+ def search(start_vertex, queue_type, neighbor_function=nil, goal_state=nil, search_depth=nil)
52
+ set_vertex_color(start_vertex, "gray")
53
+ set_vertex_distance(start_vertex, 0)
54
+ queue = Queue.new(queue_type)
55
+ queue.enqueue(get_graph_vertex(start_vertex))
56
+ goal_not_reached = true
57
+ count = 0
58
+ return_goal_state = nil
59
+ while queue.length != 0 and goal_not_reached
60
+ current_vertex = queue.dequeue
61
+ count += 1
62
+ # Full BFS or DFS with no goal state
63
+ if neighbor_function.nil? and search_depth.nil? and goal_state.nil?
64
+ neighbors_of(current_vertex).each do |neighbor|
65
+ if neighbor.color == "white"
66
+ set_vertex_color(get_graph_vertex(neighbor), "gray")
67
+ set_vertex_distance(get_graph_vertex(neighbor), get_vertex_distance(get_graph_vertex(current_vertex)) + 1)
68
+ set_vertex_predecessor(get_graph_vertex(neighbor), get_graph_vertex(current_vertex))
69
+ queue.enqueue(get_graph_vertex(neighbor))
70
+ end
71
+ end
72
+ set_vertex_color(get_graph_vertex(current_vertex), "black")
73
+ # Search for goal_state with no distance limit
74
+ elsif !neighbor_function.nil? and !goal_state.nil? and search_depth.nil?
75
+ neighbors = get_graph_vertex(current_vertex).send(neighbor_function, goal_state)
76
+ neighbors.each do |neighbor|
77
+ unless self.include? neighbor
78
+ self.add_vertex(neighbor)
79
+ self.add_edge(current_vertex, neighbor)
80
+ if neighbor == goal_state
81
+ set_vertex_color(get_graph_vertex(neighbor), "gray")
82
+ set_vertex_distance(get_graph_vertex(neighbor), get_vertex_distance(get_graph_vertex(current_vertex)) + 1)
83
+ set_vertex_predecessor(get_graph_vertex(neighbor), get_graph_vertex(current_vertex))
84
+ puts " a;dslfkj #{return_goal_state} "
85
+ return_goal_state = neighbor
86
+ goal_not_reached = false
87
+ break
88
+ end
89
+ if get_vertex_color(get_graph_vertex(neighbor)) == "white"
90
+ set_vertex_color(get_graph_vertex(neighbor), "gray")
91
+ set_vertex_distance(get_graph_vertex(neighbor), get_vertex_distance(get_graph_vertex(current_vertex)) + 1)
92
+ set_vertex_predecessor(get_graph_vertex(neighbor), get_graph_vertex(current_vertex))
93
+ queue.enqueue(get_graph_vertex(neighbor))
94
+ end
95
+ set_vertex_color(get_graph_vertex(current_vertex), "black")
96
+ end
97
+ end
98
+ # Random walk to a given distance and no goal state
99
+ elsif !neighbor_function.nil? and goal_state.nil? and !search_depth.nil?
100
+ neighbors = get_graph_vertex(current_vertex).send(neighbor_function)
101
+ neighbors.each do |neighbor|
102
+ unless self.include? neighbor
103
+ self.add_vertex(neighbor)
104
+ self.add_edge(current_vertex, neighbor)
105
+ if count == search_depth
106
+ return_goal_state = neighbor
107
+ goal_not_reached = false
108
+ break
109
+ end
110
+ if get_vertex_color(get_graph_vertex(neighbor)) == "white"
111
+ set_vertex_color(get_graph_vertex(neighbor), "gray")
112
+ set_vertex_distance(get_graph_vertex(neighbor), get_vertex_distance(get_graph_vertex(current_vertex)) + 1)
113
+ set_vertex_predecessor(get_graph_vertex(neighbor), get_graph_vertex(current_vertex))
114
+ queue.enqueue(get_graph_vertex(neighbor))
115
+ end
116
+ set_vertex_color(get_graph_vertex(current_vertex), "black")
117
+ end
118
+ end
119
+ else
120
+ # Other possible prototypes
121
+ end
122
+ end
123
+ puts "return_goal_state: #{return_goal_state}"
124
+ return return_goal_state, count
125
+ end
126
+
127
+ # Performs depth-first search to the given depth, starting at the vertex start_state.
128
+ def walk_n_steps(start_state, neighbor_function, depth)
129
+ search(start_state, "lifo", neighbor_function, nil, depth)
130
+ end
131
+
132
+ #
133
+ # Precondition: BFS has been run on the graph
134
+ #
135
+ def shortest_path(start_vertex, end_vertex)
136
+ @ret_array ||= []
137
+ predecessor = get_vertex_predecessor(get_graph_vertex(end_vertex))
138
+ if start_vertex == end_vertex
139
+ @ret_array << get_graph_vertex(start_vertex)
140
+ elsif predecessor.nil?
141
+ "No path."
142
+ else
143
+ shortest_path(get_graph_vertex(start_vertex), predecessor)
144
+ @ret_array << get_graph_vertex(end_vertex)
145
+ end
146
+ end
147
+
148
+ def set_vertex_color(v, color)
149
+ get_graph_vertex(v).color = color
150
+ end
151
+
152
+ def get_vertex_color(v)
153
+ get_graph_vertex(v).color
154
+ end
155
+
156
+ def set_vertex_distance(v, distance)
157
+ get_graph_vertex(v).distance = distance
158
+ end
159
+
160
+ def get_vertex_distance(v)
161
+ get_graph_vertex(v).distance
162
+ end
163
+
164
+ def set_vertex_predecessor(v, predecessor)
165
+ get_graph_vertex(v).predecessor = get_graph_vertex(predecessor) unless predecessor.nil?
166
+ end
167
+
168
+ def get_vertex_predecessor(v)
169
+ get_graph_vertex(v).predecessor
170
+ end
171
+
172
+ private
173
+ def get_graph_vertex(v)
174
+ @adj_matrix.find { |vertex| vertex[0] == v }[0]
175
+ end
176
+ end
177
+
178
+ class Vertex
179
+ attr_accessor :id, :color, :distance, :predecessor
180
+ def initialize(id)
181
+ @id = id
182
+ @color = "white"
183
+ @distance = 2**32
184
+ @predecessor = nil
185
+ end
186
+
187
+ def ==(other_vertex)
188
+ @id == other_vertex.id
189
+ end
190
+
191
+ def eql?(other_vertex)
192
+ @id == other_vertex.id
193
+ end
194
+
195
+ def hash
196
+ @id.hash
197
+ end
198
+
199
+ def to_s
200
+ "id: #{@id}, color: #{@color}, distance: #{@distance}, predecessor: \n\t\t #{@predecessor}"
201
+ end
202
+ end
@@ -0,0 +1,29 @@
1
+ class Queue < Array
2
+ def initialize(type)
3
+ super()
4
+ @type = type
5
+ @func_map = {"fi" => Proc.new{ |item| self.insert(0, item) }, "li" => Proc.new{ |item| self << item }, "fo" => Proc.new{ self.pop }, "lo" => Proc.new{ delete_at(0) },
6
+ "be" => Proc.new do |item|
7
+ self.insert(0, item)
8
+ self.sort_by! { |state| state.score }
9
+ end
10
+ }
11
+ end
12
+
13
+ def enqueue(item)
14
+ @func_map[@type[0..1]].call(item)
15
+ end
16
+
17
+ def dequeue
18
+ @func_map[@type[2..3]].call()
19
+ end
20
+
21
+ def to_s
22
+ the_string = ""
23
+ self.each do |item|
24
+ the_string += item.to_s
25
+ the_string += ","
26
+ end
27
+ the_string[0..the_string.size()-2]
28
+ end
29
+ end
@@ -0,0 +1,183 @@
1
+ require 'minitest/autorun'
2
+ require_relative '../lib/mvGraph.rb'
3
+
4
+ class TestGraph < MiniTest::Unit::TestCase
5
+ def setup
6
+ @graph = Graph.new
7
+ @vertex = Vertex.new(1)
8
+ end
9
+
10
+ def test_create_graph
11
+ assert @graph
12
+ end
13
+
14
+ def test_create_vertex
15
+ assert @vertex
16
+ end
17
+
18
+ def test_vertex_id
19
+ @vertex.id = 1
20
+ assert @vertex.id == 1
21
+ end
22
+
23
+ def test_add_vertex
24
+ @graph.add_vertex(Vertex.new(1))
25
+ assert @graph.vertex(Vertex.new(1))
26
+ end
27
+
28
+ def test_add_edge
29
+ vertex1 = Vertex.new(1)
30
+ @graph.add_vertex(vertex1)
31
+ @graph.add_vertex(Vertex.new(2))
32
+ @graph.add_edge(vertex1, Vertex.new(2))
33
+ assert @graph.has_edge?(Vertex.new(1), Vertex.new(2))
34
+ assert @graph.has_edge?(Vertex.new(2), Vertex.new(1))
35
+ end
36
+
37
+ def test_no_edge
38
+ refute @graph.has_edge?(Vertex.new(3),Vertex.new(4))
39
+ end
40
+
41
+ def test_add_multiple_vertices_and_edges
42
+ @graph.add_vertex(Vertex.new(1))
43
+ @graph.add_vertex(Vertex.new(2))
44
+ @graph.add_edge(Vertex.new(2),Vertex.new(1))
45
+ @graph.add_vertex(Vertex.new(3))
46
+ @graph.add_vertex(Vertex.new(4))
47
+ @graph.add_edge(Vertex.new(3),Vertex.new(4))
48
+ @graph.add_edge(Vertex.new(1),Vertex.new(4))
49
+ @graph.add_edge(Vertex.new(3),Vertex.new(2))
50
+ assert @graph.has_edge?(Vertex.new(1),Vertex.new(2))
51
+ assert @graph.has_edge?(Vertex.new(3),Vertex.new(4))
52
+ assert @graph.has_edge?(Vertex.new(4),Vertex.new(1))
53
+ assert @graph.has_edge?(Vertex.new(3),Vertex.new(2))
54
+ end
55
+
56
+ def test_loop
57
+ @graph.add_vertex(Vertex.new(1))
58
+ @graph.add_edge(Vertex.new(1),Vertex.new(1))
59
+ assert @graph.has_edge?(Vertex.new(1),Vertex.new(1)), "@graph should have the edge just added."
60
+ end
61
+
62
+ def test_vertex_equal
63
+ assert Vertex.new(1).eql? Vertex.new(1)
64
+ assert Vertex.new("12345").eql? Vertex.new("12345")
65
+ end
66
+
67
+ def bfs_setup_hard
68
+ @bfs_graph = Graph.new
69
+ @bfs_graph.add_vertex(Vertex.new(1))
70
+ @bfs_graph.add_vertex(Vertex.new(2))
71
+ @bfs_graph.add_vertex(Vertex.new(3))
72
+ @bfs_graph.add_vertex(Vertex.new(4))
73
+ @bfs_graph.add_vertex(Vertex.new(5))
74
+ @bfs_graph.add_vertex(Vertex.new(6))
75
+ @bfs_graph.add_vertex(Vertex.new(7))
76
+ @bfs_graph.add_vertex(Vertex.new(8))
77
+ @bfs_graph.add_vertex(Vertex.new(9))
78
+ @bfs_graph.add_vertex(Vertex.new(10))
79
+ @bfs_graph.add_vertex(Vertex.new(11))
80
+
81
+ @bfs_graph.add_edge(Vertex.new(1),Vertex.new(2))
82
+ @bfs_graph.add_edge(Vertex.new(1),Vertex.new(3))
83
+ @bfs_graph.add_edge(Vertex.new(1),Vertex.new(4))
84
+ @bfs_graph.add_edge(Vertex.new(2),Vertex.new(5))
85
+ @bfs_graph.add_edge(Vertex.new(5),Vertex.new(6))
86
+ @bfs_graph.add_edge(Vertex.new(6),Vertex.new(7))
87
+ @bfs_graph.add_edge(Vertex.new(7),Vertex.new(8))
88
+ @bfs_graph.add_edge(Vertex.new(11),Vertex.new(8))
89
+ @bfs_graph.add_edge(Vertex.new(10),Vertex.new(5))
90
+ @bfs_graph.add_edge(Vertex.new(10),Vertex.new(9))
91
+ @bfs_graph.add_edge(Vertex.new(11),Vertex.new(9))
92
+ end
93
+
94
+ def bfs_setup_easy
95
+ @bfs_graph = Graph.new
96
+ @bfs_graph.add_vertex(Vertex.new(1))
97
+ @bfs_graph.add_vertex(Vertex.new(2))
98
+ @bfs_graph.add_vertex(Vertex.new(3))
99
+ @bfs_graph.add_vertex(Vertex.new(4))
100
+ @bfs_graph.add_edge(Vertex.new(1), Vertex.new(2))
101
+ @bfs_graph.add_edge(Vertex.new(1), Vertex.new(3))
102
+ @bfs_graph.add_edge(Vertex.new(1), Vertex.new(4))
103
+ end
104
+
105
+ #def test_bfs
106
+ # bfs_setup_hard
107
+ # assert @bfs_graph
108
+ # @bfs_graph.search(Vertex.new(1), "fifo")
109
+ # assert_equal "black", @bfs_graph.vertex(Vertex.new(1)).color
110
+ # assert_equal 0, @bfs_graph.get_vertex_distance(Vertex.new(1))
111
+ # assert_equal nil, @bfs_graph.get_vertex_predecessor(Vertex.new(1))
112
+ # assert_equal @bfs_graph.get_vertex_color(Vertex.new(11)), "black"
113
+ # assert @bfs_graph.get_vertex_distance(Vertex.new(11)) == 5
114
+ # assert @bfs_graph.get_vertex_predecessor(Vertex.new(11)) == Vertex.new(9)
115
+ #end
116
+
117
+ #def test_shortest_path
118
+ # bfs_setup_hard
119
+ # assert @bfs_graph
120
+ # @bfs_graph.search(Vertex.new(1), "fifo")
121
+ # path = @bfs_graph.shortest_path(Vertex.new(1), Vertex.new(11))
122
+ # assert path[0] == Vertex.new(1)
123
+ # assert path[1] == Vertex.new(2)
124
+ # assert path[2] == Vertex.new(5)
125
+ # assert path[3] == Vertex.new(10)
126
+ # assert path[4] == Vertex.new(9)
127
+ # assert path[5] == Vertex.new(11)
128
+ #end
129
+
130
+ #def test_no_shortest_path
131
+ # bfs_setup_hard
132
+ # assert @bfs_graph
133
+ #@bfs_graph.add_vertex(Vertex.new(20))
134
+ #@bfs_graph.search(Vertex.new(1), "fifo")
135
+ #path = @bfs_graph.shortest_path(Vertex.new(1), Vertex.new(20))
136
+ #assert path == "No path."
137
+ #end
138
+
139
+ def test_get_all_vertices
140
+ bfs_setup_easy
141
+ @bfs_graph.each { |vertex| assert vertex }
142
+ end
143
+
144
+ def test_neighbors_of
145
+ bfs_setup_easy
146
+ neighbors = @bfs_graph.neighbors_of(Vertex.new(1))
147
+ assert_equal 2, neighbors[0].id, "First neighbor should be 2."
148
+ assert_equal 3, neighbors[1].id, "Second neighbor should be 3."
149
+ assert_equal 4, neighbors[2].id, "Third neighbor should be 4."
150
+ end
151
+
152
+ def test_vertex_color
153
+ v = Vertex.new(1)
154
+ v.color = "gray"
155
+ @graph.add_vertex(v)
156
+ assert_equal "gray", @graph.vertex(Vertex.new(1)).color
157
+ end
158
+
159
+ def test_vertex_distance
160
+ v = Vertex.new(1)
161
+ v.distance = 100
162
+ @graph.add_vertex(v)
163
+ assert_equal 100, @graph.vertex(Vertex.new(1)).distance
164
+ end
165
+
166
+ def test_vertex_predecessor
167
+ @graph.add_vertex(Vertex.new(1))
168
+ @graph.vertex(Vertex.new(1)).predecessor = "5"
169
+ assert_equal "5", @graph.vertex(Vertex.new(1)).predecessor
170
+ end
171
+
172
+ #def test_dfs
173
+ # bfs_setup_hard
174
+ # assert @bfs_graph
175
+ # @bfs_graph.search(Vertex.new(1), "lifo")
176
+ # assert_equal "black", @bfs_graph.vertex(Vertex.new(1)).color
177
+ # assert_equal 0, @bfs_graph.vertex(Vertex.new(1)).distance
178
+ # assert_equal nil, @bfs_graph.vertex(Vertex.new(1)).predecessor
179
+ # assert_equal @bfs_graph.vertex(Vertex.new(11)).color, "black"
180
+ # assert @bfs_graph.vertex(Vertex.new(11)).distance == 5
181
+ # assert @bfs_graph.vertex(Vertex.new(11)).predecessor == Vertex.new(9)
182
+ #end
183
+ end
@@ -0,0 +1,46 @@
1
+ require 'minitest/autorun'
2
+ require_relative '../lib/mvQueue.rb'
3
+
4
+ class TestQueue < MiniTest::Unit::TestCase
5
+ def setup
6
+ @queue = Queue.new("fifo")
7
+ end
8
+
9
+ def iterate_setup(type)
10
+ @queue = Queue.new(type)
11
+ @queue.enqueue(1)
12
+ @queue.enqueue(2)
13
+ @queue.enqueue(3)
14
+ @queue.enqueue(4)
15
+ @queue.enqueue(5)
16
+ end
17
+
18
+ def test_enqueue_dequeue
19
+ @queue.enqueue("x")
20
+ assert_equal @queue.dequeue, "x"
21
+ end
22
+
23
+ def test_queue_accessor_is_private
24
+ refute @queue.respond_to? :queue
25
+ end
26
+
27
+ def test_iterate_queue
28
+ iterate_setup("fifo")
29
+ assert_equal 1, @queue.dequeue
30
+ assert_equal 2, @queue.dequeue
31
+ assert_equal 3, @queue.dequeue
32
+ assert_equal 4, @queue.dequeue
33
+ assert_equal 5, @queue.dequeue
34
+ assert @queue.empty?
35
+ end
36
+
37
+ def test_to_string
38
+ iterate_setup("fifo")
39
+ assert_equal "5,4,3,2,1", @queue.to_s
40
+ end
41
+
42
+ def test_to_string_stack
43
+ iterate_setup("lifo")
44
+ assert_equal "1,2,3,4,5", @queue.to_s
45
+ end
46
+ end
metadata ADDED
@@ -0,0 +1,62 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mvgraph
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jon Mckenzie, Dan Vingo
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-05-17 00:00:00.000000000 -04:00
13
+ default_executable:
14
+ dependencies: []
15
+ description: ! "mvGraph is an implementation of the graph data structure in Ruby.
16
+ \ It was created to solve \nsome classic AI search problems; as such, it currently
17
+ supports BFS, DFS, any user-defined heuristic search, as well as A*.\n"
18
+ email: danvingo@gmail.com
19
+ executables: []
20
+ extensions: []
21
+ extra_rdoc_files: []
22
+ files:
23
+ - MIT-LICENSE.txt
24
+ - test/test_mvGraph.rb
25
+ - test/test_mvQueue.rb
26
+ - Gemfile.lock
27
+ - Gemfile
28
+ - README
29
+ - doc/design.txt
30
+ - lib/mvQueue.rb
31
+ - lib/mvGraph.rb
32
+ - Rakefile
33
+ has_rdoc: true
34
+ homepage: ''
35
+ licenses: []
36
+ post_install_message:
37
+ rdoc_options: []
38
+ require_paths:
39
+ - lib
40
+ required_ruby_version: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: 1.9.2p180
46
+ required_rubygems_version: !ruby/object:Gem::Requirement
47
+ none: false
48
+ requirements:
49
+ - - ! '>='
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ requirements:
53
+ - None
54
+ rubyforge_project:
55
+ rubygems_version: 1.6.2
56
+ signing_key:
57
+ specification_version: 3
58
+ summary: A generic graph implementation, useful for solving problems where some sort
59
+ of search is needed.
60
+ test_files:
61
+ - test/test_mvGraph.rb
62
+ - test/test_mvQueue.rb