graphos 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 17e52e382a16f64bff7268a1e16d05b766ffba07
4
- data.tar.gz: 2722ab24892ed985395292e46d7589cf0a610cbf
3
+ metadata.gz: d2e7925a7c025ce637e6903a5de7bd4ccf279da1
4
+ data.tar.gz: 5606dcf83f9d0f7df45a0f506884629c51e9d1b4
5
5
  SHA512:
6
- metadata.gz: 3ddb151b5cec18977a18fd12b6814009c0744241e02d42fd2b38c68fe05a78cb9c4dc0b4be8af84b5447792b59565ba2c15aeeb1ea6ea034f6c92a2e15b58458
7
- data.tar.gz: e459dd620cb44803f8581bbd6f1df29a1d1a82db01731741bef88c6e23a3edf641d32915e58f9e9dde6bc28eafbeb7c8f9a718a7954318334f0a99b41de06c00
6
+ metadata.gz: 29976de225239e5008690fc052e899dfc597f4b7760b26a40f04fb33176b9d71296b2459d648d250b9b58afef0baf7e11c76020596aa8ff5b1401231cc761501
7
+ data.tar.gz: 4136aec7330eca3220c5e826ff7011d9a1193292abb8d3c7c7084d9a785a472e8553d330a5b45c7a3dc55ea8e85f01886f0466d4dba2c2a64e09d256a81d6747
data/Gemfile CHANGED
@@ -2,5 +2,3 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in graphos.gemspec
4
4
  gemspec
5
-
6
- gem "ruby-lxc", github: "lxc/ruby-lxc", require: "lxc"
data/graphos.gemspec CHANGED
@@ -24,5 +24,5 @@ Gem::Specification.new do |spec|
24
24
  spec.add_development_dependency "minitest-reporters", "~> 1.0"
25
25
  spec.add_development_dependency "pry", "~>0.10"
26
26
 
27
- spec.add_dependency "algorithms", "~>0.6"
27
+ spec.add_dependency "amorim-algorithms", "~>0.6"
28
28
  end
@@ -2,15 +2,11 @@ require "algorithms"
2
2
  require "graphos/path"
3
3
  module Graphos
4
4
  module Algorithm
5
- include Containers
6
5
  ##
7
6
  # Runs the dijstra algorithm on a given graph
8
7
  # at a starting node
9
8
  # This uses a Heap to get the lightest edge
10
9
  def self.dijkstra graph, initial
11
- #OK? E o path?
12
- fathers = Array.new(graph.size)
13
-
14
10
  #os paf
15
11
  allPaths = Array.new(graph.size)
16
12
 
@@ -20,23 +16,23 @@ module Graphos
20
16
  costs[initial] = 0
21
17
 
22
18
  #OK
23
- heap = Heap.new{|x,y| (costs[x] <=> costs[y]) == -1}
24
- (0...graph.size).each{|i| heap.push(i)}
19
+ heap = BinaryHeap.new{|x,y| x.value <=> y.value}
20
+ heap.push(initial,0)
25
21
 
26
22
  update_cost = -> (idx,cost) do
27
23
  costs[idx] = cost
28
- if(heap.has_key?(idx))
29
- heap.delete(idx)
30
- heap.push(idx)
24
+ if heap.has_key? idx
25
+ heap.change idx, cost
26
+ else
27
+ heap.push idx, cost
31
28
  end
32
29
  end
33
30
 
34
- count = 0
35
-
36
31
  #Para cada vértice v
37
32
  #enquanto heap (S-V) != 0
38
- while idx=heap.pop
39
- count += 1
33
+
34
+ while keyval=heap.pop
35
+ idx = keyval.key
40
36
  #Selecione u em V-S, tal que dist[u] é mínima
41
37
  u = graph[idx]
42
38
  distu = costs[idx]
@@ -46,16 +42,12 @@ module Graphos
46
42
  #Se dist[v] > dist[u] + w(u,v) então
47
43
  if costs[edge.to.index] > distu + edge.weight
48
44
  #dist[v] = dist[u] + w(u,v)
49
- fathers[edge.to.index] = u.index
50
45
  update_cost.call(edge.to.index, distu + edge.weight)
51
46
  #criar o Path entre root e v
52
47
  #se existe já, tem q atualizar. O novo é o do pai + ele msm
53
48
  allPaths[edge.to.index] = allPaths[u.index] + Path.new(edge)
54
49
  end
55
50
  end
56
-
57
- # No more nodes!
58
- break if(idx == heap.next)
59
51
  end
60
52
 
61
53
  allPaths
@@ -0,0 +1,113 @@
1
+ module Graphos
2
+ class BinaryHeap
3
+ def initialize &compare
4
+ @compare = compare
5
+ @indexes = []
6
+ @keys = []
7
+ @values = []
8
+ end
9
+
10
+ def push key, value
11
+ if !has_key? key
12
+ insert key, value
13
+ end
14
+ end
15
+
16
+ def has_key? key
17
+ @indexes[key] != nil
18
+ end
19
+
20
+ def next
21
+ if key = @keys.first
22
+ key_val key
23
+ end
24
+ end
25
+
26
+ def change key, new_value
27
+ if has_key? key
28
+ @values[key] = new_value
29
+ move_up key
30
+ move_down key
31
+ end
32
+ end
33
+
34
+ def pop
35
+ return nil if size == 0
36
+
37
+ result = key_val(@keys.first)
38
+ @indexes[result.key] = nil
39
+ @values[result.key] = nil
40
+
41
+ last = @keys.pop
42
+ if size > 0
43
+ @keys[0] = last
44
+ @indexes[last] = 0
45
+ end
46
+
47
+ result
48
+ end
49
+
50
+ def size
51
+ @keys.size
52
+ end
53
+
54
+ private
55
+ KeyVal = Struct.new(:key, :value)
56
+
57
+ def key_val key
58
+ KeyVal.new(key, @values[key])
59
+ end
60
+
61
+ def insert key, value
62
+ @indexes[key] = @keys.size
63
+ @keys.push key
64
+ @values[key] = value
65
+
66
+ move_up key
67
+ end
68
+
69
+ def move_down key
70
+ left_key = @keys[left(@indexes[key])]
71
+ right_key = @keys[right(@indexes[key])]
72
+ return if !left_key && !right_key
73
+
74
+ max_key = [key, left_key, right_key].select{|x| !!x}.sort do |x,y|
75
+ @compare.call(key_val(x), key_val(y))
76
+ end.first
77
+
78
+ return if max_key == key
79
+
80
+ swap(@indexes[key], @indexes[max_key])
81
+ move_down max_key
82
+ end
83
+
84
+ def move_up key
85
+ while(
86
+ @indexes[key] != 0 &&
87
+ smaller(key_val(key), key_val(@keys[parent(@indexes[key])]))
88
+ )
89
+ swap(parent(@indexes[key]), @indexes[key])
90
+ end
91
+ end
92
+
93
+ def parent i
94
+ (i-1)/2
95
+ end
96
+
97
+ def left i
98
+ 2*i + 1
99
+ end
100
+ def right i
101
+ 2*i + 2
102
+ end
103
+
104
+ def swap a, b
105
+ @keys[a], @keys[b] = @keys[b], @keys[a]
106
+ @indexes[@keys[a]], @indexes[@keys[b]] = @indexes[@keys[b]], @indexes[@keys[a]]
107
+ end
108
+
109
+ def smaller a, b
110
+ @compare.call(a,b) == -1
111
+ end
112
+ end
113
+ end
@@ -1,3 +1,3 @@
1
1
  module Graphos
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -0,0 +1,32 @@
1
+ require_relative "minitest_helper.rb"
2
+ require "graphos/binary_heap"
3
+
4
+ class BinaryHeapTest < MiniTest::Test
5
+ def test_binary_heap
6
+ bh = Graphos::BinaryHeap.new{|x,y| x.value <=> y.value}
7
+ bh.push(1,5)
8
+ bh.push(2,4)
9
+ bh.push(3,7)
10
+
11
+ assert_equal(2, bh.next.key)
12
+ bh.change(2,6)
13
+ assert_equal(1, bh.next.key)
14
+ bh.change(3,4)
15
+ assert_equal(3, bh.pop.key)
16
+ assert_equal(1, bh.pop.key)
17
+ assert_equal(2, bh.pop.key)
18
+ assert_equal(nil, bh.pop)
19
+ end
20
+
21
+ def test_move_up
22
+ bh = Graphos::BinaryHeap.new{|x,y| x.value <=> y.value}
23
+ (1..100).each do |i|
24
+ bh.push(i,Float::INFINITY)
25
+ end
26
+
27
+ bh.change(100,1)
28
+ assert_equal(100,bh.next.key)
29
+ bh.change(99,0)
30
+ assert_equal(99,bh.next.key)
31
+ end
32
+ end
@@ -8,7 +8,8 @@ class DijkstraTest < MiniTest::Test
8
8
 
9
9
  dij = Graphos::Algorithm.dijkstra graph, 0
10
10
 
11
- assert_equal([99,16,7,66,9], ipath(dij[9]))
11
+ assert_equal(19, dij[9].cost)
12
+ assert_equal(24, dij[19].cost)
12
13
  end
13
14
  def test_dijskstra
14
15
  graph = Graphos::Weighted::Graph.new(5)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphos
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bernardo Amorim
@@ -82,7 +82,7 @@ dependencies:
82
82
  - !ruby/object:Gem::Version
83
83
  version: '0.10'
84
84
  - !ruby/object:Gem::Dependency
85
- name: algorithms
85
+ name: amorim-algorithms
86
86
  requirement: !ruby/object:Gem::Requirement
87
87
  requirements:
88
88
  - - "~>"
@@ -112,12 +112,14 @@ files:
112
112
  - lib/graphos.rb
113
113
  - lib/graphos/algorithm/dijkstra.rb
114
114
  - lib/graphos/algorithm/prim.rb
115
+ - lib/graphos/binary_heap.rb
115
116
  - lib/graphos/path.rb
116
117
  - lib/graphos/version.rb
117
118
  - lib/graphos/weighted/edge.rb
118
119
  - lib/graphos/weighted/graph.rb
119
120
  - lib/graphos/weighted/node.rb
120
121
  - lib/graphos/weighted/text_factory.rb
122
+ - test/binary_heap_test.rb
121
123
  - test/dijsktra_test.rb
122
124
  - test/fixtures/grafo_1.txt
123
125
  - test/fixtures/wgraph.txt
@@ -150,6 +152,7 @@ signing_key:
150
152
  specification_version: 4
151
153
  summary: Educational gem to Graph Theory @ UFRJ
152
154
  test_files:
155
+ - test/binary_heap_test.rb
153
156
  - test/dijsktra_test.rb
154
157
  - test/fixtures/grafo_1.txt
155
158
  - test/fixtures/wgraph.txt