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.
@@ -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: []