Skip to content

Commit 2246c57

Browse files
Implement signal isomorphic matching
1 parent 5bcc7f3 commit 2246c57

File tree

1 file changed

+34
-4
lines changed

1 file changed

+34
-4
lines changed

yaramo/operations/compare.py

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import networkx as nx
55

6-
from ..model import DbrefGeoNode, Edge, GeoNode, Node, Signal, Topology, Wgs84GeoNode
6+
from ..model import DbrefGeoNode, Edge, GeoNode, Node, Signal, Topology, Wgs84GeoNode, SignalDirection
77

88

99
class CompareMatching:
@@ -114,7 +114,7 @@ def __add_edges_to_matching(__edge_a: Edge, __edge_b: Edge):
114114
for node_a, node_b in given_node_matching.items():
115115
__add_to_open_nodes(node_a, node_b)
116116

117-
# bfs at start nodes to generate matching
117+
# node and edge matching with a bfs
118118
while open_nodes:
119119
current_tuple = open_nodes.pop(0)
120120
node_a = current_tuple[0]
@@ -130,7 +130,6 @@ def __add_edges_to_matching(__edge_a: Edge, __edge_b: Edge):
130130

131131
__add_to_open_nodes(node_a.connected_on_head, node_b.connected_on_head)
132132
__add_edges_to_matching(node_a.connected_edge_on_head, node_b.connected_edge_on_head)
133-
# signals in order per direction
134133
if node_a.is_point():
135134
__add_to_open_nodes(node_a.connected_on_left, node_b.connected_on_left)
136135
__add_edges_to_matching(node_a.connected_edge_on_left, node_b.connected_edge_on_left)
@@ -139,6 +138,37 @@ def __add_edges_to_matching(__edge_a: Edge, __edge_b: Edge):
139138
)
140139
__add_edges_to_matching(node_a.connected_edge_on_right, node_b.connected_edge_on_right)
141140

141+
def __add_signal_lists_to_matching(signal_list_a: List[Signal], signal_list_b: List[Signal]):
142+
for i in range(0, len(signal_list_a)):
143+
signal_a = signal_list_a[i]
144+
signal_b = signal_list_b[i]
145+
result.signal_matching.element_matching[signal_a] = signal_b
146+
147+
# signal matching
148+
for edge_a in topology_a.edges.values():
149+
edge_b = result.edge_matching.element_matching[edge_a]
150+
if not edge_a.signals and not edge_b.signals:
151+
continue
152+
if not edge_a.signals or not edge_b.signals:
153+
raise ValueError(f"Signals on edges {edge_a.uuid} and {edge_b.uuid} does not match")
154+
in_direction_a = [signal for signal in edge_a.signals if signal.direction == SignalDirection.IN]
155+
in_direction_a.sort(key=lambda signal: signal.distance_edge)
156+
other_direction_a = [signal for signal in edge_a.signals if signal.direction == SignalDirection.GEGEN]
157+
other_direction_a.sort(key=lambda signal: signal.distance_edge)
158+
in_direction_b = [signal for signal in edge_b.signals if signal.direction == SignalDirection.IN]
159+
in_direction_b.sort(key=lambda signal: signal.distance_edge)
160+
other_direction_b = [signal for signal in edge_b.signals if signal.direction == SignalDirection.GEGEN]
161+
other_direction_b.sort(key=lambda signal: signal.distance_edge)
162+
163+
if result.node_matching.element_matching[edge_a.node_a] != edge_b.node_a:
164+
# edge b is reversed, so switch lists
165+
in_direction_b, other_direction_b = list(reversed(other_direction_b)), list(reversed(in_direction_b))
166+
167+
if len(in_direction_a) != len(in_direction_b) or len(other_direction_a) != len(other_direction_b):
168+
raise ValueError(f"Number of signals on edges {edge_a.uuid} and {edge_b.uuid} differs (per direction)")
169+
__add_signal_lists_to_matching(in_direction_a, in_direction_b)
170+
__add_signal_lists_to_matching(other_direction_a, other_direction_b)
171+
142172
@staticmethod
143173
def _are_topologies_isomorphic(topology_a: Topology, topology_b: Topology):
144174
if len(topology_a.nodes) != len(topology_b.nodes) or len(topology_a.edges) != len(
@@ -171,7 +201,7 @@ def _calc_distance_for_matching(matching: CompareMatching, exclude_ends_in_calcu
171201
distance_sum += abs(element_a.length - element_b.length)
172202
elif element_type == "signal":
173203
x_a, y_a = element_a.get_calculated_coordinates()
174-
x_b, y_b = element_a.get_calculated_coordinates()
204+
x_b, y_b = element_b.get_calculated_coordinates()
175205
distance_sum += DbrefGeoNode(x_a, y_a).get_distance_to_other_geo_node(DbrefGeoNode(x_b, y_b))
176206

177207
return distance_sum

0 commit comments

Comments
 (0)