def split_edge(edge, locations): """ Split edge by a list of locations. Insert an ad hoc node at each location and return a list of inserted ad hoc nodes and corresponding edges. """ # Attach indexes so we can recover the original order later idx_locations = list(enumerate(locations)) idx_locations.sort(key=lambda t: t[1]) idx_node_edges = [] forward_edge = edge prev_loc = 0 for idx, loc in idx_locations: assert 0 <= loc <= 1 and prev_loc <= loc if loc == 0: middle_node = edge.start_node backward_edge = None # The forward edge keeps unchanged elif loc == 1: middle_node = edge.end_node backward_edge = forward_edge forward_edge = None else: middle_node = AdHocNode(edge_id=edge.id, location=loc) edge_proportion = loc - prev_loc backward_edge = Edge(id=forward_edge.id, start_node=forward_edge.start_node, end_node=middle_node, cost=edge_proportion * edge.cost, reverse_cost=edge_proportion * edge.reverse_cost, reversed=edge.reversed) forward_edge = Edge(id=forward_edge.id, start_node=middle_node, end_node=forward_edge.end_node, cost=forward_edge.cost - backward_edge.cost, reverse_cost=forward_edge.reverse_cost - backward_edge.reverse_cost, reversed=edge.reversed) if idx_node_edges: idx_node_edges[-1][-1] = backward_edge # The forward edge will be replaced in the next iteration. See above line idx_node_edges.append([idx, middle_node, backward_edge, forward_edge]) prev_loc = loc # Sort by index, so each node is corresponding to its location in # the location list idx_node_edges.sort() # Drop the indexes return [(n, b, f) for _, n, b, f in idx_node_edges]
def query_edges_in_sequence_bbox(conn, road_table_name, sequence, search_radius): """ Query all road edges within the bounding box of the sequence expanded by search_radius. """ if not sequence: return subquery = create_sequence_subquery(len(sequence), ('lon', 'lat')) stmt = subquery + ''' -- NOTE the length unit is in km SELECT edge.gid, edge.source, edge.target, edge.length * 1000, edge.length * 1000 FROM {road_table_name} AS edge CROSS JOIN (SELECT ST_Extent(ST_MakePoint(sequence.lon, sequence.lat))::geometry AS extent FROM sequence) AS extent WHERE edge.the_geom && ST_Envelope(ST_Buffer(extent.extent::geography, %s)::geometry) '''.format(road_table_name=road_table_name) # Aggregate and flatten params params = sum([[lon, lat] for lon, lat in sequence], []) params.append(search_radius) cur = conn.cursor() cur.execute(stmt, params) for gid, source, target, cost, reverse_cost in cur.fetchall(): edge = Edge(id=gid, start_node=source, end_node=target, cost=cost, reverse_cost=reverse_cost) yield edge cur.close()
def parse_cell(self, cell_str: str) -> Tuple[List[Node], List[Edge]]: # remove leading and trailing bars | if cell_str[0] == "|": cell_str: str = cell_str[1:] if cell_str[-1] == "|": cell_str = cell_str[:-1] nodes: Set[Node] = set() edges: Set[Edge] = set() # e.g. # |nor_conv_3x3~0|+|nor_conv_3x3~0|avg_pool_3x3~1|+|skip_connect~0|nor_conv_3x3~1|skip_connect~2| for i, node in enumerate(cell_str.split("|+|")): node_id: int = i + 1 # e.g. # skip_connect~0|nor_conv_3x3~1|skip_connect~2| for op_str in node.split("|"): # e.g. # skip_connect~0 nodes.add(Node(f"{node_id}")) op_name: str = [ self.pretty_names[o] for o in self.OPS if o in op_str ][0] connected_from: list = re.findall("~[0-9]", op_str) if len(connected_from) > 0: connected_from = connected_from[0][1:] edges.add(Edge(f"{connected_from}", f"{node_id}", op_name)) return list(nodes), list(edges)
def build_edge(head, tail, type): if (head, tail, type) not in edges_dict: id = len(edges) edges_dict[(head, tail, type)] = id inter_text = '' edge = Edge(head, tail, type, inter_text, 1, '') edges.append(edge) else: id = edges_dict[(head, tail, type)] edges[id] = edges[id]._replace(count=edges[id].count + 1) return id
def getGraphFromJson(jsonStructure): # obtain all edges edgesList = [] for edgeStructure in jsonStructure["edges"]: edgesList.append( Edge.Edge( EdgeInfo.EdgeInfo(edgeStructure["edgeID"], edgeStructure["formEdgeID"]), edgeStructure["toID"])) # obtain all Nodes nodesList = [] for nodeStructure in jsonStructure["nodes"]: # type "L" nodes should be ignored # they are accessory nodes indicating the origin (web address) of the node content if nodeStructure["type"] != "L": nodeID = nodeStructure["nodeID"] adjEdges = [] # get all edges from current node for edgeStructure in jsonStructure["edges"]: if edgeStructure["fromID"] == nodeID: currentEdgeId = edgeStructure["edgeID"] # get edge object for e in edgesList: if e.getEdgeInfo().getEdgeId() == currentEdgeId: adjEdges.append(e) break # obtain scheme attribute (if exists) schemeValue = None if nodeStructure.get("scheme") is not None: schemeValue = nodeStructure["scheme"] schemeIDValue = None if nodeStructure.get("schemeID") is not None: schemeIDValue = nodeStructure["schemeID"] nodesList.append( Node.Node( NodeInfo.NodeInfo(nodeID, nodeStructure["text"].encode('utf8'), nodeStructure["type"], nodeStructure["timestamp"], schemeValue, schemeIDValue), adjEdges)) return Graph.Graph(nodesList)
def getGraphFromBratAnnotationFile(self, currentFileName): # obtain all edges tuples, where # first element of the tuple is the Edge object # second element if the from id of the corresponding edge (will be added to the corresponding Node's below) edgesList = [] with open(paths["AAECCorpus"] + "/" + currentFileName + ".ann", 'r') as annotationFile: for line in annotationFile: splittedLine = line.split("\t") if splittedLine[0][0] == "R": # Line contains a relation (edge) currentEdgeId = splittedLine[0] edgeType = splittedLine[1].split(" ")[0] currentEdgeSourceNodeId = ( splittedLine[1].split(" ")[1]).split(":")[1] currentEdgeTargetNodeId = ( splittedLine[1].split(" ")[2]).split(":")[1] newEdgeInfo = EdgeInfo.EdgeInfo(currentEdgeId, edgeType) edgesList.append((Edge.Edge(newEdgeInfo, currentEdgeTargetNodeId), currentEdgeSourceNodeId)) # obtain all Nodes nodesList = [] with open(paths["AAECCorpus"] + "/" + currentFileName + ".ann", 'r', encoding='utf-8') as annotationFile: for line in annotationFile: splittedLine = line.split("\t") if splittedLine[0][0] == "T": # Line contains a node adjEdges = [ edgeTuple[0] for edgeTuple in edgesList if edgeTuple[1] == splittedLine[0] ] nodesList.append( Node.Node( NodeInfo.NodeInfo(splittedLine[0], splittedLine[2], splittedLine[1].split(" ")[0], None, None, None), adjEdges)) return Graph.Graph(nodesList)
def __init__(self, base_path, hparams): self._hparams = hparams self.nodes = [] lines = open(os.path.join(base_path, 'nodes.tsv')).read().splitlines()[1:] for i in tqdm.tqdm(range(len(lines))): l = lines[i].split('\t') l = [ t if Node._field_types[Node._fields[i]] is str else json.loads(t) for i, t in enumerate(l) ] l[3] = [EntityMention(*e) for e in l[3]] n = Node(*l) self.nodes.append(n) self.edges = [] self._graph = defaultdict(dict) lines = open(os.path.join(base_path, 'edges.tsv')).read().splitlines()[1:] for i in tqdm.tqdm(range(len(lines))): l = lines[i].split('\t') l = [ t if Edge._field_types[Edge._fields[i]] is str else json.loads(t) for i, t in enumerate(l) ] e = Edge(*l) self.edges.append(e) self._graph[(e.head_id, e.tail_id)][e.label] = i self.skeletons = [] lines = open(os.path.join(base_path, 'skeletons.tsv')).read().splitlines() for i in tqdm.tqdm(range(len(lines))): l = lines[i].split('\t') l = [ t if Skeleton._field_types[Skeleton._fields[i]] is str else json.loads(t) for i, t in enumerate(l) ] s = Skeleton(*l) self.skeletons.append(s) logging.info('KG built, with %d nodes, %d edges, %d skeletons' % (len(self.nodes), len(self.edges), len(self.skeletons)))
def isInsideGeoFence(self): # here observer is static, once class is initialized can not be changed crossingNumber = 0 fromPoint = self.pointList[0] for point in self.pointList[1:]: if(self.isEdgeHorizontal(fromPoint, point)): # do nothing because edhe is horizontal to x axis # update the from point and go to next fromPoint = point else: if(self.hasRightSideRayIntersection(Edge(fromPoint, point), self.observer)): crossingNumber += 1 fromPoint = point else: fromPoint = point if(crossingNumber % 2 == 0): return False else: return True
def isInsideGeoFenceWithObserver(self, observer): # user can check geo-fence breach for specific observer crossingNumber = 0 fromPoint = self.pointList[0] for point in self.pointList[1:]: if(self.isEdgeHorizontal(fromPoint, point)): # do nothing because edhe is horizontal to x axis # update the from point and go to next fromPoint = point else: if(self.hasRightSideRayIntersection(Edge(fromPoint, point), observer)): crossingNumber += 1 fromPoint = point else: fromPoint = point if(crossingNumber % 2 == 0): return False else: return True
def query_candidates(conn, road_table_name, sequence, search_radius): """ Query candidates of each measurement in a sequence within search_radius. """ subquery = create_sequence_subquery(len(sequence), ('id', 'lon', 'lat')) subquery = subquery + ',' + ''' --- WITH sequence AS (subquery here), seq AS (SELECT *, ST_SetSRID(ST_MakePoint(sequence.lon, sequence.lat), 4326) AS geom, ST_SetSRID(ST_MakePoint(sequence.lon, sequence.lat), 4326)::geography AS geog FROM sequence) ''' stmt = subquery + ''' SELECT seq.id, seq.lon, seq.lat, --- Edge information edge.gid, edge.source, edge.target, edge.length, edge.length, --- Location, a float between 0 and 1 representing the location of the closest point on the edge to the measurement. ST_LineLocatePoint(edge.the_geom, seq.geom) AS location, --- Distance in meters from the measurement to its candidate's location ST_Distance(seq.geog, edge.the_geom::geography) AS distance, --- Candidate's location (a position along the edge) ST_X(ST_ClosestPoint(edge.the_geom, seq.geom)) AS clon, ST_Y(ST_ClosestPoint(edge.the_geom, seq.geom)) AS clat FROM seq CROSS JOIN {road_table_name} AS edge WHERE edge.the_geom && ST_Envelope(ST_Buffer(seq.geog, %s)::geometry) AND ST_DWithin(seq.geog, edge.the_geom::geography, %s) '''.format(road_table_name=road_table_name) # Aggregate and flatten params params = sum([[idx, lon, lat] for idx, (lon, lat) in enumerate(sequence)], []) params.append(search_radius) params.append(search_radius) cur = conn.cursor() cur.execute(stmt, params) for mid, mlon, mlat, \ eid, source, target, cost, reverse_cost, \ location, distance, \ clon, clat in cur: measurement = Measurement(id=mid, lon=mlon, lat=mlat) edge = Edge(id=eid, start_node=source, end_node=target, cost=cost, reverse_cost=reverse_cost) assert 0 <= location <= 1 candidate = Candidate(measurement=measurement, edge=edge, location=location, distance=distance) # Coordinate along the edge (not needed by MM but might be # useful info to users) candidate.lon = clon candidate.lat = clat yield candidate cur.close()
targets = set() # parse puzzle input into a graph for line in puzzle_input: program_name = line.split()[0] programs.add(program_name) weight = get_numbers(line)[0] n = get_or_create_node(program_name, weight) if '-> ' not in line: continue sline = line.split('-> ')[1].split(', ') for p in sline: child_node = get_or_create_node(p) e = Edge(n,child_node) g.add_edge(e) targets.add(p) # start at the bottom until we find the first node that isn't misbalanced # to balance everything out, we have to change the parent node of this node bottom = programs.difference(targets).pop() current_node = get_or_create_node(bottom) balancer = None print('Part 1:', bottom) while current_node is not None: wrong_part = {}
from utils import Node, Edge from utils.graph import build_graph from utils.hetio import NODES_CHECKPOINT as HETIO_NODES_CHECKPOINT, EDGES_CHECKPOINT as HETIO_EDGE_CHECKPOINT from utils.logger import log if __name__ == "__main__": nodes = Node.deserialize_bunch(HETIO_NODES_CHECKPOINT) edges = Edge.deserialize_bunch(HETIO_EDGE_CHECKPOINT) log.info("Building graph...") graph = build_graph(nodes, edges) log.info("Finished building graph.")
def test_split_edge(): import functools same_edge_p = functools.partial(Edge.same_edge, precision=0.0000001) edge = Edge(id=1, start_node=2, end_node=10, cost=100, reverse_cost=1000) # It should simply do it right adhoc_node_edges = split_edge(edge, [0.5]) assert len(adhoc_node_edges) == 1 n, b, f = adhoc_node_edges[0] assert n == AdHocNode(edge_id=edge.id, location= 0.5) assert same_edge_p(b, Edge(id=edge.id, start_node=edge.start_node, end_node=n, cost=edge.cost * 0.5, reverse_cost=edge.reverse_cost * 0.5)) assert same_edge_p(f, Edge(id=edge.id, start_node=n, end_node=10, cost=edge.cost * 0.5, reverse_cost=edge.reverse_cost * 0.5)) assert not b.reversed and not f.reversed # It should split reversed edge redge = edge.reversed_edge() adhoc_node_edges = split_edge(redge, [0.5]) n, b, f = adhoc_node_edges[0] assert b.reversed and f.reversed # It should split the edge by 2 locations adhoc_node_edges = split_edge(edge, [0.5, 0.4]) assert len(adhoc_node_edges) == 2 (n2, b2, f2), (n1, b1, f1) = adhoc_node_edges assert same_edge_p(b1, Edge(id=edge.id, start_node=edge.start_node, end_node=n1, cost=edge.cost * 0.4, reverse_cost=edge.reverse_cost * 0.4)) assert same_edge_p(f1, Edge(id=edge.id, start_node=n1, end_node=n2, cost=edge.cost * 0.1, reverse_cost=edge.reverse_cost * 0.1)) assert b2 == f1 assert same_edge_p(f2, Edge(id=edge.id, start_node=n2, end_node=edge.end_node, cost=edge.cost * 0.5, reverse_cost=edge.reverse_cost * 0.5)) # It should split the edge at starting location adhoc_node_edges = split_edge(edge, [0]) assert len(adhoc_node_edges) == 1 n, b, f = adhoc_node_edges[0] assert n == edge.start_node assert b is None assert f == edge # It should split the edge at ending location adhoc_node_edges = split_edge(edge, [1]) assert len(adhoc_node_edges) == 1 n, b, f = adhoc_node_edges[0] assert n == edge.end_node assert b == edge assert f is None # It should do all right adhoc_node_edges = split_edge(edge, [1, 0.4, 0, 0.4, 0, 0.5]) assert len(adhoc_node_edges) == 6 # Do this because Python gurantees stable sort n0, b0, f0 = adhoc_node_edges[2] n1, b1, f1 = adhoc_node_edges[4] n2, b2, f2 = adhoc_node_edges[1] n3, b3, f3 = adhoc_node_edges[3] n4, b4, f4 = adhoc_node_edges[5] n5, b5, f5 = adhoc_node_edges[0] assert n0 == edge.start_node and b0 is None and f0 is None assert n1 == edge.start_node and b1 is None assert same_edge_p(f1, Edge(id=edge.id, start_node=n1, end_node=n2, cost=edge.cost * 0.4, reverse_cost=edge.reverse_cost * 0.4)) assert isinstance(n2, AdHocNode) assert b2 == f1 assert same_edge_p(f2, Edge(id=edge.id, start_node=n2, end_node=n3, cost=0, reverse_cost=0)) assert isinstance(n3, AdHocNode) assert b3 == f2 assert same_edge_p(f3, Edge(id=edge.id, start_node=n3, end_node=n4, cost=edge.cost * 0.1, reverse_cost=edge.reverse_cost * 0.1)) assert isinstance(n4, AdHocNode) assert b4 == f3 assert same_edge_p(f4, Edge(id=edge.id, start_node=n4, end_node=n5, cost=edge.cost * 0.5, reverse_cost=edge.reverse_cost * 0.5)) assert n5 == edge.end_node assert b5 == f4 assert f5 is None
def test_road_network_route(): # The example from http://en.wikipedia.org/wiki/Dijkstra's_algorithm e12 = Edge('12', 1, 2, 7, 7) e13 = Edge('13', 1, 3, 9, 9) e16 = Edge('16', 1, 6, 14, 14) e23 = Edge('23', 2, 3, 10, 10) e24 = Edge('24', 2, 4, 15, 15) e34 = Edge('34', 3, 4, 11, 11) e36 = Edge('36', 3, 6, 2, 2) e45 = Edge('45', 4, 5, 6, 6) e56 = Edge('56', 5, 6, 9, 9) # Extra isolated edge e89 = Edge('89', 8, 9, 2, 1000) ecircle = Edge('cc', 'c', 'c', 100000, 1) edges = (e12, e13, e16, e23, e24, e34, e36, e45, e56, e89) road_network = { 1: (e12, e13, e16), 2: (e12.reversed_edge(), e23, e24), 3: (e13.reversed_edge(), e23.reversed_edge(), e34, e36), 4: (e24.reversed_edge(), e34.reversed_edge(), e45), 5: (e45.reversed_edge(), e56), 6: (e16.reversed_edge(), e36.reversed_edge(), e56.reversed_edge()), # Extra isolated edges 8: (e89, ), 9: (e89.reversed_edge(),)} def _get_edges(node): return road_network.get(node, []) _AHN = collections.namedtuple('AdhocNodeForTest', 'edge_id, location, reversed') def _assert_path(path, nodes): if path or nodes: assert len(nodes) == len(path) + 1, 'count not matched' else: return path = reversed(path) nodes = iter(nodes) last_edge = None for edge in path: node = next(nodes) if isinstance(node, _AHN): assert node.edge_id == edge.id assert node.location == edge.start_node.location assert node.reversed == edge.reversed else: assert node == edge.start_node if last_edge: assert last_edge.end_node == edge.start_node last_edge = edge # Last node node = next(nodes) if isinstance(node, _AHN): assert node.edge_id == edge.id assert node.location == edge.end_node.location assert node.reversed == edge.reversed else: assert node == edge.end_node # It should route between 2 locations at different edges path, cost = road_network_route((e13, 0.5), (e56, 0.5), _get_edges) _assert_path(path, [_AHN('13', 0.5, False), 3, 6, _AHN('56', 0.5, True)]) assert abs(cost - 11) <= 0.000001 # It should route between 2 locations at the same edge path, cost = road_network_route((e13, 0.1), (e13, 0.9), _get_edges) _assert_path(path, [_AHN('13', 0.1, False), _AHN('13', 0.9, False)]) assert abs(cost - 9 * 0.8) <= 0.000001 # It should route between 2 locations at a circle edge (start node == end node) in a reverse way path1, cost1 = road_network_route((ecircle, 0.2), (ecircle, 0.7), _get_edges) path2, cost2 = road_network_route((ecircle, 0.2), (ecircle.reversed_edge(), 0.3), _get_edges) assert path1 == path2 and cost1 == cost2 _assert_path(path1, [_AHN('cc', 0.2, True), 'c', _AHN('cc', 0.7, True)]) assert abs(cost1 - 0.5) <= 0.0000001 # It should give 0 cost if source and target are same location path, cost = road_network_route((e13, 0.1), (e13.reversed_edge(), 0.9), _get_edges) _assert_path(path, [_AHN('13', 0.1, True), _AHN('13', 1 - 0.9, True)]) assert abs(cost) <= 0.000001 assert cost == path[0].cost # It should route for locations at intersections path, cost = road_network_route((e13, 0), (e13, 1), _get_edges) _assert_path(path, [1, 3]) assert path[0] == e13 assert cost == e13.cost # It should not find a path from nose.tools import assert_raises assert_raises(sp.PathNotFound, road_network_route, (e13, 0.2), (e24, 0.9), _get_edges, 10) assert_raises(sp.PathNotFound, road_network_route, (e13, 0), (e89, 0.5), _get_edges) assert_raises(sp.PathNotFound, road_network_route, (e89, 0.9), (e89, 0.2), _get_edges, 10) # It should return multiple paths targets = [(e16, 0.6), (e13, 0.3), (e34, 0.5), (e56, 1)] results = road_network_route_many((e16, 0.1), targets, _get_edges) path, cost = results[0] assert abs(cost - 7) < 0.000001 _assert_path(path, [_AHN('16', 0.1, False), _AHN('16', 0.6, False)]) path, cost = results[1] assert abs(cost - 4.1) < 0.000001 _assert_path(path, [_AHN('16', 0.1, True), 1, _AHN('13', 0.3, False)]) path, cost = results[2] assert abs(cost - 15.9) < 0.000001 _assert_path(path, [_AHN('16', 0.1, True), 1, 3, _AHN('34', 0.5, False)]) path, cost = results[3] assert abs(cost - 12.4) < 0.000001 _assert_path(path, [_AHN('16', 0.1, True), 1, 3, 6]) # It should find paths when multiple targets are on the same edge with the source targets = [(e16, 0.2), (e16, 0.4), (e16, 1), (e16, 0)] results = road_network_route_many((e16, 0.8), targets, _get_edges) path, cost = results[0] _assert_path(path, [_AHN('16', 0.8, True), _AHN('16', 0.4, True), _AHN('16', 0.2, True)]) assert abs(cost - 8.4) < 0.000001 path, cost = results[1] _assert_path(path, [_AHN('16', 0.8, True), _AHN('16', 0.4, True)]) assert abs(cost - 5.6) < 0.000001 path, cost = results[2] _assert_path(path, [_AHN('16', 0.8, False), 6]) assert abs(cost - 2.8) < 0.000001 path, cost = results[3] _assert_path(path, [_AHN('16', 0.8, True), _AHN('16', 0.4, True), _AHN('16', 0.2, True), 1]) assert abs(cost - 11.2) < 0.000001 # It should find paths on the circle edge targets = [(ecircle, 0.8), (ecircle, 0.7), (ecircle, 0.1)] results = road_network_route_many((ecircle, 0.2), targets, _get_edges) path, cost = results[0] assert (cost - 0.4) < 0.0000001 _assert_path(path, [_AHN('cc', 0.2, True), _AHN('cc', 0.1, True), 'c', _AHN('cc', 0.8, True)]) path, cost = results[1] assert (cost - 0.5) < 0.0000001 _assert_path(path, [_AHN('cc', 0.2, True), _AHN('cc', 0.1, True), 'c', _AHN('cc', 0.8, True), _AHN('cc', 0.7, True)]) path, cost = results[2] assert (cost - 0.1) < 0.0000001 _assert_path(path, [_AHN('cc', 0.2, True), _AHN('cc', 0.1, True)]) # It should not find a path to the isolated edge targets = [(e13, 0.3), (e89, 0.2), (e34, 0.5)] results = road_network_route_many((e13, 0.3), targets, _get_edges) assert results[0][1] >= 0 and results[2][1] >= 0 assert results[1] == (None, -1) # It should not find a path if the cost exceeds the max_path_cost results = road_network_route_many((e89, 0.9), [(e89, 0.8), (e89, 0.1)], _get_edges, 200) path, cost = results[0] assert abs(cost - 100) < 0.00001 assert results[1] == (None, -1) # One-to-many routing should be the same as calling one-to-one # multiple times import random source = (e13, random.random()) # Generate 20 locations at each edge targets = [(edge, random.random()) for edge in edges for _ in range(20)] def _route_many_hard_way(source, targets): route_distances = [] for target in targets: try: _, route_distance = road_network_route(source, target, _get_edges) except sp.PathNotFound: route_distance = -1 route_distances.append(route_distance) return route_distances hard_ways = _route_many_hard_way(source, targets) # Get costs in the second column easy_ways = list(zip(*road_network_route_many(source, targets, _get_edges)))[1] for hard_way, easy_way in zip(hard_ways, easy_ways): assert abs(hard_way - easy_way) < 0.0000000001
def test_build_adhoc_network(): import functools same_edge_p = functools.partial(Edge.same_edge, precision=0.0000001) # It should simply do it right edge_locations = ((Edge(id=1, start_node=1, end_node=10, cost=100, reverse_cost=1000), 0.5),) adhoc_nodes, adhoc_network = build_adhoc_network(edge_locations) assert len(adhoc_nodes) == 1 node = adhoc_nodes[0] assert isinstance(node, AdHocNode) backward_edge, forward_edge = adhoc_network[node] backward_edge = backward_edge.reversed_edge() assert same_edge_p(backward_edge, Edge(id=1, start_node=1, end_node=node, cost=50, reverse_cost=500)) assert same_edge_p(forward_edge, Edge(id=1, start_node=node, end_node=10, cost=50, reverse_cost=500)) assert backward_edge == adhoc_network[1][0] assert backward_edge.reversed_edge() == adhoc_network[node][0] assert forward_edge == adhoc_network[node][1] assert forward_edge.reversed_edge() == adhoc_network[10][0] # It should do it simply right for 2 edge locations edge_locations = ((Edge(id=1, start_node=1, end_node=10, cost=100, reverse_cost=1000), 0.5), (Edge(id=2, start_node=3, end_node=5, cost=100, reverse_cost=1000), 0.4)) adhoc_nodes, adhoc_network = build_adhoc_network(edge_locations) assert len(adhoc_nodes) == 2 # It should do it right at 3 locations at the same edge edge = Edge(id=1, start_node=1, end_node=10, cost=100, reverse_cost=1000) edge_locations = ((edge, 0.5), (edge.reversed_edge(), 0.4), (edge.reversed_edge(), 0)) adhoc_nodes, adhoc_network = build_adhoc_network(edge_locations) # 1 -------------> n0 --> n1 -----------> n2 (10) n0, n1, n2 = adhoc_nodes assert same_edge_p(adhoc_network[1][0], Edge(id=1, start_node=1, end_node=n0, cost=50, reverse_cost=500)) b0, f0 = adhoc_network[n0] assert b0 == adhoc_network[1][0].reversed_edge() assert same_edge_p(f0, Edge(id=1, start_node=n0, end_node=n1, cost=10, reverse_cost=100)) b1, f1 = adhoc_network[n1] assert b1 == f0.reversed_edge() assert same_edge_p(f1, Edge(id=1, start_node=n1, end_node=n2, cost=40, reverse_cost=400)) assert n2 == 10 assert same_edge_p(adhoc_network[n2][0], Edge(id=1, start_node=n1, end_node=n2, cost=40, reverse_cost=400).reversed_edge())