bipartite_graph_sets 0.0.1
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/lib/bipartite_graph.rb +73 -0
- data/lib/bipartite_graph_sets.rb +38 -0
- metadata +46 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b6a4aeab824e381cd2bbf826c8d4ea741905799e75536cd5673331efc6cfdf7a
|
4
|
+
data.tar.gz: 4c6bada9a2c85808fdb64132e4a07b987f8b574f15bb922d6bd4988d60610d2f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d93bfefe1d1e0ce09c22554118243999dd707eb8fd499e0bd06f91f01d4ba37e400e0d107f2c2113158e80e7e40d76cb535b2e7abf1e5a1cf2136e8e48fd3eed
|
7
|
+
data.tar.gz: c06cc9b465274540a8238480375dc684f90b6ef7001e2eb7365a84ed795aca583ae2a539c93063a98255a37443c5e2dc5b4bf09a4bb3cbe7ce03ed2298d1e991
|
@@ -0,0 +1,73 @@
|
|
1
|
+
class BipartiteGraph
|
2
|
+
|
3
|
+
def self.match(left_vertices, right_vertices, edges)
|
4
|
+
vertices = left_vertices + right_vertices + [:sink, :source]
|
5
|
+
edges[:sink] = {}
|
6
|
+
edges[:source] = {}
|
7
|
+
|
8
|
+
left_vertices.each do |left_vertice|
|
9
|
+
edges[:source][left_vertice] = 0
|
10
|
+
end
|
11
|
+
right_vertices.each do |right_vertice|
|
12
|
+
edges[right_vertice] = { sink: 0 }
|
13
|
+
end
|
14
|
+
graph = { vertices: vertices, edges: edges }
|
15
|
+
matching = graph_matching! graph
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.graph_matching!(graph, source = :source, sink = :sink)
|
19
|
+
loop do
|
20
|
+
path = get_augmenting_path graph
|
21
|
+
break unless path
|
22
|
+
create_augment_flow graph, path
|
23
|
+
end
|
24
|
+
matching_in graph, source, sink
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.get_augmenting_path(graph, source = :source, sink = :sink)
|
28
|
+
parents = search graph, source, sink
|
29
|
+
return nil unless parents[sink]
|
30
|
+
path = []
|
31
|
+
current_vertex = sink
|
32
|
+
until current_vertex == source
|
33
|
+
path << [parents[current_vertex], current_vertex]
|
34
|
+
current_vertex = parents[current_vertex]
|
35
|
+
|
36
|
+
if path.length > parents.length
|
37
|
+
raise "Cannot terminate. Use integral edge weights."
|
38
|
+
end
|
39
|
+
end
|
40
|
+
path.reverse!
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.create_augment_flow (graph, path)
|
44
|
+
edges = graph[:edges]
|
45
|
+
path.each do |u, v|
|
46
|
+
edges[v] ||= {}
|
47
|
+
edges[v][u] = -edges[u][v]
|
48
|
+
edges[u].delete v
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.search(graph, source = :source, sink = :sink)
|
53
|
+
parents = { source => true }
|
54
|
+
queue = [source]
|
55
|
+
until queue.empty?
|
56
|
+
current_vertex = queue.shift
|
57
|
+
break if current_vertex == sink
|
58
|
+
(graph[:edges][current_vertex] || {}).each do |new_vertex, edge|
|
59
|
+
next if parents[new_vertex]
|
60
|
+
parents[new_vertex] = current_vertex
|
61
|
+
queue << new_vertex
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
parents
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.matching_in(graph, source = :source, sink = :sink)
|
69
|
+
Hash[*((graph[:edges][sink] || {}).keys.map { |matched_vertex|
|
70
|
+
[graph[:edges][matched_vertex].keys.first, matched_vertex]
|
71
|
+
}.flatten)]
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require_relative 'bipartite_graph'
|
2
|
+
|
3
|
+
class BipartiteGraphSets
|
4
|
+
|
5
|
+
def self.get_perfect_match requirement_hash
|
6
|
+
left_vertices, right_vertices, edges = get_vertices_and_edges requirement_hash
|
7
|
+
problem_set_matching = BipartiteGraph.match left_vertices, right_vertices, edges
|
8
|
+
matched_solution problem_set_matching
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.get_vertices_and_edges requirement_hash
|
12
|
+
left_vertices = []
|
13
|
+
right_vertices = []
|
14
|
+
edges = {}
|
15
|
+
requirement_hash.each do |key, value|
|
16
|
+
left_vertices << value[:options]
|
17
|
+
value[:options].each do |v|
|
18
|
+
edges[v] ||= {}
|
19
|
+
(1..value[:selection]).each do |n|
|
20
|
+
key_name = "#{key}_#{n}"
|
21
|
+
right_vertices << key_name
|
22
|
+
edges[v][key_name] = 0
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
[ left_vertices.flatten.uniq.shuffle, right_vertices.flatten.uniq.shuffle, edges ]
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.matched_solution problem_set_matching
|
30
|
+
solution_hash = {}
|
31
|
+
problem_set_matching.to_h.each do |k,v|
|
32
|
+
key = v.to_s.split('_').first
|
33
|
+
solution_hash[key] ||= []
|
34
|
+
solution_hash[key] << k
|
35
|
+
end
|
36
|
+
solution_hash
|
37
|
+
end
|
38
|
+
end
|
metadata
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bipartite_graph_sets
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Raghvendra Pratap Singh
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-12-06 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Job assignment problem with the help of bipartite graph
|
14
|
+
email: raghvendra1501@gmail.com
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- lib/bipartite_graph.rb
|
20
|
+
- lib/bipartite_graph_sets.rb
|
21
|
+
homepage: https://rubygems.org/gems/bipartite_graph_sets
|
22
|
+
licenses:
|
23
|
+
- MIT
|
24
|
+
metadata:
|
25
|
+
source_code_uri: https://github.com/raghvendra1501/bipartite_graph_sets
|
26
|
+
post_install_message:
|
27
|
+
rdoc_options: []
|
28
|
+
require_paths:
|
29
|
+
- lib
|
30
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
requirements: []
|
41
|
+
rubyforge_project:
|
42
|
+
rubygems_version: 2.7.7
|
43
|
+
signing_key:
|
44
|
+
specification_version: 4
|
45
|
+
summary: Job assignment problem with the help of bipartite graph
|
46
|
+
test_files: []
|