Esempio n. 1
0
 def get_next_direction(self, start, goal):
     self.start = start
     self.goal = goal
     graph = self.create_graph(self.game_map)
     path = astar.astar_path(graph, start, goal)
     direction = self.convert_node_to_direction(path)
     return direction
Esempio n. 2
0
File: trip.py Progetto: mklucz/drogi
 def __init__(self, way_map, start, end):
     """
     Args:
         way_map(WayMap): the map the trip takes place on
         start(2-tuple): starting point
         end(2-tuple): destination
     """
     self.way_map = way_map
     self.start = start
     self.end = end
     try:
         self.list_of_nodes = astar_path(self.way_map.graph,
                                         self.start,
                                         self.end)
     except NetworkXNoPath:
         self.list_of_nodes = []
     self.linestring = LineString(self.list_of_nodes)
     self.straightline_length = Path.straightline_distance(self.start,
                                                           self.end)
     self.straightline = LineString([self.start, self.end])
     self.deviation_factor = (self.linestring.length /
                              self.straightline_length)
     self.obstacles = []
     for polygon in list(polygonize([self.linestring,
                                     self.straightline])):
         self.obstacles.append(Obstacle(self.way_map,
                                        self.start,
                                        self.end,
                                        polygon))
Esempio n. 3
0
def graph_routes(graph, find_longest):
    """ Return a list of routes through a network as (x, y) pair lists, with no edge repeated.
    
        Each node in the graph must have a "point" attribute with a Point object.
    """
    # it's destructive
    _graph = graph.copy()
    
    # passed directly to shortest_path()
    weight = find_longest and 'length' or None
    
    # heuristic function for A* path-finding functions, see also:
    # http://networkx.lanl.gov/reference/algorithms.shortest_paths.html#module-networkx.algorithms.shortest_paths.astar
    heuristic = lambda n1, n2: _graph.node[n1]['point'].distance(_graph.node[n2]['point'])
    
    routes = []
    
    while True:
        if not _graph.edges():
            break
    
        leaves = [index for index in _graph.nodes() if _graph.degree(index) == 1]
        
        if len(leaves) == 1 or not find_longest:
            # add Y-junctions because with a single leaf, we'll get nowhere
            leaves += [index for index in _graph.nodes() if _graph.degree(index) == 3]
        
        if len(leaves) == 0:
            # just pick an arbitrary node and its neighbor out of the infinite loop
            node = [index for index in _graph.nodes() if _graph.degree(index) == 2][0]
            neighbor = _graph.neighbors(node)[0]
            leaves = [node, neighbor]

        distances = [(_graph.node[v]['point'].distance(_graph.node[w]['point']), v, w)
                     for (v, w) in combinations(leaves, 2)]
        
        for (distance, v, w) in sorted(distances, reverse=find_longest):
            try:
                indexes = astar_path(_graph, v, w, heuristic, weight)
            except NetworkXNoPath:
                # try another
                continue
    
            for (v, w) in zip(indexes[:-1], indexes[1:]):
                _graph.remove_edge(v, w)
            
            points = [_graph.node[index]['point'] for index in indexes]
            coords = [(point.x, point.y) for point in points]
            routes.append(coords)
            
            # move on to the next possible route
            break
    
    return routes
Esempio n. 4
0
def _graph_routes_main(graph, find_longest, time_coefficient=0.02):
    """ Return a list of routes through a network as (x, y) pair lists, with no edge repeated.
    
        Called from graph_routes().
    
        Each node in the graph must have a "point" attribute with a Point object.
        
        The time_coefficient argument helps determine a time limit after which
        this function is killed off by means of a SIGALRM. With the addition of
        divide_points() in polygon_skeleton_graphs() as of version 0.6.0, this
        condition is much less likely to actually happen.

        The default value of 0.02 comes from a graph of times for a single
        state's generalized routes at a few zoom levels. I found that this
        function typically runs in O(n) time best case with some spikes up
        to O(n^2) and a general cluster around O(n^1.32). Introducing a time
        limit based on O(n^2) seemed too generous for large graphs, while
        the coefficient 0.02 seemed to comfortably cover graphs with up to
        tens of thousands of nodes.
        
        In the graph (new-hampshire-times.png) the functions are:
        - X-axis: graph size in nodes
        - Y-axis: compute time in seconds
        - Orange dashed good-enough limit: y = 0.02x
        - Blue bottom limit: y = 0.00005x
        - Green trend line: y = 2.772e-5x^1.3176
        - Black upper bounds: y = 0.000001x^2
    """
    # it's destructive
    _graph = graph.copy()

    start_nodes, start_time = _graph.number_of_nodes(), time()

    # passed directly to shortest_path()
    weight = find_longest and 'length' or None

    # heuristic function for A* path-finding functions, see also:
    # http://networkx.lanl.gov/reference/algorithms.shortest_paths.html#module-networkx.algorithms.shortest_paths.astar
    heuristic = lambda n1, n2: point_distance(_graph.node[n1]['point'], _graph.
                                              node[n2]['point'])

    routes = []

    while True:
        if not _graph.edges():
            break

        leaves = [
            index for index in _graph.nodes() if _graph.degree(index) == 1
        ]

        if len(leaves) == 1 or not find_longest:
            # add Y-junctions because with a single leaf, we'll get nowhere
            leaves += [
                index for index in _graph.nodes() if _graph.degree(index) == 3
            ]

        if len(leaves) == 0:
            # just pick an arbitrary node and its neighbor out of the infinite loop
            node = [
                index for index in _graph.nodes() if _graph.degree(index) == 2
            ][0]
            neighbor = _graph.neighbors(node)[0]
            leaves = [node, neighbor]

        distances = [(point_distance(_graph.node[v]['point'],
                                     _graph.node[w]['point']), v, w)
                     for (v, w) in combinations(leaves, 2)]

        for (distance, v, w) in sorted(distances, reverse=find_longest):
            try:
                indexes = astar_path(_graph, v, w, heuristic, weight)
            except NetworkXNoPath:
                # try another
                continue

            for (v, w) in zip(indexes[:-1], indexes[1:]):
                _graph.remove_edge(v, w)

            points = [_graph.node[index]['point'] for index in indexes]
            coords = [(point.x, point.y) for point in points]
            routes.append(coords)

            # move on to the next possible route
            break

    print(start_nodes, (time() - start_time),
          file=open('graph-routes-log.txt', 'a'))

    return routes
Esempio n. 5
0
def _graph_routes_main(graph, find_longest, time_coefficient=0.02):
    """ Return a list of routes through a network as (x, y) pair lists, with no edge repeated.
    
        Called from graph_routes().
    
        Each node in the graph must have a "point" attribute with a Point object.
        
        The time_coefficient argument helps determine a time limit after which
        this function is killed off by means of a SIGALRM. With the addition of
        divide_points() in polygon_skeleton_graphs() as of version 0.6.0, this
        condition is much less likely to actually happen.

        The default value of 0.02 comes from a graph of times for a single
        state's generalized routes at a few zoom levels. I found that this
        function typically runs in O(n) time best case with some spikes up
        to O(n^2) and a general cluster around O(n^1.32). Introducing a time
        limit based on O(n^2) seemed too generous for large graphs, while
        the coefficient 0.02 seemed to comfortably cover graphs with up to
        tens of thousands of nodes.
        
        In the graph (new-hampshire-times.png) the functions are:
        - X-axis: graph size in nodes
        - Y-axis: compute time in seconds
        - Orange dashed good-enough limit: y = 0.02x
        - Blue bottom limit: y = 0.00005x
        - Green trend line: y = 2.772e-5x^1.3176
        - Black upper bounds: y = 0.000001x^2
    """
    # it's destructive
    _graph = graph.copy()
    
    start_nodes, start_time = _graph.number_of_nodes(), time()
    
    # passed directly to shortest_path()
    weight = find_longest and 'length' or None
    
    # heuristic function for A* path-finding functions, see also:
    # http://networkx.lanl.gov/reference/algorithms.shortest_paths.html#module-networkx.algorithms.shortest_paths.astar
    heuristic = lambda n1, n2: point_distance(_graph.node[n1]['point'], _graph.node[n2]['point'])
    
    routes = []
    
    while True:
        if not _graph.edges():
            break
    
        leaves = [index for index in _graph.nodes() if _graph.degree(index) == 1]
        
        if len(leaves) == 1 or not find_longest:
            # add Y-junctions because with a single leaf, we'll get nowhere
            leaves += [index for index in _graph.nodes() if _graph.degree(index) == 3]
        
        if len(leaves) == 0:
            # just pick an arbitrary node and its neighbor out of the infinite loop
            node = [index for index in _graph.nodes() if _graph.degree(index) == 2][0]
            neighbor = _graph.neighbors(node)[0]
            leaves = [node, neighbor]

        distances = [(point_distance(_graph.node[v]['point'], _graph.node[w]['point']), v, w)
                     for (v, w) in combinations(leaves, 2)]
        
        for (distance, v, w) in sorted(distances, reverse=find_longest):
            try:
                indexes = astar_path(_graph, v, w, heuristic, weight)
            except NetworkXNoPath:
                # try another
                continue
    
            for (v, w) in zip(indexes[:-1], indexes[1:]):
                _graph.remove_edge(v, w)
            
            points = [_graph.node[index]['point'] for index in indexes]
            coords = [(point.x, point.y) for point in points]
            routes.append(coords)
            
            # move on to the next possible route
            break
    
    print >> open('graph-routes-log.txt', 'a'), start_nodes, (time() - start_time)

    return routes