Пример #1
0
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]
Пример #2
0
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()
Пример #3
0
    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)
Пример #4
0
 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
Пример #5
0
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)
Пример #6
0
    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)
Пример #7
0
    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
Пример #10
0
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()
Пример #11
0
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 = {}
Пример #12
0
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.")
Пример #13
0
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
Пример #14
0
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
Пример #15
0
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())