コード例 #1
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
コード例 #2
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
コード例 #3
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
コード例 #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
ファイル: 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
コード例 #7
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
コード例 #8
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
コード例 #9
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)
コード例 #10
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
コード例 #11
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))
コード例 #12
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
コード例 #13
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