simple-graph 1.0.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,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9df289cf2e820574d29a3423187552d0f41cd4be
4
+ data.tar.gz: 28ff78a5bc850c98b9507a13f32ee7dfb548267e
5
+ SHA512:
6
+ metadata.gz: 5f87b5205d846ab77fcd96a0b004bc602088affae6ebc23be3e8eccae760e077e92402ed7fea1060f5834071748ace4335f2c469f3cd91caaedd7cc922808438
7
+ data.tar.gz: c0ab5acf01b7d4c436e3f3b477db72c702984294770373de8ebf77923cfe5a1c6ea86e5c8c628bf22004c2a31114b8e5d1b3ceb36d7f3b66c072f56e2b1be8d0
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :development, :test do
6
+ gem 'pry-nav'
7
+ gem 'rake'
8
+ end
9
+
10
+ group :test do
11
+ gem 'rspec'
12
+ gem 'rr'
13
+ end
@@ -0,0 +1,3 @@
1
+ == 1.0.0
2
+
3
+ * Birthday!
@@ -0,0 +1,57 @@
1
+
2
+ ## simple-graph [![Build Status](https://secure.travis-ci.org/camertron/simple-graph.png?branch=master)](http://travis-ci.org/camertron/simple-graph)
3
+
4
+ A simple, no-frills graph implementation.
5
+
6
+ ## Installation
7
+
8
+ `gem install simple-graph`
9
+
10
+ ## Usage
11
+
12
+ ```ruby
13
+ require 'simple-graph'
14
+ ```
15
+
16
+ ### Adding Vertices
17
+
18
+ Let's model an airline that flies to certain cities:
19
+
20
+ ```ruby
21
+ graph = SimpleGraph::Graph.new
22
+ graph.add_vertex('Seattle')
23
+ graph.add_vertex('Los Angeles')
24
+ graph.add_vertex('Denver')
25
+ graph.add_vertex('New York')
26
+ graph.add_vertex('Miami')
27
+ ```
28
+
29
+ ### Adding Edges
30
+
31
+ ```ruby
32
+ graph.add_edge('Seattle', 'Los Angeles')
33
+ graph.add_edge('Seattle', 'Denver')
34
+ graph.add_edge('Los Angeles', 'Miami')
35
+ graph.add_edge('Denver', 'New York')
36
+ graph.add_edge('New York', 'Miami')
37
+ ```
38
+
39
+ ### Shortest Path
40
+
41
+ SimpleGraph doesn't support weighted edges, so let's pretend all these cities are equidistant from each other. We could also say we're trying to find the least number of layovers:
42
+
43
+ ```ruby
44
+ graph.shortest_path('Seattle', 'Miami') # ["Seattle", "Los Angeles", "Miami"]
45
+ ```
46
+
47
+ ## Requirements
48
+
49
+ None.
50
+
51
+ ## Running Tests
52
+
53
+ `bundle exec rspec`
54
+
55
+ ## Authors
56
+
57
+ * Cameron C. Dutro: http://github.com/camertron
@@ -0,0 +1,18 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'rubygems' unless ENV['NO_RUBYGEMS']
4
+
5
+ require 'bundler'
6
+ require 'rspec/core/rake_task'
7
+ require 'rubygems/package_task'
8
+
9
+ require './lib/simple-graph'
10
+
11
+ Bundler::GemHelper.install_tasks
12
+
13
+ task :default => :spec
14
+
15
+ desc 'Run specs'
16
+ RSpec::Core::RakeTask.new do |t|
17
+ t.pattern = './spec/**/*_spec.rb'
18
+ end
@@ -0,0 +1,90 @@
1
+ # encoding: UTF-8
2
+
3
+ module SimpleGraph
4
+
5
+ class Vertex
6
+ attr_reader :value, :neighbors
7
+
8
+ def initialize(value, neighbors = {})
9
+ @value = value
10
+ @neighbors = neighbors || {}
11
+ end
12
+
13
+ def add_neighbor(vertex)
14
+ neighbors[vertex.value] ||= vertex
15
+ end
16
+ end
17
+
18
+ class Graph
19
+ attr_reader :vertices
20
+
21
+ def initialize
22
+ @vertices = {}
23
+ end
24
+
25
+ def add_vertex(value)
26
+ vertices[value] ||= create_vertex(value)
27
+ end
28
+
29
+ def add_edge(value1, value2)
30
+ vertices[value1].add_neighbor(vertices[value2])
31
+ end
32
+
33
+ # Djikstra's shortest path algorithm, adapted from:
34
+ # https://gist.github.com/yaraki/1730288
35
+ def shortest_path(source, target = nil)
36
+ distances = {}
37
+ previouses = {}
38
+
39
+ vertices.each_pair do |key, vertex|
40
+ distances[key] = nil # Infinity
41
+ previouses[key] = nil
42
+ end
43
+
44
+ distances[source] = 0
45
+ verts = vertices.clone
46
+
47
+ until verts.empty?
48
+ nearest_vertex = verts.inject(verts.first.first) do |a, (b, c)|
49
+ next b unless distances[a]
50
+ next a unless distances[b]
51
+ next a if distances[a] < distances[b]
52
+ b
53
+ end
54
+
55
+ break unless distances[nearest_vertex] # Infinity
56
+
57
+ if target && nearest_vertex == target
58
+ return compose_path(target, distances[target], previouses)
59
+ end
60
+
61
+ neighbors = verts[nearest_vertex].neighbors
62
+ neighbors.each_pair do |name, vertex|
63
+ alt = distances[nearest_vertex] + 1
64
+
65
+ if distances[name].nil? || alt < distances[name]
66
+ distances[name] = alt
67
+ previouses[name] = nearest_vertex
68
+ end
69
+ end
70
+ verts.delete(nearest_vertex)
71
+ end
72
+ end
73
+
74
+ private
75
+
76
+ def compose_path(target, distance, previouses)
77
+ result = Array.new(distance)
78
+ distance.downto(0) do |i|
79
+ result[i] = target
80
+ target = previouses[target]
81
+ end
82
+ result
83
+ end
84
+
85
+ def create_vertex(value, edges = nil)
86
+ Vertex.new(value, edges)
87
+ end
88
+ end
89
+
90
+ end
@@ -0,0 +1,5 @@
1
+ # encoding: UTF-8
2
+
3
+ module SimpleGraph
4
+ VERSION = "1.0.0"
5
+ end
@@ -0,0 +1,18 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), 'lib')
2
+ require 'simple-graph/version'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "simple-graph"
6
+ s.version = ::SimpleGraph::VERSION
7
+ s.authors = ["Cameron Dutro"]
8
+ s.email = ["camertron@gmail.com"]
9
+ s.homepage = "http://github.com/camertron"
10
+
11
+ s.description = s.summary = "A simple, no-frills graph implementation."
12
+
13
+ s.platform = Gem::Platform::RUBY
14
+ s.has_rdoc = true
15
+
16
+ s.require_path = 'lib'
17
+ s.files = Dir["{lib,spec}/**/*", "Gemfile", "History.txt", "README.md", "Rakefile", "simple-graph.gemspec"]
18
+ end
@@ -0,0 +1,50 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe SimpleGraph do
6
+ let(:graph) { SimpleGraph::Graph.new }
7
+
8
+ describe '#add_vertex' do
9
+ it 'should add vertices correctly' do
10
+ graph.add_vertex('Seattle').tap do |vertex|
11
+ expect(vertex).to be_a(SimpleGraph::Vertex)
12
+ expect(vertex.value).to eq('Seattle')
13
+ expect(vertex.neighbors).to eq({})
14
+ end
15
+ end
16
+ end
17
+
18
+ describe '#add_edge' do
19
+ it 'should add edges correctly' do
20
+ seattle = graph.add_vertex('Seattle')
21
+ la = graph.add_vertex('Los Angeles')
22
+ graph.add_edge('Seattle', 'Los Angeles')
23
+ expect(seattle.neighbors).to include('Los Angeles')
24
+ end
25
+ end
26
+
27
+ context 'with a nice graph' do
28
+ before(:each) do
29
+ graph.add_vertex('Seattle')
30
+ graph.add_vertex('Los Angeles')
31
+ graph.add_vertex('Denver')
32
+ graph.add_vertex('New York')
33
+ graph.add_vertex('Miami')
34
+
35
+ graph.add_edge('Seattle', 'Los Angeles')
36
+ graph.add_edge('Seattle', 'Denver')
37
+ graph.add_edge('Los Angeles', 'Miami')
38
+ graph.add_edge('Denver', 'New York')
39
+ graph.add_edge('New York', 'Miami')
40
+ end
41
+
42
+ describe '#shortest_path' do
43
+ it 'finds the shortest path' do
44
+ expect(graph.shortest_path('Seattle', 'Miami')).to eq([
45
+ "Seattle", "Los Angeles", "Miami"
46
+ ])
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: UTF-8
2
+
3
+ $:.push(File.dirname(__FILE__))
4
+
5
+ require 'rspec'
6
+ require 'simple-graph'
7
+ require 'pry-nav'
8
+
9
+ RSpec.configure do |config|
10
+ config.mock_with :rr
11
+ end
metadata ADDED
@@ -0,0 +1,52 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: simple-graph
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Cameron Dutro
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-06-23 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A simple, no-frills graph implementation.
14
+ email:
15
+ - camertron@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - Gemfile
21
+ - History.txt
22
+ - README.md
23
+ - Rakefile
24
+ - lib/simple-graph.rb
25
+ - lib/simple-graph/version.rb
26
+ - simple-graph.gemspec
27
+ - spec/simple-graph_spec.rb
28
+ - spec/spec_helper.rb
29
+ homepage: http://github.com/camertron
30
+ licenses: []
31
+ metadata: {}
32
+ post_install_message:
33
+ rdoc_options: []
34
+ require_paths:
35
+ - lib
36
+ required_ruby_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ required_rubygems_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ requirements: []
47
+ rubyforge_project:
48
+ rubygems_version: 2.2.2
49
+ signing_key:
50
+ specification_version: 4
51
+ summary: A simple, no-frills graph implementation.
52
+ test_files: []