simple_graph 0.1.0

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.
@@ -0,0 +1,134 @@
1
+ require "simple_graph/version"
2
+
3
+ module SimpleGraph
4
+ class Graph
5
+ class Node
6
+ def initialize(id:, data:)
7
+ @data = data
8
+ @neighbors = []
9
+ @id = id
10
+ end
11
+
12
+ def add_neighbor(node)
13
+ @neighbors << node
14
+ end
15
+
16
+ attr_reader :neighbors
17
+ attr_reader :data
18
+ attr_reader :id
19
+ end
20
+
21
+ # Constructor
22
+ def initialize
23
+ # Our array of internal nodes
24
+ @nodes = []
25
+ # Helper hash lookup table
26
+ @nodes_by_id = {}
27
+ # Tracks the highest used id for autoincrement
28
+ @last_id = 0
29
+ end
30
+
31
+ # Add a new node to the graph
32
+ def add_node(id: nil, data: {})
33
+ id ||= next_id
34
+ node = Graph::Node.new(id: id, data: data)
35
+ @nodes << node
36
+ @nodes_by_id[id] = node
37
+ node
38
+ end
39
+
40
+ # Delete a node from the graph
41
+ def delete_node(node)
42
+ # Remove all edges connected with this node
43
+ node.neighbors.each do |neighbor|
44
+ neighbor.neighbors.delete(node)
45
+ end
46
+ # Remove the node itself
47
+ @nodes.delete(node)
48
+ end
49
+
50
+ # Retrieve the amount of nodes in the graph
51
+ def node_count
52
+ @nodes.length
53
+ end
54
+
55
+ # Retrieve a array of node ids in the graph
56
+ def node_ids
57
+ # The .to_a call is used to return a copy of the array so it cannot be modified from the outside.
58
+ @nodes_by_id.keys.to_a
59
+ end
60
+
61
+ # Method to connect 2 nodes
62
+ def connect_nodes(first, second)
63
+ @nodes_by_id[first].add_neighbor(@nodes_by_id[second])
64
+ @nodes_by_id[second].add_neighbor(@nodes_by_id[first])
65
+ end
66
+
67
+ # Retrieve the current graph in the DOT format to be used with Graphviz
68
+ def to_dot_string
69
+ str = "strict graph {\n"
70
+
71
+ @nodes.each do |node|
72
+ node.neighbors.each do |neighbor|
73
+ str << " \"#{node.data[:name]}\" -- \"#{neighbor.data[:name]}\";\n"
74
+ end
75
+ end
76
+
77
+ str << "}"
78
+ end
79
+
80
+ def load_from_string(str)
81
+ lines = str.lines.map(&:chomp)
82
+
83
+ separator_position = lines.index("#")
84
+
85
+ nodes = lines[0..separator_position - 1]
86
+ edges = lines[separator_position + 1..-1].map(&:split)
87
+
88
+ nodes.each do |node|
89
+ add_node(id: node)
90
+ end
91
+
92
+ edges.each do |edge|
93
+ connect_nodes(edge.first, edge.last)
94
+ end
95
+ end
96
+
97
+ def find_paths(source_id, terminal_id)
98
+ found_paths = []
99
+
100
+ # Path queue
101
+ paths = Queue.new
102
+
103
+ destination = @nodes_by_id[terminal_id]
104
+
105
+ # Current Path
106
+ path = [@nodes_by_id[source_id]]
107
+
108
+ paths << path
109
+
110
+ until paths.empty?
111
+ path = paths.pop
112
+
113
+ last = path.last
114
+
115
+ found_paths << path if last == destination
116
+
117
+ last.neighbors.each do |neighbor|
118
+ next if path.include?(neighbor)
119
+ # Note that this creates a copy of the current path.
120
+ paths << path + [neighbor]
121
+ end
122
+ end
123
+
124
+ found_paths.map { |found_path| found_path.map(&:id) }
125
+ end
126
+
127
+ private
128
+
129
+ def next_id
130
+ @last_id += 1 while @nodes_by_id.keys.include?(@last_id + 1)
131
+ @last_id += 1
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,3 @@
1
+ module SimpleGraph
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,27 @@
1
+ lib = File.expand_path("../lib", __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "simple_graph/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "simple_graph"
7
+ spec.version = SimpleGraph::VERSION
8
+ spec.authors = ["Kevin Nowald"]
9
+ spec.email = ["knowald1@gmail.com"]
10
+
11
+ spec.summary = "A simple graph library for Ruby supporting undirected, unweighted graphs."
12
+ # spec.description = "TODO: Write a longer description or delete this line."
13
+ spec.homepage = "https://github.com/Vesther/simple_graph"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ f.match(%r{^(test|spec|features)/})
18
+ end
19
+ spec.bindir = "exe"
20
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.15"
24
+ spec.add_development_dependency "pry"
25
+ spec.add_development_dependency "rake", "~> 10.0"
26
+ spec.add_development_dependency "rspec", "~> 3.0"
27
+ end
metadata ADDED
@@ -0,0 +1,130 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: simple_graph
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Kevin Nowald
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-11-23 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.15'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.15'
27
+ - !ruby/object:Gem::Dependency
28
+ name: pry
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: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ description:
70
+ email:
71
+ - knowald1@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - ".rspec"
78
+ - ".travis.yml"
79
+ - ".yardopts"
80
+ - Gemfile
81
+ - LICENSE.txt
82
+ - README.md
83
+ - Rakefile
84
+ - bin/console
85
+ - bin/setup
86
+ - docs/SimpleGraph.html
87
+ - docs/SimpleGraph/Graph.html
88
+ - docs/SimpleGraph/Graph/Node.html
89
+ - docs/_index.html
90
+ - docs/class_list.html
91
+ - docs/css/common.css
92
+ - docs/css/full_list.css
93
+ - docs/css/style.css
94
+ - docs/file.README.html
95
+ - docs/file_list.html
96
+ - docs/frames.html
97
+ - docs/index.html
98
+ - docs/js/app.js
99
+ - docs/js/full_list.js
100
+ - docs/js/jquery.js
101
+ - docs/method_list.html
102
+ - docs/top-level-namespace.html
103
+ - lib/simple_graph.rb
104
+ - lib/simple_graph/version.rb
105
+ - simple_graph.gemspec
106
+ homepage: https://github.com/Vesther/simple_graph
107
+ licenses:
108
+ - MIT
109
+ metadata: {}
110
+ post_install_message:
111
+ rdoc_options: []
112
+ require_paths:
113
+ - lib
114
+ required_ruby_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ required_rubygems_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ requirements: []
125
+ rubyforge_project:
126
+ rubygems_version: 2.6.7
127
+ signing_key:
128
+ specification_version: 4
129
+ summary: A simple graph library for Ruby supporting undirected, unweighted graphs.
130
+ test_files: []