graphos 0.1.1 → 0.2.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 +4 -4
- data/Gemfile +0 -2
- data/graphos.gemspec +1 -1
- data/lib/graphos/algorithm/dijkstra.rb +9 -17
- data/lib/graphos/binary_heap.rb +113 -0
- data/lib/graphos/version.rb +1 -1
- data/test/binary_heap_test.rb +32 -0
- data/test/dijsktra_test.rb +2 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d2e7925a7c025ce637e6903a5de7bd4ccf279da1
|
4
|
+
data.tar.gz: 5606dcf83f9d0f7df45a0f506884629c51e9d1b4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 29976de225239e5008690fc052e899dfc597f4b7760b26a40f04fb33176b9d71296b2459d648d250b9b58afef0baf7e11c76020596aa8ff5b1401231cc761501
|
7
|
+
data.tar.gz: 4136aec7330eca3220c5e826ff7011d9a1193292abb8d3c7c7084d9a785a472e8553d330a5b45c7a3dc55ea8e85f01886f0466d4dba2c2a64e09d256a81d6747
|
data/Gemfile
CHANGED
data/graphos.gemspec
CHANGED
@@ -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 =
|
24
|
-
|
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
|
29
|
-
heap.
|
30
|
-
|
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
|
-
|
39
|
-
|
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
|
data/lib/graphos/version.rb
CHANGED
@@ -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
|
data/test/dijsktra_test.rb
CHANGED
@@ -8,7 +8,8 @@ class DijkstraTest < MiniTest::Test
|
|
8
8
|
|
9
9
|
dij = Graphos::Algorithm.dijkstra graph, 0
|
10
10
|
|
11
|
-
assert_equal(
|
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.
|
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
|