Example #1
0
 def test_is_empty(self):
     p = PriorityQueue()
     assert p.is_empty() is True
     p.enqueue('A', 1)
     assert p.is_empty() is False
     p.enqueue('B', 1)
     assert p.is_empty() is False
     p.dequeue()
     assert p.is_empty() is False
     p.dequeue()
     assert p.is_empty() is True
Example #2
0
def minimum_spanning_tree(graph):

    min_heap = PriorityQueue(True)
    vertex_to_edge = {}
    result = []

    for vertex in graph.all_vertex.values():
        min_heap.add_task(sys.maxsize, vertex)

    start_vertex = next(iter((graph.all_vertex.values())))
    min_heap.change_task_priority(0, start_vertex)
    while min_heap.is_empty() is False:
        current = min_heap.pop_task()

        if (current in vertex_to_edge):
            spanning_tree_edge = vertex_to_edge[current]
            result.append(spanning_tree_edge)

        for edge in current.edges:
            adjacent = get_other_vertex_for_edge(current, edge)
            if min_heap.contains_task(
                    adjacent) is True and min_heap.get_task_priority(
                        adjacent) > edge.weight:
                min_heap.change_task_priority(edge.weight, adjacent)
                vertex_to_edge[adjacent] = edge

    return result
Example #3
0
def shortest_path(graph, sourceVertex):

    min_heap = PriorityQueue(True)
    distance = {}
    parent = {}

    for vertex in graph.all_vertex.values():
        min_heap.add_task(sys.maxsize, vertex)

    min_heap.change_task_priority(0, sourceVertex)
    distance[sourceVertex] = 0
    parent[sourceVertex] = None

    while min_heap.is_empty() is False:
        task = min_heap.peek_task()
        weight = min_heap.get_task_priority(task)               
        current =  min_heap.pop_task()
        distance[current] = weight

        for edge in current.edges:
            adjacent = get_other_vertex_for_edge(current, edge)
            if min_heap.contains_task(adjacent) is False:
                continue

            new_distance = distance[current] + edge.weight;
            if min_heap.get_task_priority(adjacent) > new_distance:
                min_heap.change_task_priority(new_distance, adjacent)
                parent[adjacent] = current
                

    return distance
Example #4
0
    def get_path(self, start, end, board, cost_estimate=get_distance):

        t0 = time.time()

        explored = set()
        previous = {}
        previous[start] = None
        moves = {}
        moves[start] = 0

        frontier = PriorityQueue()
        frontier.insert(start, cost_estimate(start, end))

        if VERBOSE_ASTAR: print 'get_path start, end:', start, end

        while not frontier.is_empty():

            if (time.time() - t0 > PATHFINDER_TIMEOUT):
                print 'PATHFINDING TIMEOUT: Averting disconnect...'
                print '    get_path: Probably could not find a valid path from', start, 'to', end
                return [start, start]

            if VERBOSE_ASTAR: print 'get_path frontier:', frontier

            current = frontier.remove()
            explored.add(current)

            if VERBOSE_ASTAR: print 'get_path explored set', explored
            if VERBOSE_ASTAR: print 'get_path current pos:', current

            if (current == end):
                if VERBOSE_ASTAR: print 'Found end loc'
                break
            else:
                neighbors = get_neighboring_locs(current, board)

                if VERBOSE_ASTAR: print 'get_path neighbors:', neighbors

                for n in neighbors:
                    if n not in explored and (board.passable(n)
                                              or n in (start, end)):
                        moves[n] = moves[current] + MOVE_COST
                        frontier.insert(n, cost_estimate(n, end) + moves[n])
                        previous[n] = current

        # found goal, now reconstruct path
        i = end
        path = [i]
        while i != start:
            if (i in previous):
                path.append(previous[i])
                i = previous[i]
            else:
                print 'get_path error: probably could not find a valid path from', start, 'to', end
                return [start, start]  # return something valid

        path.reverse()

        return path
Example #5
0
 def test_init_with_list(self):
     q = PriorityQueue()
     q.enqueue('B', 3)
     q.enqueue('C', 5)
     q.enqueue('A', 1)
     assert q.front() == 'A'
     assert q.length() == 3
     assert q.is_empty() is False
Example #6
0
    def get_path(self, start, end, board, cost_estimate=get_distance):
    
        t0 = time.time()

        explored = set()
        previous = {}
        previous[start] = None
        moves = {}
        moves[start] = 0

        frontier = PriorityQueue()
        frontier.insert(start, cost_estimate(start, end))

        if VERBOSE_ASTAR: print 'get_path start, end:', start, end

        while not frontier.is_empty():
        
            if (time.time() - t0 > PATHFINDER_TIMEOUT):
                print 'PATHFINDING TIMEOUT: Averting disconnect...'
                print '    get_path: Probably could not find a valid path from', start, 'to', end
                return [start, start] 

            if VERBOSE_ASTAR: print 'get_path frontier:', frontier

            current = frontier.remove()
            explored.add(current)

            if VERBOSE_ASTAR: print 'get_path explored set', explored
            if VERBOSE_ASTAR: print 'get_path current pos:', current

            if (current == end):
                if VERBOSE_ASTAR: print 'Found end loc'
                break
            else:
                neighbors = get_neighboring_locs(current, board)

                if VERBOSE_ASTAR: print 'get_path neighbors:', neighbors

                for n in neighbors:
                    if n not in explored and (board.passable(n) or n in (start, end)):
                        moves[n] = moves[current] + MOVE_COST
                        frontier.insert(n, cost_estimate(n, end) + moves[n])
                        previous[n] = current

        # found goal, now reconstruct path
        i = end
        path = [i]
        while i != start:
            if (i in previous):
                path.append(previous[i])
                i = previous[i]
            else:
                print 'get_path error: probably could not find a valid path from', start, 'to', end
                return [start, start]    # return something valid

        path.reverse()

        return path
Example #7
0
 def test_dequeue(self):
     pq = PriorityQueue([(1, 'A'), (2, 'B'), (3, 'C')])
     assert pq.dequeue() == (1, 'A')
     assert pq.length() == 2
     assert pq.dequeue() == (2, 'B')
     assert pq.length() == 1
     assert pq.dequeue() == (3, 'C')
     assert pq.length() == 0
     assert pq.is_empty() is True
     with self.assertRaises(ValueError):
         pq.dequeue()
Example #8
0
 def test_enqueue(self):
     q = PriorityQueue()
     q.enqueue('A', 3)
     assert q.front() == 'A'
     assert q.length() == 1
     q.enqueue('B', 1)
     assert q.front() == 'B'
     assert q.length() == 2
     q.enqueue('C', 4)
     assert q.front() == 'B'
     assert q.length() == 3
     assert q.is_empty() is False
Example #9
0
 def test_enqueue(self):
     pq = PriorityQueue()
     pq.enqueue('B', 2)
     assert pq.front() == (2, 'B')
     assert pq.length() == 1
     pq.enqueue('A', 1)
     assert pq.front() == (1, 'A')
     assert pq.length() == 2
     pq.enqueue('C', 3)
     assert pq.front() == (1, 'A')
     assert pq.length() == 3
     assert pq.is_empty() is False
Example #10
0
 def test_dequeue(self):
     q = PriorityQueue()
     q.enqueue('A', 1)
     q.enqueue('B', 2)
     q.enqueue('C', 3)
     assert q.dequeue() == 'A'
     assert q.length() == 2
     assert q.dequeue() == 'B'
     assert q.length() == 1
     assert q.dequeue() == 'C'
     assert q.length() == 0
     assert q.is_empty() is True
     with self.assertRaises(ValueError):
         q.dequeue()
Example #11
0
class TestPriorityQueue(unittest.TestCase):
    def setUp(self):
        self.pq = PriorityQueue(":memory:")

    def test_empty(self):
        result = self.pq.is_empty()
        self.assertTrue(result)

    def test_order(self):
        self.assertEqual("hello", self.pq.push(10, "hello"))
        self.pq.push(1, "foo")
        self.pq.push(30, "bar")
        self.pq.push(5, "baz")

        self.assertEqual("bar", self.pq.pop())
        self.assertEqual("hello", self.pq.pop())
        self.assertEqual("baz", self.pq.pop())
        self.assertEqual("foo", self.pq.pop())
class TestPriorityQueue(unittest.TestCase):

    def setUp(self):
        self.pq = PriorityQueue(":memory:")

    def test_empty(self):
        result = self.pq.is_empty()
        self.assertTrue(result)

    def test_order(self):
        self.assertEqual("hello", self.pq.push(10, "hello"))
        self.pq.push(1, "foo")
        self.pq.push(30, "bar")
        self.pq.push(5, "baz")

        self.assertEqual("bar", self.pq.pop())
        self.assertEqual("hello", self.pq.pop())
        self.assertEqual("baz", self.pq.pop())
        self.assertEqual("foo", self.pq.pop())
Example #13
0
def prims_algorithm_mst(graph):
    """
  Prim's algorithm, this algorithm
  has the same time complexity as Djikstra's
  single source shorted path algorithm.

  This particular algorithm is

  O((V ** 2) + (V * E))

  but with a priority queue or vEB tree this can be reduced
  to

  O((V * log(V)) + (V * E))

  a time complexity equivalent to Djikstra's

  """
    if not isinstance(graph, Graph):
        raise TypeError('this function expects an instance of Graph')
    queue = PriorityQueue(graph)
    root = None
    nodes = {u: TreeNode(u) for u in graph.vertices}
    while not queue.is_empty():
        u = queue.pop_min()
        if root is None:
            root = nodes[u]
        for v in graph.adj[u]:
            if queue.contains(v):
                queue.update(v, graph.weights[(u, v)])
                nodes[v].parent = nodes[u]
    for n in nodes:
        node = nodes[n]
        if node.parent is not None:
            node.parent.children.append(node)
    return root
def Astar(puzzle8, came_from):
    frontier = PriorityQueue()
    cost_so_far = {}
    frontier.enqueue(puzzle8, 0)
    cost_so_far[puzzle8.ToString()] = puzzle8.cost
    came_from[puzzle8.ToString()] = None
    while not frontier.is_empty():
        puzzle8 = frontier.dequeue()
        
        if puzzle8.isGoal():
            return puzzle8
        else:
            moves = puzzle8.getAllMoves()
            for move in moves:
                newpuzzle8 = puzzle8.clone()
                newpuzzle8.move(*move)
                new_cost = newpuzzle8.cost
                if cost_so_far.get(newpuzzle8.ToString()) == None or \
                   new_cost < cost_so_far[newpuzzle8.ToString()]:
                    cost_so_far[newpuzzle8.ToString()] = new_cost
                    priority = new_cost + newpuzzle8.heuristics
                    frontier.enqueue(newpuzzle8, priority)
                    came_from[newpuzzle8.ToString()] = puzzle8
    return None
Example #15
0
 def test_init_with_list(self):
     pq = PriorityQueue([(1, 'A'), (2, 'B'), (3, 'C')])
     assert pq.front() == (1, 'A')
     assert pq.length() == 3
     assert pq.is_empty() is False
Example #16
0
 def test_init(self):
     q = PriorityQueue()
     assert q.front() is None
     assert q.length() == 0
     assert q.is_empty() is True
Example #17
0
def astar(grid, start, goal):
    '''Return a path found by A* alogirhm 
       and the number of steps it takes to find it.

    arguments:
    grid - A nested list with datatype int. 0 represents free space while 1 is obstacle.
           e.g. a 3x3 2D map: [[0, 0, 0], [0, 1, 0], [0, 0, 0]]
    start - The start node in the map. e.g. [0, 0]
    goal -  The goal node in the map. e.g. [2, 2]

    return:
    path -  A nested list that represents coordinates of each step (including start and goal node), 
            with data type int. e.g. [[0, 0], [0, 1], [0, 2], [1, 2], [2, 2]]
    steps - Number of steps it takes to find the final solution, 
            i.e. the number of nodes visited before finding a path (including start and goal node)

    >>> from main import load_map
    >>> grid, start, goal = load_map('test_map.csv')
    >>> astar_path, astar_steps = astar(grid, start, goal)
    It takes 7 steps to find a path using A*
    >>> astar_path
    [[0, 0], [1, 0], [2, 0], [3, 0], [3, 1]]
    '''
    
    debug_draw = False

    path = []
    steps = 0
    found = False

    map = map2d(grid)

    frontier = PriorityQueue()
    frontier.put(start, map.get_manhattan_distance(start, goal))

    came_from = {}
    came_from[tuple(start)] = {
        'from': None,
        'cost': 0
    }

    while not frontier.is_empty():
        (curr_cost, current) = frontier.get()
        frontier.remove()
        if tuple(goal) in came_from.keys():
            found = True
            break

        for neighbor in map.get_neighbors(current):
            if neighbor is None or map.get_value(neighbor) == 1:
                continue
            neighbor_cost = curr_cost - map.get_manhattan_distance(current, goal) + \
                map.get_manhattan_distance(current, neighbor) + \
                map.get_manhattan_distance(neighbor, goal)
            if tuple(neighbor) not in came_from or \
               neighbor_cost < came_from.get(tuple(neighbor)).get('cost'):
                frontier.put(neighbor, neighbor_cost)
                came_from[tuple(neighbor)] = {
                    'from': current,
                    'cost': neighbor_cost
                }
        if debug_draw: map.draw_path(start = start, goal = goal, path = path, came_from = came_from)
        
    # found = True
    steps = len(came_from) - 1
    curr_point = goal
    while curr_point != start:
        path.append(curr_point)
        curr_point = came_from.get(tuple(curr_point)).get('from')
    path.append(start)
    path.reverse()

    if found:
        print(f"It takes {steps} steps to find a path using A*")
    else:
        print("No path found")
    return path, steps