コード例 #1
0
ファイル: kms.py プロジェクト: raysarinas/routefinder
def least_cost_path(graph, start, dest, cost):
    reached = {}  # empty dictionary
    events = BinaryHeap()  # empty heap
    events.insert((start, start), 0)  # vertex s burns at time 0

    while len(events) > 0:
        edge, time = events.popmin()
        if edge[1] not in reached:
            reached[edge[1]] = edge[0]
            for nbr in graph.neighbours(edge[1]):
                events.insert((edge[1], nbr), time + cost.distance(
                    (edge[1], nbr)))

    if dest not in reached:
        return []

    current = dest
    path = [current]

    while current != start:
        current = reached[current]
        path.append(current)

    path = path[::-1]
    return path
コード例 #2
0
ファイル: realservice.py プロジェクト: raysarinas/routefinder
def least_cost_path(graph, start, dest, cost):
    reached = {}  # empty dictionary
    events = BinaryHeap()  # empty heap
    events.insert((start, start), 0)  # vertex s burns at time 0

    while len(events) > 0:
        edge, time = events.popmin()
        if edge[1] not in reached:
            reached[edge[1]] = edge[0]
            for nbr in graph.neighbours(edge[1]):
                events.insert((edge[1], nbr), time + cost.distance((edge[1], nbr)))
    # if the dest is not in reached, then no route was found
    if dest not in reached:
        return []

    current = dest
    route = [current]
    # go through the reached vertices until we get back to start and append
    # each vertice that we "stop" at
    while current != start:
        current = reached[current]
        route.append(current)
    # reverse the list because we made a list that went from the dest to start
    route = route[::-1]
    return route
コード例 #3
0
def make_valid_heaps():
    valid_heaps = []
    for permutation in unsorted_lists:
        heap = BinaryHeap()
        for item in permutation:
            heap.insert(item)
        valid_heaps.append(heap)
    return valid_heaps
コード例 #4
0
def least_cost_path(graph, start, dest, location):
    """
    *** NOTE: This function is a modified version of our previous ***
    *** implementation of Dijkstra's Algorithm from Assignment 1  ***
    *** Part 1. Comments in code indicate changes made.           ***

    Find and return a least cost path in graph from start vertex to dest vertex.

    Args:
    graph (Graph): The digraph defining the edges between the
    vertices.
    start: The vertex where the path starts. It is assumed
    that start is a vertex of graph.
    dest: The vertex where the path ends. It is assumed
    that dest is a vertex of graph.
    location: A dictionary containing all the vertices on the screen.
    Keys of location are identifiers holding the vertices as values.

    Returns:
    list: A potentially empty list (if no path can be found) of
    the vertices in the graph. If there was a path, the first
    vertex is always start, the last is always dest in the list.
    Any two consecutive vertices correspond to some edge in graph.
    """

    reached = {}
    events = BinaryHeap()
    events.insert((start, start), 0)

    while len(events) > 0:
        edge, time = events.popmin()
        if edge[1] not in reached:
            reached[edge[1]] = edge[0]

            # each vertex in our graph is a tuple, so we use tuples to find neighbours
            # instead of single values to find the neighbours of a vertex
            for nbr in graph.neighbours(location[edge[1]]):
                # find the identifier/key value attached to nbr tuple
                nbrID = neighbour_identifier(nbr, location)
                # insert to binary heap appropriately
                events.insert((edge[1], nbrID),
                              time + distance(location[edge[1]], nbr))

    # FIND MINIMUM PATH IF POSSIBLE
    if dest not in reached:
        return []

    # start at the dest and continously ind the parent of current vertex
    # until have reached starting vertex
    current = dest
    path = [current]

    while current != start:
        current = reached[current]
        path.append(current)

    path = path[::-1]  # reverse the list so starts from the ghost
    return path
コード例 #5
0
    def least_cost_path_lrt(self, lrts, end):
        reached = {}
        events = BinaryHeap()

        #insert start location with time of 0 into the heap
        counter = 0
        for key, val in lrts.items():
            events.insert((val, val, 0), 0)

        while (len(events)) > 0:
            pair, time = events.popmin()
            #print(time)

            #account for heuristic so it is not compounded
            if (pair[2]):
                time -= pair[2]

            if pair[1] not in reached:
                # add to reached dictionary
                reached[pair[1]] = pair[0]

                #consider neighbors around each point and distance to each neighbor
                for neighbour in self.graph.neighbours(pair[1]):
                    point1 = self.locations[pair[1]]
                    point2 = self.locations[neighbour]

                    # maybe we could save distances between objects in a dict, and reuse them?

                    # add heuristic in for the form of euclidean distance. This will helps lead the searching algorithm
                    # more towards the end location

                    heuristic = euclidean_distance(point2, self.locations[end])

                    # add key and val to BinaryHeap called events
                    events.insert(
                        (pair[1], neighbour, heuristic),
                        time + euclidean_distance(point1, point2) + heuristic)

            # end loop right after destination is popped
            if (pair[1] == end):
                break

        # use the get_path included with the breadth_first_search helper file to find path from reached dictionary
        path = None
        closestLRT = None
        for key, val in lrts.items():
            if val in reached:
                path = get_path(reached, val, end)
            if path == None:
                pass
            else:
                closestLRT = key
                break
        return path, closestLRT
コード例 #6
0
    def test_empty_heap_insert_extract_elements_should_return_sorted_elements(self):
        nums = [3, 4, -1, 15, 2, 77, -3, 4, 12]
        heap = BinaryHeap()
        expected = [77, 15, 12, 4, 4, 3, 2, -1, -3]
        result = []
        for num in nums:
            heap.insert(num)
        while heap.count > 0:
            result.append(heap.extract_max())

        self.assertEqual(result, expected)
コード例 #7
0
ファイル: dijkstra.py プロジェクト: raysarinas/routefinder
def least_cost_path(graph, start, dest, cost):
    """Find and return a least cost path in graph from start vertex to dest vertex.
    Efficiency: If E is the number of edges, the run-time is
      O( E log(E) ).
    Args:
      graph (Graph): The digraph defining the edges between the
        vertices.
      start: The vertex where the path starts. It is assumed
        that start is a vertex of graph.
      dest:  The vertex where the path ends. It is assumed
        that dest is a vertex of graph.
      cost:  A class with a method called "distance" that takes
        as input an edge (a pair of vertices) and returns the cost
        of the edge. For more details, see the CostDistance class
        description below.
    Returns:
      list: A potentially empty list (if no path can be found) of
        the vertices in the graph. If there was a path, the first
        vertex is always start, the last is always dest in the list.
        Any two consecutive vertices correspond to some
        edge in graph.
        """

    reached = {} # empty dictionary
    events = BinaryHeap() # empty heap
    events.insert((start, start), 0) # vertex s burns at time 0

    while len(events) > 0:
        edge, time = events.popmin()
        if edge[1] not in reached:
            reached[edge[1]] = edge[0] # burn vertex v, record predecessor u
            for nbr in graph.neighbours(edge[1]):
                events.insert((edge[1], nbr), time + cost.distance((edge[1], nbr)))

    # if the dest is not in the reached dictionary, then return an empty list
    if dest not in reached:
      return []

    # IMPLEMENTED FROM GET_PATH FUNCTION FROM breadth_first_search
    # finds minimum path
    # start at the dest and continuosly and find the parent of current vertex
    # until have reached starting vertex
    current = dest
    path = [current]

    while current != start:
        current = reached[current]
        path.append(current)

    path = path[::-1]
    return path
コード例 #8
0
ファイル: astar.py プロジェクト: wayoalamos/15-puzzle-inv
class Astar:
    def __init__(self, initial_state, heuristic, weight=1):
        self.expansions = 0
        self.generated = 0
        self.initial_state = initial_state
        self.weight = weight
        self.heuristic = heuristic

    def search(self):
        self.start_time = time.process_time()
        self.open = BinaryHeap()
        self.expansions = 0
        initial_node = Node(self.initial_state)
        initial_node.g = 0
        initial_node.h = self.heuristic(self.initial_state)
        initial_node.key = 10000 * self.weight * initial_node.h  # asignamos el valor f
        self.open.insert(initial_node)
        # para cada estado alguna vez generado, generated almacena
        # el Node que le corresponde
        self.generated = {}
        self.generated[self.initial_state] = initial_node
        while not self.open.is_empty():
            n = self.open.extract()  # extrae n de la open
            if n.state.is_goal():
                self.end_time = time.process_time()
                return n
            succ = n.state.successors()
            self.expansions += 1
            for child_state, action, cost in succ:
                child_node = self.generated.get(child_state)
                is_new = child_node is None  # es la primera vez que veo a child_state
                path_cost = n.g + cost  # costo del camino encontrado hasta child_state
                if is_new or path_cost < child_node.g:
                    # si vemos el estado child_state por primera vez o lo vemos por
                    # un mejor camino, entonces lo agregamos a open
                    if is_new:  # creamos el nodo de child_state
                        child_node = Node(child_state, n)
                        child_node.h = self.heuristic(child_state)
                        self.generated[child_state] = child_node
                    child_node.action = action
                    child_node.parent = n
                    child_node.g = path_cost
                    child_node.key = 10000 * (
                        child_node.g + self.weight * child_node.h
                    ) - child_node.g  # actualizamos el f de child_node
                    self.open.insert(
                        child_node
                    )  # inserta child_node a la open si no esta en la open
        self.end_time = time.process_time(
        )  # en caso contrario, modifica la posicion de child_node en open
        return None
コード例 #9
0
class PriorityQueue:
    def __init__(self):
        self.binary_heap = BinaryHeap(lambda a, b: a[1] < b[1])

    def insert(self, element):
        self.binary_heap.insert(element)

    def multiple_insert(self, elements):
        for element in elements:
            self.insert(element)

    def extract(self):
        element = self.binary_heap.extract()
        return element[0] if element else element
コード例 #10
0
ファイル: test2.py プロジェクト: raysarinas/routefinder
def least_cost_path(graph, start, dest, cost):
    # Implementation of Dijkstra's algorithm
    events = BinaryHeap()
    reached = dict()
    events.insert((start, start), 0)  # Begin at time 0, at the start vertex

    while events:
        edge, time = events.popmin()  # Get next burnt vertex
        if edge[1] not in reached:  # If the destination is not been reached
            reached[edge[1]] = edge[0]  # Keep track of where we came from
            for w in graph.neighbours(edge[1]):  # Burn the neighbours!!!!
                events.insert(((edge[1]), w), (time + cost.distance(
                    (edge[1], w))))  # Add the fuse

    return get_path(reached, start, dest)  # return the path
コード例 #11
0
ファイル: server.py プロジェクト: jacobwong98/SandwichQueen
def least_cost_path(graph, start, dest, cost):
    """Find and return a least cost path in graph from start
    vertex to dest vertex.
    Efficiency: If E is the number of edges, the run-time is
    O( E log(E) ).
    Args:
    graph (Graph): The digraph defining the edges between the
    vertices.
    start: The vertex where the path starts. It is assumed
    that start is a vertex of graph.
    dest:  The vertex where the path ends. It is assumed
    that dest is a vertex of graph.
    cost:  A class with a method called "distance" that takes
    as input an edge (a pair of vertices) and returns the cost
    of the edge. For more details, see the CostDistance class
    description below.
    Returns:
    list: A potentially empty list (if no path can be found) of
    the vertices in the graph. If there was a path, the first
    vertex is always start, the last is always dest in the list.
    Any two consecutive vertices correspond to some
    edge in graph.
    """
    reached = {}  # empty dictionary
    events = BinaryHeap()  # empty heap
    events.insert((start, start), 0)  # vertex s burns at time 0

    while len(events) > 0:
        edge, time = events.popmin()
        if edge[1] not in reached:
            reached[edge[1]] = edge[0]
            for nbr in graph.neighbours(edge[1]):
                events.insert((edge[1], nbr), time + cost.distance(
                    (edge[1], nbr)))
    # if the dest is not in reached, then no route was found
    if dest not in reached:
        return []

    current = dest
    route = [current]
    # go through the reached vertices until we get back to start and append
    # each vertice that we "stop" at
    while current != start:
        current = reached[current]
        route.append(current)
    # reverse the list because we made a list that went from the dest to start
    route = route[::-1]
    return route
コード例 #12
0
def least_cost_path(graph, start, dest, cost):
    """
	Find and return a least cost path in graph from start
	vertex to dest vertex.

	Efficiency: If E is the number of edges, the run-time is
	O( E log(E) ).

	Args:
		graph (Graph): The digraph defining the edges between the
			vertices.
		start: The vertex where the path starts. It is assumed
			that start is a vertex of graph.
		dest:  The vertex where the path ends. It is assumed
			that dest is a vertex of graph.
		cost:  A class with a method called "distance" that takes
			as input an edge (a pair of vertices) and returns the cost
			of the edge. For more details, see the CostDistance class
			description below.

	Returns:
		list: A potentially empty list (if no path can be found) of
		the vertices in the graph. If there was a path, the first
		vertex is always start, the last is always dest in the list.
		Any two consecutive vertices correspond to some
		edge in graph.
	"""

    # initialize reached as a empty dict
    reached = {}
    # an instance of BinaryHeap class, initially empty
    events = BinaryHeap()
    events.insert((start, start), 0)  # vertex s burns at time 0
    while len(events) > 0:
        (u, v), time = events.popmin()
        if v not in reached:
            reached[v] = u  # burn vertex v, record predecessor u
            nbr_list = graph.neighbours(v)
            for w in nbr_list:
                # new event: edge (v,w) started burning
                events.insert((v, w), time + cost.distance((v, w)))

    # using the get_path function from bfs file developed in class
    # get the path as a list, if no path then a empty list
    return get_path(reached, start, dest)
コード例 #13
0
class PriorityQueue(object):
    def __init__(self):
        self._heap = BinaryHeap()

    def peek(self):
        return self._heap.peek_min()

    def is_empty(self):
        return self._heap.is_empty()

    def enqueue(self, value):
        self._heap.insert(value)

    def dequeue(self):
        self._heap.extract_min()

    def __iter__(self):
        yield from iter(self._heap)

    def __len__(self):
        return len(self._heap)
コード例 #14
0
class PriorityQueue(object):
	def __init__(self):
		self._heap = BinaryHeap()

	def peek(self):
		return self._heap.peek_min()

	def is_empty(self):
		return self._heap.is_empty()

	def enqueue(self, value):
		self._heap.insert(value)

	def dequeue(self):
		self._heap.extract_min()

	def __iter__(self):
		yield from iter(self._heap)

	def __len__(self):
		return len(self._heap)
コード例 #15
0
class TestBinaryHeap(unittest.TestCase):
    def setUp(self):
        size = 8
        self.random_list = random.sample(range(0, size), size)
        print "random list generated: " + str(self.random_list)

        self.heap = BinaryHeap(size)
        for key in self.random_list:
            if not self.heap.is_full():
                self.heap.insert(key)

    def tearDown(self):
        pass

    def test_delete_min(self):
        order_list = sorted(self.random_list)
        index = 0
        while not self.heap.is_empty():
            min_value = self.heap.delete_min()
            print min_value
            self.assertEqual(min_value, order_list[index])
            index += 1
コード例 #16
0
 def test_insert(self):
     bh = BinaryHeap(compare=lambda a, b: a < b)
     bh.insert(3)
     bh.insert(3)
     bh.insert(2)
     self.assertSequenceEqual([3, 3, 2], bh.values)
     bh.insert(4)
     self.assertSequenceEqual([4, 3, 2, 3], bh.values)
コード例 #17
0
 def test_insert_nodes_with_descending_values(self):
     binary_heap = BinaryHeap()
     binary_heap.insert(HeapNode({'name': 'A', 'value': 0.91}, 'value'))
     self.assertEqual([x.get_value_attribute() for x in binary_heap.node_list if x is not None], [0.91])
     binary_heap.insert(HeapNode({'name': 'B', 'value': 0.57}, 'value'))
     self.assertEqual([x.get_value_attribute() for x in binary_heap.node_list if x is not None], [0.57, 0.91])
     binary_heap.insert(HeapNode({'name': 'B', 'value': 0.34}, 'value'))
     self.assertEqual([x.get_value_attribute() for x in binary_heap.node_list if x is not None], [0.34, 0.91, 0.57])
コード例 #18
0
 def test_extract(self):
     bh = BinaryHeap(compare=lambda a, b: a < b)
     bh.insert(4)
     bh.insert(1)
     bh.insert(1)
     bh.insert(3)
     bh.insert(3)
     bh.insert(2)
     bh.insert(2)
     self.assertEqual(4, bh.extract())
     self.assertEqual(3, bh.extract())
     self.assertEqual(3, bh.extract())
     self.assertEqual(2, bh.extract())
     self.assertEqual(2, bh.extract())
     self.assertEqual(1, bh.extract())
     self.assertEqual(1, bh.extract())
コード例 #19
0
ファイル: huffman.py プロジェクト: evantimms/HuffmanEncoder
def make_tree(freq_table):
    """
    Constructs and returns the Huffman tree from the given frequency table.
    """

    trees = BinaryHeap()
    trees.insert(TreeLeaf(None), 1)
    for (symbol, freq) in freq_table.items():   
        trees.insert(TreeLeaf(symbol), freq)

    while len(trees) > 1:
        right, rfreq = trees.popmin()
        left, lfreq = trees.popmin()
        trees.insert(TreeBranch(left, right), lfreq+rfreq)

    tree, _ = trees.popmin()
    return tree
コード例 #20
0
def least_cost_path(graph, start, dest, cost):
    """
        Find and return a least cost path in graph from start
        vertex to dest vertex.

        Efficiency: If E is the number of edges, the run-time is
        O( E log(E) ).

        Args:
            graph (Graph): The digraph defining the edges between the
            vertices.
            start: The vertex where the path starts. It is assumed
                that start is a vertex of graph.
            dest:  The vertex where the path ends. It is assumed
                that dest is a vertex of graph.
            cost:  A class with a method called "distance" that takes
                as input an edge (a pair of vertices) and returns the cost
                of the edge. For more details, see the CostDistance class
                description below.

        Returns:
            least: A potentially empty list (if no path can be found) of
            the vertices in the graph. If there was a path, the first
            vertex is always start, the last is always dest in the list.
            Any two consecutive vertices correspond to some
            edge in graph.

    >>> g = Graph({1, 2, 3, 4, 5}, [(1, 4), (2, 3), (4, 2)])
    >>> location = {1: (1, 0), 2: (4, 0), 3: (10, 0), 4: (2, 0), 5: (10, 10)}
    >>> cost = CostDistance(location)
    >>> print(least_cost_path(g, 1, 2, cost))
    [1, 4, 2]
    >>> print(least_cost_path(g, 1, 3, cost))
    [1, 4, 2, 3]
    >>> print(least_cost_path(g, 1, 5, cost))
    []
    >>> H = Graph({1, 2, 3, 4, 5, 6}, [(1, 2), (2, 3), (2, 4), (4, 3), (3, 5), (1, 6), (6, 5)])
    >>> locationtwo = {1: (0, 0), 2: (1, 1), 3: (3, 1), 4: (2, 2), 5: (0, 6), 6: (-100, 100)}
    >>> testcost = CostDistance(locationtwo)
    >>> print(least_cost_path(H, 1, 5, testcost))
    [1, 2, 3, 5]
    """

    reached = {}
    events = BinaryHeap()
    events.insert((start, start), 0)

    while len(events) > 0:
        (u, v), time = events.popmin()

        if v not in reached.keys():
            reached[v] = u
            for w in graph.neighbours(v):
                events.insert((v, w), time + cost.distance((v, w)))
    '''
        reached is a dictionary of all visted verices. The value of each key is
        represented by the previous vertice visited to get to that vertice.
        If we cannot find our destination in reached, then that means there is
        no such path in the given graph to get from start to dest, and so we
        would return an empty array. otherwise, we make our list least by
        working in reverse from our dest, all the way back to start by using
        the keys in reached to find the
        previous vertice
    '''
    if dest not in reached:
        return []

    least = [dest]
    step = dest

    while step != start:
        least.append(reached[step])
        step = reached[step]

    least.reverse()
    return least
コード例 #21
0
ファイル: dijkstra.py プロジェクト: raysarinas/routefinder
def least_cost_path(graph, start, dest, cost):
    """Find and return a least cost path in graph from start vertex to dest vertex.
    Efficiency: If E is the number of edges, the run-time is
      O( E log(E) ).
    Args:
      graph (Graph): The digraph defining the edges between the
        vertices.
      start: The vertex where the path starts. It is assumed
        that start is a vertex of graph.
      dest:  The vertex where the path ends. It is assumed
        that dest is a vertex of graph.
      cost:  A class with a method called "distance" that takes
        as input an edge (a pair of vertices) and returns the cost
        of the edge. For more details, see the CostDistance class
        description below.
    Returns:
      list: A potentially empty list (if no path can be found) of
        the vertices in the graph. If there was a path, the first
        vertex is always start, the last is always dest in the list.
        Any two consecutive vertices correspond to some
        edge in graph.
    """

    reached = {} # empty dictionary
    events = BinaryHeap() # empty heap
    events.insert((start, start), 0) # vertex s burns at time 0


    while len(events) > 0:
        print("Loop 1")
        vertices, time = events.popmin()
        print(type(vertices))
        print(type(vertices[0]))
        if vertices[1] not in reached:
            reached[vertices[1]] = vertices[0]# vertices[0] = reached[vertices[1]]   burn vertex v, record predecessor u
            for n in graph.neighbours(vertices[1]):
                 # new event: edge (v,w) started burning
                print("Loop 2")
                events.insert(([vertices[1]], n), time + cost.distance((vertices[1], n)))

            if vertices[1] == dest:
                break

    #return reached
    print("Done")
    #find path to see if a path exists
    # return empty list if dest cannot be reached/if no path from start to dest exists
    if dest not in reached:
      return []

    # if the destination gets reached we can form a minimum path

    current = dest
    path = [current]

    while current != start:
        # print("Loop 3")
        print(dest)
        print(type(dest))
        current = reached[current]
        #current = reached[current]
        path.append(current)

    #or while reached[current] != start:
    #path.append(reached[current])
    #    current = reached[current]

    path = path[::-1]
    return path
コード例 #22
0
ファイル: astar.py プロジェクト: abhimita/algorithms
class AStar():
    """
    Paramaters:
        map: Reference to map object
        start_node_id: Index of start node
        dest_node_id: Index of destination node
    """
    def __init__(self, map):
        self.map = map
        # Hash set to keep track of open intersections. The hash set will contain intersection IDs only
        # and will be used to find out if an intersection ID is already there is the set
        self.open = set()
        # Hash set to keep track of closed intersection ID. The hash set will contain intersection IDs only
        # and will be used to find out
        self.closed = set()
        # Dictionary to keep track of cost. The dictionary is keyed by intersection id
        # Cost will have three components.
        # g = true of cost of getting from source node to current node
        # h = estimated cost of getting from current node to destination node
        # f = total cost = g + h
        self.cost = {}

        # List used to store the actual path from destination path back to source intersection.
        # Once the shortest path to destination intersection is found, this will be reversed and returned as path from
        # source to destination
        self.nodes_in_path = []
        # Dictionary to keep track of parent intersection. It is keyed by current intersection id.
        # Parent intersection ID is the intersection from where the current intersection is reached
        self.parent = {}
        # Initialize min binary heap. This will be used to get the intersection with minimum cost
        self.cost_heap = BinaryHeap()

    # Private method to get the intersection with minimum total cost
    def _get_node_with_min_cost(self):
        min_value_node = self.cost_heap.delete_min()
        # Remove the intersection with min cost from list of open intersections
        self.open.remove(min_value_node.id)
        # Put that intersection into closed intersections
        self.closed.add(min_value_node.id)
        return min_value_node

    # Returns the list of intersections that can be reached from the current intersection
    def _get_next_nodes(self, current_node_id):
        return self.map.roads[current_node_id]

    # Method that performs A-star search
    def search(self, start_node_id, dest_node_id):
        # Initialize the cost structure of first intersection
        self.cost[start_node_id] = {
            'g': 0, # True cost of getting from start node to this node. This is calculated in terms of number of hops (edges)
            'h': 0, # Estimated cost of getting this node to destination node
            'f': 0  # Total cost. It is a computed field f = g + h
        }
        # Put the start node as the first open node where the search starts
        self.open.add(start_node_id)
        self.cost_heap.insert(HeapNode({'id': start_node_id, 'f': 0, 'g': 0, 'h' : 0}, 'f'))
        iteration = 1
        while len(self.open) > 0:
            # Among all nodes which are open find the node with minimum total cost
            # This will be the nest node to explore
            current_node = self._get_node_with_min_cost()
            if current_node.id == dest_node_id:
                end_node = current_node.id
                while end_node is not None:
                    self.nodes_in_path.append(end_node)
                    end_node = self.parent.get(end_node, None)
                self.nodes_in_path.reverse()
                return self.nodes_in_path
            children = self._get_next_nodes(current_node.id)
            for child in children:
                # If the intersection is already in closed set then there is no need to explore it
                if child in self.closed: continue
                g = self.cost[current_node.id]['g'] + \
                    math.sqrt(
                        math.pow(self.map.intersections[current_node.id][0] - self.map.intersections[child][0], 2) + \
                        math.pow(self.map.intersections[current_node.id][1] - self.map.intersections[child][1], 2))

                # Estimate distance to destination intersection. This is pre euclidean distance.
                # This heuristic will always be less than or equal to the true distance of the road
                # connecting the two intersections
                h = math.sqrt(
                    math.pow(self.map.intersections[child][0] - self.map.intersections[dest_node_id][0], 2) + \
                    math.pow(self.map.intersections[child][1] - self.map.intersections[dest_node_id][1], 2))
                # If the child intersection is not in open set then put it in the list to explore
                # Compute the cost (cost to reach this intersection, estimated cost to reach destination
                # from here and total cost for this intersection
                # The child intersection may already be there if there way another intersection leading to this one
                # Update the cost values if cost of reaching this child intersection is lower than cost value
                # associated with the intersection
                if child not in self.open:
                    self.cost[child] = {'g' : g, 'h' : h, 'f' : g + h}
                    self.parent[child] = current_node.id
                    self.open.add(child)
                    self.cost_heap.insert(HeapNode({'id': child, 'f': g + h, 'g': g, 'h' : h}, 'f'))
                elif self.cost[child]['f'] > g + h:
                    self.cost[child] = {'g' : g, 'h' : h, 'f' : g + h}
                    self.parent[child] = current_node.id
                    self.cost_heap.build_heap()
            #if iteration >= 1:
            #    sys.exit(0)
            iteration += 1

    # Generates SVG diagram for the graph and the shortest path found using A* search
    def draw_astar_map(self, path, colors, output_file):
        graph = pydot.Dot(graph_type='graph', rankdir="LR")
        nodes = {}
        edges = set()

        for k, v in self.map.intersections.items():
            n = pydot.Node(k, shape="circle", style="filled", fillcolor="cyan" if k not in path else colors[0], tooltip="(%f,%f)" % (v[0], v[1]))
            nodes[k] = n
            graph.add_node(n)
        for src, dst in enumerate(self.map.roads):
            for d in dst:
                if (src,d) not in edges:
                    distance = math.sqrt(math.pow(self.map.intersections[src][0] - self.map.intersections[d][0], 2) + \
                                         math.pow(self.map.intersections[src][1] - self.map.intersections[d][1], 2))
                    edges.add((src,d))
                    edges.add((d,src))
                    if src in path and d in path:
                        color = colors[1]
                        style="bold"
                    else:
                        color = "black"
                        style = "dashed"
                    graph.add_edge(pydot.Edge(nodes[src], nodes[d], style=style, label="%0.2f" % distance, color=color, tooltip="%0.2f" % distance))
        graph.write_svg(output_file)
コード例 #23
0
ファイル: server.py プロジェクト: evantimms/routeFinder
    def least_cost_path(graph, start, dest, cost):
        """	Find and return a least cost path in graph from start
			vertex to dest vertex.

			Efficiency: If E is the number of edges, the run-time is
			O( E log(E) ).

			Args:
			graph (Graph): The digraph defining the edges between the
			vertices.

			start: The vertex where the path starts. It is assumed
			that start is a vertex of graph.

			dest: The vertex where the path ends. It is assumed
			that dest is a vertex of graph.

			cost: A class with a method called "distance" that takes
			as input an edge (a pair of vertices) and returns the cost
			of the edge. For more details, see the CostDistance class
			description below.

			Returns:

			list: A potentially empty list (if no path can be found) of
			the vertices in the graph. If there was a path, the first
			vertex is always start, the last is always dest in the list.
			Any two consecutive vertices correspond to some
			edge in graph.

		"""

        reached = {}  #search tree
        events = BinaryHeap()  #uses heap to store data on nodes and weights

        events.insert((start, start), 0)  #starting vertex burns at time 0

        edges = graph.get_edges

        while len(events) > 0:
            curr = events.popmin()

            u, v = curr[0][0], curr[0][1]
            time = curr[1]

            if v not in reached:
                reached[v] = u  #burn the vertex v and add u to the record

                neighbors = graph.neighbours(v)

                for w in neighbors:

                    newTime = time + cost.distance(
                        (v, w)
                    )  #stores the time taken to reach new node from previous
                    events.insert((v, w), newTime)

        shortest_path = []

        shortest_path.append(dest)
        next_node = reached[dest]

        while next_node != start:
            #iterates through the search tree from end to start,
            #collecting visited vertices and storing them in path array
            for el in reached:
                if el == next_node:
                    shortest_path.append(next_node)
                    next_node = reached[el]

        shortest_path.append(next_node)

        #removes any doubles:
        newList = []
        for el in shortest_path:
            if el not in newList:
                newList.append(el)

        return list(reversed(newList))
コード例 #24
0
class Ara:
    def __init__(self, initial_state, heuristic, weight, max_expansions):
        self.expansions = 0
        self.generated = 0
        self.initial_state = initial_state
        self.heuristic = heuristic
        self.weight = weight
        self.open = None
        self.cost = None
        self.max_expansions = max_expansions
        self.last_solution = None

    def estimate_suboptimality(self):
        cost = self.cost
        denominator = min(self.open, key=lambda x: x.g + x.h)

        denominator_num = denominator.h + denominator.g

        return cost / denominator_num

    def fvalue(self, g, h):
        return g + self.weight * h

    def adjust_weight(self):
        denominator = min(self.open, key=lambda x: x.g + x.h)
        denominator_num = denominator.h + denominator.g
        self.weight = self.last_solution.g / denominator_num

    def recalculate_open(self):
        for i in self.open:
            i.key = self.fvalue(i.g, i.h)
        self.open.reorder()

    def search(self):

        self.start_time = time.process_time()
        self.open = BinaryHeap()
        self.expansions = 0
        initial_node = Node(self.initial_state)
        initial_node.g = 0
        initial_node.h = self.heuristic(self.initial_state)
        initial_node.key = self.fvalue(0,
                                       initial_node.h)  # asignamos el valor f
        self.open.insert(initial_node)
        self.generated = {}
        self.generated[self.initial_state] = initial_node
        while self.expansions <= self.max_expansions:

            while not self.open.is_empty():

                if self.expansions >= self.max_expansions:
                    return self.last_solution

                n = self.open.extract()

                if not self.open.is_empty() and self.open.top().key == n.key:
                    tied_node = self.open.top()
                    if tied_node.g < n.g:
                        tied_node = self.open.extract()
                        self.open.insert(n)
                        n = tied_node

                if n.state.is_goal():
                    self.end_time = time.process_time()
                    self.cost = n.g
                    self.last_solution = n
                    self.adjust_weight()
                    self.recalculate_open()
                    #print('aaa')
                    yield n

                if not (self.last_solution is not None
                        and n.g + n.h >= self.last_solution.g):
                    succ = n.state.successors()
                    self.expansions += 1

                    if self.expansions >= self.max_expansions:
                        return self.last_solution

                    for child_state, action, cost in succ:
                        child_node = self.generated.get(child_state)
                        is_new = child_node is None
                        path_cost = n.g + cost
                        if is_new or path_cost < child_node.g:
                            if is_new:
                                child_node = Node(child_state, n)
                                child_node.h = self.heuristic(child_state)
                                self.generated[child_state] = child_node
                            child_node.action = action
                            child_node.parent = n
                            child_node.g = path_cost
                            child_node.key = self.fvalue(
                                child_node.g, child_node.h)
                            self.open.insert(child_node)
            self.end_time = time.process_time()
            if self.open.is_empty():
                #print("empty open")
                return self.last_solution
            #return None
        return self.last_solution
コード例 #25
0
class Astar:
    def __init__(self, initial_state, heuristic, weight=1):
        self.expansions = 0
        self.generated = 0
        self.initial_state = initial_state
        self.heuristic = heuristic
        self.weight = weight

    def estimate_suboptimality(self, result):
        costo = result.g
        mini = 1000000000
        for n in self.open:
            f = n.h + n.g
            if f < mini:
                mini = f
        return costo / mini

        print(self.open)

        return 0  # este método debe ser implementado en la parte 1

    def fvalue(self, g, h):
        return (
            g + self.weight * h, h
        )  #Esto nos permite seleccionar primero los que tienen menor h si g+h spn iguales

    def search(self):
        self.start_time = time.process_time()
        self.open = BinaryHeap()
        self.expansions = 0
        initial_node = Node(self.initial_state)
        initial_node.g = 0
        initial_node.h = self.heuristic(self.initial_state)
        initial_node.key = self.fvalue(0,
                                       initial_node.h)  # asignamos el valor f
        self.open.insert(initial_node)
        # para cada estado alguna vez generado, generated almacena
        # el Node que le corresponde
        self.generated = {}
        self.generated[self.initial_state] = initial_node
        while not self.open.is_empty():
            n = self.open.extract()  # extrae n de la open
            if n.state.is_goal():
                self.end_time = time.process_time()
                return n
            succ = n.state.successors()
            self.expansions += 1
            for child_state, action, cost in succ:
                child_node = self.generated.get(child_state)
                is_new = child_node is None  # es la primera vez que veo a child_state
                path_cost = n.g + cost  # costo del camino encontrado hasta child_state
                if is_new or path_cost < child_node.g:
                    # si vemos el estado child_state por primera vez o lo vemos por
                    # un mejor camino, entonces lo agregamos a open
                    if is_new:  # creamos el nodo de child_state
                        child_node = Node(child_state, n)
                        child_node.h = self.heuristic(child_state)
                        self.generated[child_state] = child_node
                    child_node.action = action
                    child_node.parent = n
                    child_node.g = path_cost
                    child_node.key = self.fvalue(
                        child_node.g,
                        child_node.h)  # actualizamos el valor f de child_node
                    self.open.insert(
                        child_node
                    )  # inserta child_node a la open si no esta en la open
        self.end_time = time.process_time(
        )  # en caso contrario, modifica la posicion de child_node en open
        return None
コード例 #26
0
def naive_construct_heap(alist):
    new_heap = BinaryHeap()
    for number in alist:
        new_heap.insert(number)
    return new_heap
コード例 #27
0
from binary_heap import BinaryHeap
import unittest

my_list = [8, 5, 4, 9, 3, 65, 1, 66, 599, 80]

my_heap = BinaryHeap()

for i in my_list:
    my_heap.insert(i)


class InsertTests(unittest.TestCase):
    def test_insert(self):
        my_heap.insert(2)
        self.assertTrue(my_heap.check_heap)
        my_heap.insert(0)
        self.assertTrue(my_heap.check_heap)
        my_heap.insert(500)
        self.assertTrue(my_heap.check_heap)


if __name__ == '__name__':
    unittest.main()

# command to run tests: python -m unittest -v insert_test.py
コード例 #28
0
ファイル: maze.py プロジェクト: songhzh/the-maze
class Maze:
    def __init__(self, width, length, height):
        """
        Generates all maze cells and edges
        """
        self.width = width
        self.length = length
        self.height = height
        self.generated = False
        self.graph = Graph((width, length, height))

        self.edge_queue = BinaryHeap()
        self.edges_added = 0
        self.inter_layer_edges = 0

        for x in range(width):
            for y in range(length):
                for z in range(height):
                    self.graph.add_vertex((x, y, z))

        self.areas = UnionFind([cell.get_pos() for cell in self])
        self.edge_choices = RandomSet(self.graph.get_all_edges())
        self.queue_factor = len(self.edge_choices) // LAYER_FACTOR

        for _ in range(self.queue_factor):
            edge = self.edge_choices.pop_random()
            self._queue_edge(edge)

        self.player = self.graph.get_cell((0, 0, 0))

        self.end_cell = self.graph.get_cell(
            (self.width - 1, self.length - 1, self.height - 1))
        self.end_cell.is_end = True

    def __iter__(self):
        """
        Returns an iterator to the start of the grid
        """

        self._i = 0
        self._j = 0
        self._k = 0

        return self

    def __next__(self):
        """
        Returns the next cell in the grid
        """

        if self._i < self.width and self._j < self.length \
                and self._k < self.height:

            next_cell = self.graph.get_cell((self._i, self._j, self._k))

            self._i += 1
            if self._i == self.width:
                self._i = 0
                self._j += 1
            if self._j == self.length:
                self._j = 0
                self._k += 1

            return next_cell
        else:
            # Done iterating over cells
            raise StopIteration

    def get_layer(self, layer):
        return self.graph.get_layer(layer)

    def get_player(self):
        return self.player

    def generate(self):
        """
        Links two random, adjacent cells from different partitions
        """
        # Loop until we have removed a wall
        while not self.generated:

            # chooses a random item from all possible edges
            # and removes this choice
            if len(self.edge_choices) > 1:
                self._queue_edge(self.edge_choices.pop_random())

            (p1, p2), _ = self.edge_queue.popmin()

            # adds an edge (removes a wall) if it is valid
            if self.areas.union(p1, p2):
                self.graph.add_edge((p1, p2))
                return self.graph.get_cell(p1), self.graph.get_cell(p2)

            # Check if maze is completely generated
            if len(self.edge_queue) == 0:
                self.generated = True

        return None

    def _queue_edge(self, edge):
        """
        Put an edge into a queue to be generated. We use this to limit the amount of
        inter-layer edges being generated by making them cost more, which adds them
        progressively later to the maze. Thus, they are less likely to connect disjoint
        partitions, and less likely to be generated at all
        """

        if edge[0][2] != edge[1][2]:
            cost = self.queue_factor * self.inter_layer_edges
            self.inter_layer_edges += 1
        else:
            cost = self.edges_added
            self.edges_added += 1

        self.edge_queue.insert(edge, cost)

    def player_move(self, dx, dy, dz):
        """
        checks if an edge exists between current and next cell
        if so, update player
        """
        p1 = self.player.get_pos()
        p2 = self.player.x + dx, self.player.y + dy, self.player.z + dz

        c1 = self.graph.get_cell(p1)

        if self.graph.is_edge((p1, p2)):
            self.player = self.graph.get_cell(p2)

            c2 = self.graph.get_cell(p2)

            if c2.visited:
                c1.visited = False
                c2.visited = False
            else:
                c1.flip_visit()

            return c1, c2
        else:
            return c1, c1

    def check_layer(self, new_layer):
        """
        Clamps layer to be valid
        """
        if new_layer < 0:
            return 0
        elif new_layer >= self.height:
            return self.height - 1
        else:
            return new_layer
コード例 #29
0
from binary_heap import BinaryHeap

if __name__ == "__main__":
    items = [3, 4, 10, 1, 6, 5]
    # items = ['T', 'P', 'R', 'N', 'H', 'O', 'A', 'E', 'I', 'G']

    priorityQueue = BinaryHeap(len(items))

    for item in items:
        priorityQueue.insert(item)

    print "BEFORE: ",
    for i in range(1, len(priorityQueue.pq)):
        print priorityQueue.pq[i],

    print
    print "DELETED: " + str(priorityQueue.delMax())

    print "AFTER: ",
    for i in range(1, priorityQueue.N + 1):
        print priorityQueue.pq[i],

    print
    print "DELETED: " + str(priorityQueue.delMax())

    print "AFTER: ",
    for i in range(1, priorityQueue.N + 1):
        print priorityQueue.pq[i],
コード例 #30
0
ファイル: main.py プロジェクト: nlantau/Portfolio
def create_heap_for_loop_insert(unsorted_list):
    bh = BinaryHeap()
    for num in unsorted_list:
        bh.insert(num)
    x = f"{'Heap list ':<15}"
    return x, bh