graphmatcher 0.4.0 → 0.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 825a8f82e234efc81b2de40f274f2dd60619bdaa797e65c303675a1b5a3c2a69
4
- data.tar.gz: f9e114404851c37c7cd3bfefc84fe04ec8e3e11c63d21c7dd695ebff1a02e959
3
+ metadata.gz: ac93435628f298d6ea79c76d0c0f56f21167dc958afd7837636c9de53ad5bfb9
4
+ data.tar.gz: 4d91ff69d4f2c0ddf8eaec29b3ff84d4453ed6d8b47613e1da77a42c1399665d
5
5
  SHA512:
6
- metadata.gz: 37ff3e5e04a316849cb1f343b5f701b082a49a2582626cafa2ac51f88c9bb72bb0a04bec352833b1725abda7eb970f822688a2da538fa63b352c571fadd1fb65
7
- data.tar.gz: 2d181382e180ca3cb8c888f1ce55db75cdfd8c2d27c1c8dfbccff3304bb0814c25f31514b9e36841509412d2e59b87bc96739b3b91f61b68ec71f482e07204de
6
+ metadata.gz: f60980782fd68a0b41ab83878c3b193d384a85fc780d61910b72a3cc3d41d91fbb657bb2fcccb432f00cd53bfc175b516b061abf6fe4ba809bccb4be2b186552
7
+ data.tar.gz: 3bed6339341e5fc3034d5876288e7b1cbe75a3a09acc108f3c60979ffb1e2c2331c4c9e11a0f4003ea997e6e1bf2162d1cd866d533a59d9891437b772089851b
data/lib/graphmatcher.rb CHANGED
@@ -1,8 +1,9 @@
1
1
  require 'logger'
2
+ require_relative 'graphmatcher_vf2pp'
2
3
  #require 'ruby-prof'
3
4
  class Graphmatcher
4
5
 
5
- VERSION = "0.4.0"
6
+ VERSION = "0.4.1"
6
7
 
7
8
  @@logger = Logger.new(STDOUT)
8
9
  @@logger.level = Logger::INFO
@@ -34,7 +34,7 @@ require 'set'
34
34
  # the original Graphmatcher, but — unlike it — also works on cyclic queries.)
35
35
  class GraphmatcherVF2pp
36
36
 
37
- VERSION = "0.1.0".freeze
37
+ VERSION = "0.4.1".freeze
38
38
 
39
39
  @@logger = Logger.new(STDOUT)
40
40
  @@logger.level = Logger::INFO
@@ -44,11 +44,15 @@ class GraphmatcherVF2pp
44
44
  end
45
45
 
46
46
  def initialize(args)
47
- @query_graph = args[:query].to_a
48
- @data_graph = args[:data].to_a
47
+ # Accept both the native keys (:query/:data) and the schedy worker's
48
+ # keys (:query_graph/:data_graph). :cost_matrix is optional and only
49
+ # consumed by find_matches.
50
+ @query_graph = (args[:query] || args[:query_graph]).to_a
51
+ @data_graph = (args[:data] || args[:data_graph]).to_a
49
52
  @limit = args[:limit].to_i
50
53
  @max_allowed_time = args[:max_allowed_time].to_f
51
54
  @self_loops = args[:self_loops]
55
+ @cost_matrix = args[:cost_matrix]
52
56
  validate!
53
57
 
54
58
  @q_adj = @query_graph[0]
@@ -90,8 +94,50 @@ class GraphmatcherVF2pp
90
94
  @matches
91
95
  end
92
96
 
97
+ # Cost-aware matching used by the schedy worker's Resource.estimate.
98
+ #
99
+ # Requires a :cost_matrix (passed at construction) laid out as
100
+ # cost_matrix[data_index][query_index] => Numeric
101
+ # i.e. the cost of assigning data vertex `data_index` to query vertex
102
+ # (role) `query_index`. This matches Resource.estimate_costs, which uses a
103
+ # large sentinel (360000) for incompatible pairs.
104
+ #
105
+ # Returns an Array of plans. Each plan has one [data_index, cost] pair per
106
+ # query vertex, in query-vertex order (NOT matching order):
107
+ # [[d0, c0], [d1, c1], ..., [dn, cn]]
108
+ # where ci = cost_matrix[di][i]. The caller computes a plan's cost as the
109
+ # maximum (bottleneck) of the per-node costs and filters/sorts on it, so
110
+ # this method returns every structural match annotated with cost and leaves
111
+ # the cost thresholding to the caller.
112
+ def find_matches
113
+ raise ArgumentError, "find_matches requires :cost_matrix" if @cost_matrix.nil?
114
+
115
+ getMatches.map do |phi|
116
+ phi.each_index.map do |query_index|
117
+ data_index = phi[query_index].first
118
+ [data_index, cost_for(data_index, query_index)]
119
+ end
120
+ end
121
+ end
122
+
93
123
  private
94
124
 
125
+ # Look up cost_matrix[data_index][query_index], tolerating either Hash-of-Hash
126
+ # (as built by Resource.estimate_costs) or Array-of-Array layouts. Missing
127
+ # entries fall back to the incompatibility sentinel so the caller's
128
+ # bottleneck filter discards them.
129
+ INCOMPATIBLE_COST = 360000
130
+
131
+ def cost_for(data_index, query_index)
132
+ return INCOMPATIBLE_COST if data_index.nil?
133
+ row = @cost_matrix[data_index]
134
+ return INCOMPATIBLE_COST if row.nil?
135
+ value = row[query_index]
136
+ value.nil? ? INCOMPATIBLE_COST : value
137
+ end
138
+
139
+ public
140
+
95
141
  def timed_out?
96
142
  @max_allowed_time > 0 && (Time.now.to_f - @t0) > @max_allowed_time
97
143
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphmatcher
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Emre Unlu