graphsrb 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/.DS_Store +0 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.travis.yml +7 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +37 -0
- data/LICENSE.txt +21 -0
- data/README.md +338 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/examples/ApproxAlgs/TSP/tsp.rb +45 -0
- data/examples/ApproxAlgs/VertexCover/main.rb +34 -0
- data/examples/ApproxAlgs/VertexCover/vertex_cover.rb +31 -0
- data/examples/Apts/artc_points.rb +59 -0
- data/examples/Apts/main.rb +51 -0
- data/examples/BackEdges/backedges.rb +37 -0
- data/examples/BackEdges/main.rb +41 -0
- data/examples/BipartMatching/bipart_matching.rb +34 -0
- data/examples/BipartMatching/main.rb +58 -0
- data/examples/EdgeConnectivity/econ.rb +31 -0
- data/examples/EdgeConnectivity/main.rb +34 -0
- data/examples/Euler/euler_tour.rb +36 -0
- data/examples/Euler/main.rb +19 -0
- data/examples/FundCircuits/fund_circuits.rb +49 -0
- data/examples/FundCircuits/main.rb +34 -0
- data/examples/FundCutsets/fund_cutsets.rb +50 -0
- data/examples/FundCutsets/main.rb +26 -0
- data/examples/MaxFlow/edmonds_karp.rb +91 -0
- data/examples/MaxFlow/main.rb +79 -0
- data/examples/PrimMST/main.rb +46 -0
- data/examples/PrimMST/prim.rb +82 -0
- data/examples/ProbAlgs/LargeCustset/large_cutset.rb +59 -0
- data/examples/ProbAlgs/LargeCustset/main.rb +45 -0
- data/graphsrb.gemspec +39 -0
- data/lib/graphsrb.rb +11 -0
- data/lib/graphsrb/adjacency_list.rb +78 -0
- data/lib/graphsrb/base_graph.rb +167 -0
- data/lib/graphsrb/diedge.rb +6 -0
- data/lib/graphsrb/digraph.rb +93 -0
- data/lib/graphsrb/edge.rb +34 -0
- data/lib/graphsrb/exceptions.rb +5 -0
- data/lib/graphsrb/graph.rb +46 -0
- data/lib/graphsrb/node.rb +21 -0
- data/lib/graphsrb/version.rb +3 -0
- data/lib/graphsrb/vertex.rb +32 -0
- metadata +149 -0
@@ -0,0 +1,93 @@
|
|
1
|
+
#Directed graph
|
2
|
+
class Graphsrb::Digraph < Graphsrb::BaseGraph
|
3
|
+
|
4
|
+
#Retrieves adjacent vertices of a vertex (takes only outgoing edeges)
|
5
|
+
def adjacent_vertices(vertex)
|
6
|
+
nodes = []
|
7
|
+
id = vertex.id
|
8
|
+
nodes = adj_table[id].nodes unless adj_table[id].nil?
|
9
|
+
#Convert nodes into vertices
|
10
|
+
nodes.map{|node| _create_vertex(node.vertex.id)}
|
11
|
+
end
|
12
|
+
|
13
|
+
alias neighborhood adjacent_vertices
|
14
|
+
|
15
|
+
#Checks whether the digraph has an edge
|
16
|
+
def has_edge?(id1, id2)
|
17
|
+
has_vertex?(id1) && adj_table[id1].has_node?(_create_node(id2))
|
18
|
+
end
|
19
|
+
alias edge? has_edge?
|
20
|
+
|
21
|
+
#Retrieves an edge
|
22
|
+
def edge(v, u)
|
23
|
+
id1, id2 = v.id, u.id
|
24
|
+
if has_vertex?(id1)
|
25
|
+
node = adj_table[id1].find(_create_node(id2))
|
26
|
+
return _create_edge(id1, id2, weight:node.weight) if node
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
#Updates edge weight
|
31
|
+
def update_weight(v, u, w)
|
32
|
+
id1, id2 = v.id, u.id
|
33
|
+
adj_table[id1].update_weight(_create_node(id2), w) if has_vertex?(id1)
|
34
|
+
end
|
35
|
+
|
36
|
+
#Increses edge weight by +w+
|
37
|
+
def increase_weight(v, u, dw)
|
38
|
+
id1, id2 = v.id, u.id
|
39
|
+
adj_table[id1].increase_weight(_create_node(id2), dw) if has_vertex?(id1)
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
#Remove an edge from the graph
|
44
|
+
def remove_edge(id1, id2)
|
45
|
+
adj_table[id1].delete(_create_node(id2)) if has_vertex?(id1)
|
46
|
+
true
|
47
|
+
end
|
48
|
+
|
49
|
+
#Retrieves outgoing edges of a vertex
|
50
|
+
def outgoing_edges(v)
|
51
|
+
#Convert nodes into edges
|
52
|
+
_outgoing_nodes(v.id).map{|node| _create_edge(v.id, node.vertex.id, weight:node.weight)}
|
53
|
+
end
|
54
|
+
|
55
|
+
#Retrieves incoming edges of a vertex
|
56
|
+
def incoming_edges(v)
|
57
|
+
#Convert nodes into edges
|
58
|
+
_incoming_nodes(v.id).map{|node| _create_edge(node.vertex.id, v.id, weight:node.weight)}
|
59
|
+
end
|
60
|
+
|
61
|
+
#Returns +out-degree+ of a vertex
|
62
|
+
def outdegree(v)
|
63
|
+
_outgoing_nodes(v.id).size
|
64
|
+
end
|
65
|
+
|
66
|
+
#Returns +in-degree+ of a vertex
|
67
|
+
def indegree(v)
|
68
|
+
_incoming_nodes(v.id).size
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def _outgoing_nodes(id)
|
74
|
+
nodes = []
|
75
|
+
nodes = adj_table[id].nodes unless adj_table[id].nil?
|
76
|
+
nodes
|
77
|
+
end
|
78
|
+
|
79
|
+
def _incoming_nodes(id)
|
80
|
+
nodes = []
|
81
|
+
vertices.each do |vertex|
|
82
|
+
next if vertex.id == id
|
83
|
+
node = adj_table[vertex.id].find(_create_node(id))
|
84
|
+
nodes << _create_node(vertex.id, weight:node.weight) unless node.nil?
|
85
|
+
end
|
86
|
+
nodes
|
87
|
+
end
|
88
|
+
|
89
|
+
protected
|
90
|
+
def _create_edge(id1, id2, args={})
|
91
|
+
Graphsrb::DiEdge.new(id1, id2, args)
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
|
2
|
+
class Graphsrb::Edge
|
3
|
+
attr_reader :vertex1, :vertex2, :weight
|
4
|
+
def initialize(id1, id2, args={})
|
5
|
+
if id1 == id2
|
6
|
+
raise Graphsrb::EdgeInitializationError, "Vertex id's must be different from each other"
|
7
|
+
end
|
8
|
+
|
9
|
+
@vertex1 = Graphsrb::Vertex.new(id1)
|
10
|
+
@vertex2 = Graphsrb::Vertex.new(id2)
|
11
|
+
@weight = args.fetch(:weight, 1)
|
12
|
+
end
|
13
|
+
|
14
|
+
alias initial_vertex vertex1
|
15
|
+
alias terminal_vertex vertex2
|
16
|
+
|
17
|
+
def ==(other)
|
18
|
+
(vertex1.id == other.vertex1.id) && (vertex2.id == other.vertex2.id) ||
|
19
|
+
(vertex1.id == other.vertex2.id) && (vertex2.id == other.vertex1.id)
|
20
|
+
end
|
21
|
+
|
22
|
+
def eql?(other)
|
23
|
+
self == other
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_s
|
27
|
+
"(#{vertex1.id}, #{vertex2.id}, weight:#{weight})"
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_json
|
31
|
+
{vertex1: vertex1.id, vertex2: vertex2.id, weight: weight}.to_json
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
class Graphsrb::Graph < Graphsrb::BaseGraph
|
2
|
+
|
3
|
+
#Retrieves adjacent vertices of a vertex
|
4
|
+
def adjacent_vertices(vertex)
|
5
|
+
nodes = []
|
6
|
+
id = vertex.id
|
7
|
+
nodes = adj_table[id].nodes unless adj_table[id].nil?
|
8
|
+
vertices.each do |v|
|
9
|
+
next if v.id == id
|
10
|
+
node = adj_table[v.id].find(_create_node(id))
|
11
|
+
nodes << _create_node(v.id, weight:node.weight) unless node.nil?
|
12
|
+
end
|
13
|
+
#Convert nodes into vertices
|
14
|
+
nodes.map{|node| _create_vertex(node.vertex.id)}
|
15
|
+
end
|
16
|
+
|
17
|
+
alias neighborhood adjacent_vertices
|
18
|
+
|
19
|
+
#Retrieves incident edges of a vertex
|
20
|
+
def incident_edges(v)
|
21
|
+
#Convert nodes into edges with weights
|
22
|
+
_incident_nodes(v.id).map{|node| _create_edge(v.id, node.vertex.id, weight:node.weight)}
|
23
|
+
end
|
24
|
+
|
25
|
+
#Returns +degree+ of a vertex
|
26
|
+
def degree(v)
|
27
|
+
_incident_nodes(v.id).size
|
28
|
+
end
|
29
|
+
|
30
|
+
#Returns maximum degree of all graph vertices
|
31
|
+
def max_degree
|
32
|
+
self.vertices.map{|v| self.degree(v)}.max
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
def _incident_nodes(id)
|
37
|
+
nodes = []
|
38
|
+
nodes = adj_table[id].nodes unless adj_table[id].nil?
|
39
|
+
vertices.each do |vertex|
|
40
|
+
next if vertex.id == id
|
41
|
+
node = adj_table[vertex.id].find(_create_node(id))
|
42
|
+
nodes << _create_node(vertex.id, weight:node.weight) unless node.nil?
|
43
|
+
end
|
44
|
+
nodes
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
|
2
|
+
#This class represents a single entry in a adjacency list.
|
3
|
+
class Graphsrb::Node
|
4
|
+
attr_reader :vertex, :weight
|
5
|
+
|
6
|
+
#Creates a new node
|
7
|
+
def initialize(vertex_id, args={})
|
8
|
+
@vertex = Graphsrb::Vertex.new(vertex_id)
|
9
|
+
@weight = args.fetch(:weight, 1)
|
10
|
+
end
|
11
|
+
|
12
|
+
#Updates weight
|
13
|
+
def update_weight(w)
|
14
|
+
@weight = w
|
15
|
+
end
|
16
|
+
|
17
|
+
#Compares two nodes. Two nodes are equal if their +vertices+ are equal.
|
18
|
+
def ==(node)
|
19
|
+
vertex == node.vertex
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
|
2
|
+
#This class represents a graph vertex.
|
3
|
+
class Graphsrb::Vertex
|
4
|
+
attr_reader :id
|
5
|
+
|
6
|
+
#Creates a vertex given its +id+, a nonnegative integer.
|
7
|
+
def initialize(id)
|
8
|
+
raise Graphsrb::VertexInitializationError, 'Vertex id may not be nil' if id.nil?
|
9
|
+
@id = id
|
10
|
+
end
|
11
|
+
|
12
|
+
#Compares two vertices. Two vertices are equal if their +id+s are equal.
|
13
|
+
def ==(vertex)
|
14
|
+
id == vertex.id
|
15
|
+
end
|
16
|
+
|
17
|
+
def !=(vertex)
|
18
|
+
id != vertex.id
|
19
|
+
end
|
20
|
+
|
21
|
+
def eql?(other)
|
22
|
+
self == other
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_s
|
26
|
+
self.id.to_s
|
27
|
+
end
|
28
|
+
|
29
|
+
def hash
|
30
|
+
self.id
|
31
|
+
end
|
32
|
+
end
|
metadata
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: graphsrb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Bayram Kuliyev
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-01-13 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.16'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.16'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: json
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.8'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.8'
|
69
|
+
description:
|
70
|
+
email:
|
71
|
+
- bkuliyev@gmail.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- ".DS_Store"
|
77
|
+
- ".gitignore"
|
78
|
+
- ".rspec"
|
79
|
+
- ".travis.yml"
|
80
|
+
- CODE_OF_CONDUCT.md
|
81
|
+
- Gemfile
|
82
|
+
- Gemfile.lock
|
83
|
+
- LICENSE.txt
|
84
|
+
- README.md
|
85
|
+
- Rakefile
|
86
|
+
- bin/console
|
87
|
+
- bin/setup
|
88
|
+
- examples/ApproxAlgs/TSP/tsp.rb
|
89
|
+
- examples/ApproxAlgs/VertexCover/main.rb
|
90
|
+
- examples/ApproxAlgs/VertexCover/vertex_cover.rb
|
91
|
+
- examples/Apts/artc_points.rb
|
92
|
+
- examples/Apts/main.rb
|
93
|
+
- examples/BackEdges/backedges.rb
|
94
|
+
- examples/BackEdges/main.rb
|
95
|
+
- examples/BipartMatching/bipart_matching.rb
|
96
|
+
- examples/BipartMatching/main.rb
|
97
|
+
- examples/EdgeConnectivity/econ.rb
|
98
|
+
- examples/EdgeConnectivity/main.rb
|
99
|
+
- examples/Euler/euler_tour.rb
|
100
|
+
- examples/Euler/main.rb
|
101
|
+
- examples/FundCircuits/fund_circuits.rb
|
102
|
+
- examples/FundCircuits/main.rb
|
103
|
+
- examples/FundCutsets/fund_cutsets.rb
|
104
|
+
- examples/FundCutsets/main.rb
|
105
|
+
- examples/MaxFlow/edmonds_karp.rb
|
106
|
+
- examples/MaxFlow/main.rb
|
107
|
+
- examples/PrimMST/main.rb
|
108
|
+
- examples/PrimMST/prim.rb
|
109
|
+
- examples/ProbAlgs/LargeCustset/large_cutset.rb
|
110
|
+
- examples/ProbAlgs/LargeCustset/main.rb
|
111
|
+
- graphsrb.gemspec
|
112
|
+
- lib/graphsrb.rb
|
113
|
+
- lib/graphsrb/adjacency_list.rb
|
114
|
+
- lib/graphsrb/base_graph.rb
|
115
|
+
- lib/graphsrb/diedge.rb
|
116
|
+
- lib/graphsrb/digraph.rb
|
117
|
+
- lib/graphsrb/edge.rb
|
118
|
+
- lib/graphsrb/exceptions.rb
|
119
|
+
- lib/graphsrb/graph.rb
|
120
|
+
- lib/graphsrb/node.rb
|
121
|
+
- lib/graphsrb/version.rb
|
122
|
+
- lib/graphsrb/vertex.rb
|
123
|
+
homepage: https://github.com/fade2black/graphsrb
|
124
|
+
licenses:
|
125
|
+
- MIT
|
126
|
+
metadata:
|
127
|
+
allowed_push_host: https://rubygems.org
|
128
|
+
post_install_message:
|
129
|
+
rdoc_options: []
|
130
|
+
require_paths:
|
131
|
+
- lib
|
132
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
133
|
+
requirements:
|
134
|
+
- - ">="
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '0'
|
137
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
138
|
+
requirements:
|
139
|
+
- - ">="
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
requirements: []
|
143
|
+
rubyforge_project:
|
144
|
+
rubygems_version: 2.7.7
|
145
|
+
signing_key:
|
146
|
+
specification_version: 4
|
147
|
+
summary: This gem allows to create simple directed and undirected graphs. Basic operations
|
148
|
+
allows easily implement graph algorithms
|
149
|
+
test_files: []
|