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.
- checksums.yaml +7 -0
- data/.gitignore +13 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/.yardopts +3 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +75 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/docs/SimpleGraph.html +127 -0
- data/docs/SimpleGraph/Graph.html +825 -0
- data/docs/SimpleGraph/Graph/Node.html +483 -0
- data/docs/_index.html +137 -0
- data/docs/class_list.html +51 -0
- data/docs/css/common.css +1 -0
- data/docs/css/full_list.css +58 -0
- data/docs/css/style.css +492 -0
- data/docs/file.README.html +147 -0
- data/docs/file_list.html +56 -0
- data/docs/frames.html +17 -0
- data/docs/index.html +147 -0
- data/docs/js/app.js +248 -0
- data/docs/js/full_list.js +216 -0
- data/docs/js/jquery.js +4 -0
- data/docs/method_list.html +163 -0
- data/docs/top-level-namespace.html +110 -0
- data/lib/simple_graph.rb +134 -0
- data/lib/simple_graph/version.rb +3 -0
- data/simple_graph.gemspec +27 -0
- metadata +130 -0
data/lib/simple_graph.rb
ADDED
@@ -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,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: []
|