Example #1
0
def get_char_freq(file_name):
    """
    gets the sorted list of character frequencies
    :param file_name: the file to parse through
    :type file_name: str
    :return: the huffman tree and char count
    """
    char_frequency = {}

    with open(file_name) as to_encode:
        cur_char = to_encode.read(1)
        while cur_char:
            if char_frequency.has_key(cur_char):
                char_frequency[cur_char] += 1
            else:
                char_frequency[cur_char] = 1
            cur_char = to_encode.read(1)

    # create the huffman list of nodes sorted by count
    nodes = PriorityQueue()

    # adds the initial nodes to the list
    for node_char, node_freq in char_frequency.iteritems():
        nodes.put(h_node(None, None, node_freq, node_char), node_freq)

    # create the tree of nodes required to get the character codes
    while nodes.count() > 1:
        # get the two smallest nodes
        h_node_a = nodes.get()
        h_node_b = nodes.get()
        freq_sum = h_node_a.frequency + h_node_b.frequency
        nodes.put(h_node(h_node_a, h_node_b, freq_sum, None), freq_sum)

    return nodes.get()
    def search(self, start, end):
        frontier = PriorityQueue()
        frontier.put(0, start)

        cost_so_far = dict()
        cost_so_far[start] = 0

        came_from = dict()
        came_from[start] = None

        while not frontier.is_empty():
            pri, current = frontier.get()

            if current == end:
                self.paths[start].update(self.reconstruct_path(end, came_from))
                break

            neighbors = [
                neighbor.end for neighbor in self.graph.neighbors(current)
            ]
            for neighbor in neighbors:
                new_cost = cost_so_far[current] + self.graph.cost(
                    current, neighbor)
                if neighbor not in cost_so_far.keys(
                ) or new_cost < cost_so_far[neighbor]:
                    cost_so_far[neighbor] = new_cost
                    came_from[neighbor] = current
                    frontier.put(new_cost, neighbor)
Example #3
0
    def search(self, initial_state_data, manhattan_distance, max_nodes=0):
        assert isinstance(initial_state_data, Search.NodeStateData)
        assert isinstance(manhattan_distance, bool)
        heuristic = "h2cost" if manhattan_distance else "h1cost"
        current_node = self.__create_node(initial_state_data, heuristic)
        frontier = PriorityQueue()  # nodes we're looking at now
        frontier.push(current_node, current_node.search_data.fcost)
        explored = set()  # nodes we've looked at and needn't again

        while True:
            if frontier.empty() or (0 < max_nodes <=
                                    len(frontier) + len(explored)):  # failure
                return None
            current_node = frontier.pop()
            # print(current_node.state_data.get_tiles())
            if current_node.state_data.goal_test:  # success
                return Search.build_solution(current_node.state_data)
            if current_node not in explored:  # mark the current node as explored if not already
                explored.add(current_node)
                # print("moved ", str(current_node.state_data.last_move), " to " + str(current_node.state_data.parent),
                # str(current_node.search_data.fcost))
            # expand unexplored neighbors, updating their path cost if a better one is found
            for prioritized_neighbor_node in self.__prioritize_neighbors(
                    current_node, heuristic):
                neighbor_node = prioritized_neighbor_node[1]
                if (neighbor_node not in explored) and (
                        not frontier.contains(neighbor_node)):
                    frontier.push(neighbor_node, prioritized_neighbor_node[0])
                elif frontier.contains(neighbor_node) and (
                        frontier.get(neighbor_node).search_data.fcost >
                        neighbor_node.search_data.fcost):
                    frontier.replace(neighbor_node)
Example #4
0
    def a_star_search(self, start, goal):
        frontier = PriorityQueue()
        frontier.put(start, 0)

        came_from = {}
        cost_so_far = {}

        came_from[start] = start
        cost_so_far[start] = 0

        while not frontier.empty():
            current = frontier.get()
            if current.position_x == goal.position_x and current.position_y == goal.position_y:
                break

            for next in self.neighbors(current):
                next_cell = Cell(next[0], next[1])

                if next_cell.position_x == goal.position_x and next_cell.position_y == goal.position_y:
                    next_cell = goal
                new_cost = cost_so_far[current] + self.heuristic(current, next_cell)

                if next_cell not in cost_so_far or new_cost < cost_so_far[next_cell]:
                    cost_so_far[next_cell] = new_cost
                    priority = new_cost + self.heuristic(goal, next_cell)
                    frontier.put(next_cell, priority)
                    came_from[next_cell] = current

        return came_from  # , cost_so_far
Example #5
0
def dijkstra_search(graph, start, goal):
    frontier = PriorityQueue()
    frontier.put(start, 0)

    # different from first implementation in that it remembers
    # WHERE we came from, not just that we visited it
    came_from = {}
    cost_so_far = {}
    came_from[start] = None
    cost_so_far[start] = 0

    while not frontier.empty():
        # from front of the queue
        current = frontier.get()
        # print("Visiting ", current)

        # main difference from implementation 2
        if current == goal:
            break

        # get neighbors of current node
        # add it to back of frontier queue if not yet visited
        for next in graph.neighbors(current):
            new_cost = cost_so_far[current] + graph.cost(current, next)
            if next not in cost_so_far or new_cost < cost_so_far[next]:
                cost_so_far[next] = new_cost
                priority = new_cost
                frontier.put(next, priority)
                came_from[next] = current

    return came_from, cost_so_far
Example #6
0
 def search(self, startHex, goalHex):
     startNode = HexNode(startHex, None)
     goalNode = HexNode(goalHex, None)
     frontier = PriorityQueue()
     frontier.put(startNode, 0)
     cameFrom = {}
     currCost = {}
     cameFrom[startNode] = None
     currCost[startNode] = 0
     
     while not frontier.empty():
         currNode = frontier.get()
         
         if currNode.h == goalNode.h:
             break
         
         for nextNode in self.getNeighborNodes(currNode.h):
             newCost = currCost[currNode] + self.cost(currNode, nextNode)
             if nextNode not in currCost or newCost < currCost[nextNode]:
                 currCost[nextNode] = newCost
                 priority = newCost + HexMap.heuristic(goalNode, nextNode)
                 frontier.put(nextNode, priority)
                 cameFrom[nextNode] = currNode
     
     return cameFrom, currCost
def dijkstra(start, C):
    openSet = PriorityQueue()
    openSet_check = {}

    closedSet = {}
    g = {}
    for i in range(len(start)):
        g[start[i]] = 0

    for i in range(len(start)):
        openSet.put(start[i], 0)
        openSet_check[start[i]] = 1

    while not openSet.empty():
        currentState = openSet.get()
        closedSet[currentState] = 1
        for nextState in get_successors(currentState):
            if nextState in closedSet:
                continue

            newCost = g[currentState] + get_cost(C, nextState)
            if nextState not in openSet_check:
                g[nextState] = newCost
                openSet.put(nextState, g[nextState])
                openSet_check[nextState] = 1
            elif newCost >= g[nextState]:
                continue

            else:
                g[nextState] = newCost
                openSet.update(nextState, g[nextState])
                openSet_check[nextState] = 1

    temp = ''
    #For printing the H as a grid:
    '''for i in range(N):
		for j in range(N):
			if j==0:
				temp +=str(g[(i,j)])			
			else:
				temp +=','+str(g[(i,j)])
		temp += "\n"
	print temp'''

    #For writing the H onto a file
    f = open('heuristic.txt', 'w')
    temp = ''
    for i in range(N):
        temp = ''
        for j in range(N):
            if j == 0:
                temp += str(g[(i, j)])
            else:
                temp += ',' + str(g[(i, j)])
        if i == 0:
            f.write(temp)
        else:
            f.write('\n' + temp)
    f.close()
    return False
    def a_star_search(self, start, goal):
        self.graph2D.reset()
        #Push start into frontier
        frontier = PriorityQueue()
        frontier.put(start, 0)

        # Create a dictionary that contains previous position of current position
        parent = {}
        # Create a dictionary that contains cost_so_far[current_position] = sum up cost from start to current_position
        cost_so_far = {}

        # Initilization dictionary
        parent[start] = None
        parent[goal] = None
        cost_so_far[start] = 0
        while not frontier.empty():
            # Get position from front positions (previous position)
            current = frontier.get()
            # If you are standing at goal to stop
            if current == goal:
                break

            # Get adjacent vertices
            for next in self.graph2D.get_neighbors(current):
                #Update new_cost
                new_cost = cost_so_far[current] + 1
                # Checking is in cost_so_far or new_cost is smaller than old_cost
                if next not in cost_so_far or new_cost < cost_so_far[next]:
                    #Update new cost
                    cost_so_far[next] = new_cost
                    priority = new_cost + self.heuristic(goal, next)
                    #Update frontier and parent
                    frontier.put(next, priority)
                    parent[next] = current
        return self.backtrace(parent, start, goal)
Example #9
0
def a_star_search(graph, start, goal):
    frontier = PriorityQueue()
    frontier.put(start, 0)

    came_from = {}
    cost_so_far = {}
    came_from[start] = None
    cost_so_far[start] = 0

    while not frontier.empty():
        current = frontier.get()

        if current == goal:
            break

        for next in graph.neighbors(current):
            new_cost = cost_so_far[current] + graph.cost(current, next)
            if next not in cost_so_far or new_cost < cost_so_far[next]:
                cost_so_far[next] = new_cost
                priority = new_cost + heuristic(
                    goal, next
                )  # reduce priority for positions further away from goal
                frontier.put(next, priority)
                came_from[next] = current

    return came_from, cost_so_far
Example #10
0
    def a_star_search(self, start, goal):
        frontier = PriorityQueue()
        frontier.put(start, 0)

        came_from = {}
        cost_so_far = {}

        came_from[start] = start
        cost_so_far[start] = 0

        while not frontier.empty():
            current = frontier.get()
            if current.position_x == goal.position_x and current.position_y == goal.position_y:
                break

            for next in self.neighbors(current):
                next_cell = Cell(next[0], next[1])

                if next_cell.position_x == goal.position_x and next_cell.position_y == goal.position_y:
                    next_cell = goal
                new_cost = cost_so_far[current] + self.heuristic(
                    current, next_cell)

                if next_cell not in cost_so_far or new_cost < cost_so_far[
                        next_cell]:
                    cost_so_far[next_cell] = new_cost
                    priority = new_cost + self.heuristic(goal, next_cell)
                    frontier.put(next_cell, priority)
                    came_from[next_cell] = current

        return came_from  # , cost_so_far
    def a_star(self):
        # Genera camino usando el algoritmo A*
        frontier = PriorityQueue()
        frontier.put(self.start, 0)
        came_from = {}
        cost_so_far = {}
        came_from[self.start] = None
        cost_so_far[self.start] = 0

        # comienza la busqueda
        while not frontier.empty():
            current = frontier.get()
            # termina si llega a la meta
            if current == self.goal:
                break
            # busca en sus vecinos
            for next in self.graph.neighbors(current):
                new_cost = cost_so_far[current] + self.graph.cost(
                    current, next)
                if next not in cost_so_far or new_cost < cost_so_far[next]:
                    cost_so_far[next] = new_cost
                    priority = new_cost + self.cost(self.posiciones[self.goal],
                                                    self.posiciones[next])
                    frontier.put(next, priority)
                    came_from[next] = current
        # ordena el plan
        current = self.goal
        path = [current]
        while current != self.start:
            current = came_from[current]
            path.append(current)
        # invierte el camino para empezar al inicio
        path.reverse()
        self.plan = path
Example #12
0
    def a_star_search(self, start, goal):
        frontier = PriorityQueue()
        frontier.put(start, 0)
        came_from = {}
        cost_so_far = {}
        came_from[start.get_key()] = None
        cost_so_far[start.get_key()] = 0

        while not frontier.empty():
            current = frontier.get()

            if current == goal:
                break

            for point in self.graph.neighbors(current):
                move_cost = self.graph.cost(current, point)
                new_cost = cost_so_far[current.get_key()] + move_cost
                if point is None:
                    continue
                if point.get_key(
                ) not in cost_so_far or new_cost < cost_so_far[
                        point.get_key()]:
                    cost_so_far[point.get_key()] = new_cost
                    priority = new_cost + self.heuristic(goal, point)
                    frontier.put(point, priority)
                    came_from[point.get_key()] = current

        #return came_from, cost_so_far
        return came_from
Example #13
0
def astar(maze, start, goal):

    pq = PriorityQueue()
    pq.put(start, 0)
    predecessor = {start: None}
    g_value = {start: 0}

    while not pq.is_empty():

        current_cell = pq.get()

        if current_cell == goal:
            return get_path(predecessor, start, goal)

        for directions in ["up", "right", "down", "left"]:
            row_offset, col_offset = offsets[directions]
            neighbor = (current_cell[0] + row_offset,
                        current_cell[1] + col_offset)

            if is_legal_pos(maze, neighbor) and neighbor not in g_value:
                g_value[neighbor] = g_value[current_cell] + 1
                f_value = g_value[neighbor] + heuristic(neighbor, goal)
                pq.put(neighbor, f_value)
                predecessor[neighbor] = current_cell

    return None
Example #14
0
def Astar(start, goal, C, im):
    """Input: Start state, Goal State, Cost map and original map
   	Output: Bool value False after completion of the algorithm
   	This function performs the A-Star algorithm to find the shortest path to the goal
    	"""
    openSet = PriorityQueue()
    openSet.put(start, 0)
    openSet_check = {}
    openSet_check[start] = 1
    closedSet = {}
    plan = {}
    g = {}
    g[start] = 0
    f = {}
    j = 0
    f[start] = get_heuristic(start, goal)
    p = 0
    while not openSet.empty():
        currentState, fpop = openSet.get()
        if currentState == goal:
            print "Path found!"
            path = reconstruct_path(plan, currentState)
            path.reverse()
            get_totalCost(path, C)
            visualize(path, C, im)
            #for i in range(len(path)):
            #	print path[i]
            break

        closedSet[currentState] = 1
        for nextState in get_successors(currentState):
            j = j + 1
            if nextState in closedSet:
                continue

            newCost = g[currentState] + get_cost(C, nextState)
            if nextState not in openSet_check:
                plan[nextState] = currentState
                g[nextState] = newCost
                f[nextState] = g[(nextState)] + get_heuristic(
                    currentState, nextState)

                openSet.put(nextState, f[nextState])
                openSet_check[nextState] = 1
                continue

            elif newCost >= g[nextState]:
                openSet_check[nextState] = 1
                continue

            plan[nextState] = currentState
            g[nextState] = newCost
            f[nextState] = g[(nextState)] + get_heuristic(
                currentState, nextState)

            openSet.put(nextState, f[nextState])
            openSet_check[nextState] = 1

    return False
Example #15
0
 def algorithm_Prim(self, start_position):
     priority_queue = PriorityQueue(self.size)
     self.visited = [False] * (self.size + 1)
     self.visited[start_position] = True
     self.insert_to_priority_queue_from(start_position, priority_queue)
     while self.visited.count(True) < len(self.nodes):
         target = priority_queue.get()
         self.visited_history.append((target[1], target[0]))
         position = target[0]
         self.visited[position] = True
         self.insert_to_priority_queue_from(position, priority_queue)
     self.__show_graph__()
Example #16
0
def Astar(start, goal, C):
    openSet = PriorityQueue()
    openSet.put(start, 0)
    openSet_check = {}
    openSet_check[start] = 1
    closedSet = {}
    plan = {}
    g = {}
    g[start] = 0
    f = {}
    j = 0
    f[start] = get_heuristic(start)
    p = 0
    while not openSet.empty():
        currentState, fpop = openSet.get()
        if currentState in goal:
            path = reconstruct_path(plan, currentState)
            path.reverse()
            get_totalCost(path, C)
            visualize(path, C)
            for i in range(len(path)):
                print path[i]
            break

        closedSet[currentState] = 1
        for nextState in get_successors(currentState):
            j = j + 1
            if nextState in closedSet:
                continue

            newCost = g[currentState] + get_cost(C, nextState)
            if nextState not in openSet_check:
                plan[nextState] = currentState
                g[nextState] = newCost
                f[nextState] = g[(nextState)] + get_heuristic(nextState)

                openSet.put(nextState, f[nextState])
                openSet_check[nextState] = 1
                continue

            elif newCost >= g[nextState]:
                openSet_check[nextState] = 1
                continue

            plan[nextState] = currentState
            g[nextState] = newCost
            f[nextState] = g[(nextState)] + get_heuristic(nextState)

            openSet.put(nextState, f[nextState])
            openSet_check[nextState] = 1
    return False
def dijkstra(start, C):
    """Input: Start state and Cost map
	Output: The cost of each cell as a dictionary
	This function performs the Dijkstra algorithm to find the cost of each cell in the map
	"""
    openSet = PriorityQueue()
    openSet_check = {}
    closedSet = {}
    g = {}
    for i in range(len(start)):
        g[start[i]] = 0
        openSet.put(start[i], 0)
        openSet_check[start[i]] = 1

    while not openSet.empty():
        currentState = openSet.get()
        closedSet[currentState] = 1
        for nextState in get_successors(currentState):
            if nextState in closedSet:
                continue
            newCost = g[currentState[0]] + get_cost(nextState)
            if nextState not in openSet_check:
                g[nextState] = newCost
                openSet.put(nextState, g[nextState])
                openSet_check[nextState] = 1
                continue

            elif newCost >= g[nextState]:
                continue

            g[nextState] = newCost
            openSet.put(nextState, g[nextState])
            openSet_check[nextState] = 1

    # This writes the cost values onto a file which is accessed by the A-star algorithm
    # for the planning part
    f = open('heuristic.txt', 'w')
    temp = ''
    for i in range(M):
        temp = ''
        for j in range(N):
            if j == 0:
                temp += str(g[(i, j)])
            else:
                temp += ',' + str(g[(i, j)])
        if i == 0:
            f.write(temp)
        else:
            f.write('\n' + temp)
    f.close()
    return g
def Dijkstra(G, v0):
    inf = float("+inf")
    dist = [inf] * len(G)
    prev = [None] * len(G)
    dist[v0] = 0
    Q = PriorityQueue()
    for i in range(len(dist)):
        Q.put(i, dist[i])
    while not Q.empty():
        u,d = Q.get()
        for w in range(len(G)):
            if G[u][w] and w in Q and dist[u] + G[u][w] < dist[w]:
                dist[w] = dist[u] + G[u][w]
                prev[w] = u
                Q.update(w, dist[w])
    return dist
def dijkstra(start,C):
	openSet = PriorityQueue()
	openCheck = {}
	closedSet = {}
	g = {}
	for i in range(len(start)):
		g[start[i]] = 0
	for i in range(len(start)):
		openSet.put(start[i],0)
		openCheck[start[i]] = 1
	while not openSet.empty():
		currentState = openSet.get()
		closedSet[currentState] = 1
		for nextState in getSuccessors(currentState):
			if nextState in closedSet:
				continue

			newCost = g[currentState] + cost(C,nextState)
			if nextState not in openCheck:
				g[nextState] = newCost
				openSet.put(nextState,g[nextState])
				openCheck[nextState] = 1
			elif newCost >= g[nextState]:
				continue
			else:
				g[nextState] = newCost
				openSet.update(nextState,g[nextState])
				openCheck[nextState] = 1

	hmap = open('heuristic.txt','w')
	temp=''
	for i in range(N):
		temp=''
		for j in range(N):
			if j==0:
				temp +=str(g[(i,j)])			
			else:
				temp +=','+str(g[(i,j)]) 
		if i==0:
			hmap.write(temp)
		else:
			hmap.write('\n'+temp)	
	hmap.close()
	return False
Example #20
0
    def findPath(self, gridMap):
        print("A*.findpath()")

        startCell = gridMap.getCellOfType(CellConstants.START_CELL)
        goal = gridMap.getCellOfType(CellConstants.FINISH_CELL)

        openSet = PriorityQueue()
        openSet.put(startCell, 0)

        gScore = {}  #cost so far
        gScore[startCell] = 0.0
        #
        fScore = {}
        fScore[startCell] = self.cbDist(
            startCell.position, goal.position,
            1.0)  #calculate huristic (h()) and add to g() to get f()

        cameFrom = {}
        cameFrom[startCell] = None

        while not openSet.empty():
            current = openSet.get()

            if current == goal:
                print("Goal reached")
                waypoints = self.reconstructPath(cameFrom, current)
                return waypoints

            #Get neighboring cells
            t = gridMap.getNeighbors(current)
            for next in t:

                tentative_gScore = gScore[current] + next.cost
                if next not in gScore or tentative_gScore < gScore.setdefault(
                        next, float('inf')):
                    gScore[next] = tentative_gScore
                    fScore[next] = gScore[next] + self.cbDist(
                        next.position, goal.position, 1.0)
                    openSet.put(next, fScore[next])
                    cameFrom[next] = current

        print("Path not Found")
        return None
Example #21
0
def a_star_search(graph, start, finish):
    frontier = PriorityQueue()
    frontier.put(start, 0)
    came_from = {}
    cost_so_far = {}
    came_from[start] = None
    cost_so_far[start] = 0

    while not frontier.empty():
        current = frontier.get()

        if current == finish:
            break

        for next in graph.neighbors(current):
            new_cost = cost_so_far[current] + graph.cost(current, next)
            if next not in cost_so_far or new_cost < cost_so_far[next]:
                cost_so_far[next] = new_cost
                priority = new_cost + heuristic(finish, next)
                frontier.put(next, priority)
                came_from[next] = current

    return came_from, cost_so_far
    def shortest_path_with_moving_polygons(self, start, goal, pick_up_points):
        self.graph2D.reset()
        frontier = PriorityQueue()
        frontier.put(start, 0)

        parent = {}
        cost_so_far = {}

        parent[start] = None
        parent[goal] = None
        cost_so_far[start] = 0
        trace = []
        self.history.append(self.graph2D.polygons)

        while not frontier.empty():
            current = frontier.get()

            trace.append(current)

            if current == goal:
                break

            forbidden_points = [start, goal]
            for point in pick_up_points:
                forbidden_points.append(point)

            self.graph2D.move_polygons(forbidden_points)
            self.history.append(self.graph2D.polygons)

            for next in self.graph2D.get_neighbors(current):
                new_cost = cost_so_far[current] + 1
                if next not in cost_so_far or new_cost < cost_so_far[next]:
                    cost_so_far[next] = new_cost
                    priority = new_cost + self.heuristic(goal, next)
                    frontier.put(next, priority)
                    parent[next] = current
        return self.backtrace(parent, start, goal), trace
Example #23
0
    def dijkstra(self, G, start, end=None):

        D = {} # dictionary of final distances
        P = {} # dictionary of predecessors
        Q = PriorityQueue() # estimated distances of non-final vertices
        Q[start] = 0 # add zero cost

        for v in Q:
            D[v] = Q[v]

            if v == end:
                break

            for w in G.getVertex(v).adjacencies:
                vwLength = D.get(v) + G.vertexAdjacencies(v).get(w).getcost()

                if w in D:
                    if vwLength < D.get(w):
                        raise ValueError("Dijkstra: found better path to already-final vertex")
                elif w not in Q or vwLength < Q.get(w):
                    Q[w] = vwLength
                    P[w] = v

        return D, P
Example #24
0
def dijkstra(graph: Graph,
             s,
             g,
             starter_tickets=[],
             start_cost=0,
             previous_path=[],
             reversable_nodes=[],
             is_recurrency_dijkstra=False):
    start = graph.getNodeById(s)
    goal = graph.getNodeById(g)
    frontier = PriorityQueue()
    frontier.put(start, 0)
    came_from = {start.id: None}
    start_tickets = set(starter_tickets)
    if start.group is not None:
        start_tickets.add(start.group)
    tickets_earned = {start.id: start_tickets}
    cost_so_far = {start.id: start_cost}
    reverse_states = []

    while not frontier.empty():
        current = frontier.get()
        if current == goal:
            break

        if current.id in reversable_nodes:
            if came_from[
                    current.
                    id] is not None and current.group not in tickets_earned[
                        came_from[current.id]] and current.group != 0:
                reverse_states.append(
                    (reconstruct_path(came_from, s, current.id),
                     cost_so_far[current.id], tickets_earned[current.id]))
            elif came_from[
                    current.
                    id] is None and not is_recurrency_dijkstra and current.group != 0:
                reverse_states.append(([current.id], cost_so_far[current.id],
                                       tickets_earned[current.id]))

        for i in graph.getNeighbors(current.id).values():
            next_node = graph.getNodeById(i.id)
            new_tickets = set(tickets_earned[current.id])
            new_tickets.add(next_node.group)
            new_cost = graph.getCost(
                current, next_node,
                tickets_earned[current.id]) + cost_so_far[current.id]

            if next_node.id not in cost_so_far or new_cost < cost_so_far[
                    next_node.id]:
                cost_so_far[next_node.id] = new_cost
                priority = new_cost
                frontier.put(next_node, priority)
                came_from[next_node.id] = current.id
                tickets_earned[next_node.id] = new_tickets

    best_path = previous_path + reconstruct_path(came_from, start.id, goal.id)
    best_cost = cost_so_far[goal.id]
    best_tickets = tickets_earned[goal.id]

    for state in reverse_states:  # state = previous_path, previous_cost, previous_tickets
        p, c, t = dijkstra(graph=graph,
                           s=state[0][-1],
                           g=g,
                           starter_tickets=state[2],
                           start_cost=state[1],
                           previous_path=state[0],
                           reversable_nodes=reversable_nodes,
                           is_recurrency_dijkstra=True)
        if c < best_cost:
            best_path = p
            best_cost = c
            best_tickets = t

    best_path = clean_path(
        best_path
    )  # clean path from 'duplicates' e.g [1, 0, 0, 2] -> [1,0,2]. Duplicates occur due to recurrency dijkstra

    return best_path, best_cost, best_tickets
Example #25
0
class PathFinder(object):
    def __init__(self, bzrc, tank_index):
        self.bzrc = bzrc
        self.points = []
        self.edges = []
        self.visibility_graph = None

        self.frontier = []
        self.visited = []
        self.path = []

        self.search_snapshots = []
        self.create_visibility_graph(tank_index)

    def get_path(self):
        return self.get_a_star_path()

    ########################
    ### VISIBILITY GRAPH ###
    ########################

    def create_visibility_graph(self, tank_index):
        print "Generating Visibility Graph for Tank", tank_index

        tank = self.bzrc.get_mytanks()[tank_index]
        self.points = []

        # append tank position to points, this MUST be the first point in this list (we're relying on that for
        # our search algorithms below)
        self.points.append((tank.x, tank.y))

        # append goal flag position to points
        flags = self.bzrc.get_flags()
        for flag in flags:
            if tank.flag != '-' and flag.color in tank.callsign:        # if the tank has the flag, go home
                self.points.append((flag.x, flag.y))                    # TODO: this line only works if the other team hasn't already taken our flag and run with it. We should probably use our base instead...
                break
            elif flag.color not in tank.callsign:                       # if the tank has no flag, go for one
                self.points.append((flag.x, flag.y))
                break

        # append obstacle corners to points, and obstacle edges to our list of edges
        for obstacle in self.bzrc.get_obstacles():
            i = 0
            for point in obstacle:
                self.points.append(point)
                self.edges.append([point, obstacle[(i+1) % len(obstacle)]])
                i += 1

        # initialize the visibility graph to all -1's
        length = len(self.points)
        self.visibility_graph = [[-1 for _ in range(length)] for _ in range(length)]

        # figure out the visibility between each pair of points
        for col in range(length):
            for row in range(length):
                if self.visibility_graph[row][col] == -1:  # we haven't considered this pair of points yet
                    if self.is_visible(self.points[col], self.points[row]):
                        # "if you are visible to me, than I am visible to you" mentality
                        self.visibility_graph[row][col] = 1
                        self.visibility_graph[col][row] = 1
                    else:
                        # "if you are not visible to me, than I am not visible to you" mentality
                        self.visibility_graph[row][col] = 0
                        self.visibility_graph[col][row] = 0

        # remove any edges that are on the very edge of the map (and therefore couldn't be traversed by the tank)
        self.remove_visibility_on_world_edges()


    def update_visibility_graph(self, tank_index):
        tank = self.bzrc.get_mytanks()[tank_index]
        self.points[0] = (tank.x, tank.y)  # update the tank position

        # update goal flag position in points
        flags = self.bzrc.get_flags()
        for flag in flags:
            if tank.flag != '-' and flag.color in tank.callsign:        # if the tank has the flag, go home
                self.points[1] = (flag.x, flag.y)                    # TODO: this line only works if the other team hasn't already taken our flag and run with it. We should probably use our base instead...
                break
            elif tank.flag == '-' and flag.color not in tank.callsign:                       # if the tank has no flag, go for one
                self.points[1] = (flag.x, flag.y)
                break

        # update the first two rows and columns in our visibility graph (these are the only points that have changed)
        # initialize the visibility graph to all -1's
        length = len(self.points)

        # figure out the visibility between each pair of points
        for col in range(length):
            for row in range(length):
                if col > 1 and row > 1:
                    continue

                if self.is_visible(self.points[col], self.points[row]):
                    # "if you are visible to me, than I am visible to you" mentality
                    self.visibility_graph[row][col] = 1
                    self.visibility_graph[col][row] = 1
                else:
                    # "if you are not visible to me, than I am not visible to you" mentality
                    self.visibility_graph[row][col] = 0
                    self.visibility_graph[col][row] = 0

    def is_visible(self, point1, point2):
        # check if they are the same point...a point is not visible to itself
        if point1 == point2:
            return False

        # check if they share an edge
        p1_found = False
        for edge in self.edges:
            if point1 in edge:
                p1_found = True
                if point2 in edge:
                    return True

        # check if they are both in the same obstacle (but obviously don't share an edge because of the case above)
        if p1_found:
            for obstacle in self.bzrc.get_obstacles():
                if point1 in obstacle and point2 in obstacle:
                    return False

        # check if there are any intersecting edges between these two points
        temp_edge = [point1, point2]
        for edge in self.edges:
            if self.line_segments_intersect(temp_edge, edge):
                return False

        # No edges intersected, these two points are visible to each other
        return True

    # Determines if two line segments intersect by checking that the two ends of one segment are on different sides
    # of the other segment, AND vise-versa (both conditions must be true for the line segments to intersect).
    # See http://stackoverflow.com/questions/7069420/check-if-two-line-segments-are-colliding-only-check-if-they-are-intersecting-n
    # for further explanation & math.
    def line_segments_intersect(self, edge1, edge2):
        # if both points of edge1 are on the same side of edge2, or one of edge1's points is on edge2
        # then we already know the lines aren't crossing over each other.
        cp1 = self.cross_product(edge1[0], edge2)
        cp2 = self.cross_product(edge1[1], edge2)
        if (cp1 > 0 and cp2 > 0) or (cp1 < 0 and cp2 < 0) or cp1 == 0 or cp2 == 0:
            return False

        # if both points of edge2 are on the same side of edge1, or one of edge2's endpoints is on edge1
        # then we know the lines aren't crossing over each other
        cp1 = self.cross_product(edge2[0], edge1)
        cp2 = self.cross_product(edge2[1], edge1)
        if (cp1 > 0 and cp2 > 0) or (cp1 < 0 and cp2 < 0) or cp1 == 0 or cp2 == 0:
            return False

        return True

    # Returns the cross product between the given line segment and the vector from that line segment to the given point
    def cross_product(self, point, segment):
        seg_start = segment[0]
        seg_end = segment[1]
        x = 0
        y = 1

        return (seg_end[x]-seg_start[x]) * (point[y]-seg_end[y]) - (seg_end[y]-seg_start[y]) * (point[x]-seg_end[x])

    def remove_visibility_on_world_edges(self):
        length = len(self.points)

        for index1 in range(length):
            point1 = self.points[index1]

            # check left edge
            if point1[0] == -400:  # the x value is on the left edge of the map
                for index2 in range(length):
                    point2 = self.points[index2]
                    if self.visibility_graph[index1][index2] == 1 and point2[0] == -400:  # both of these points' x values are on the left edge of the map
                        self.visibility_graph[index1][index2] = 0  # make them invisible to each other
                        self.visibility_graph[index2][index1] = 0

            # check right edge
            elif point1[0] == 400:  # the x value is on the right edge of the map
                for index2 in range(length):
                    point2 = self.points[index2]
                    if self.visibility_graph[index1][index2] == 1 and point2[0] == 400:  # both of these points' x values are on the edge of the map
                        self.visibility_graph[index1][index2] = 0  # make them invisible to each other
                        self.visibility_graph[index2][index1] = 0

            # check top edge
            elif point1[1] == 400:  # the y value is on the top edge of the map
                for index2 in range(length):
                    point2 = self.points[index2]
                    if self.visibility_graph[index1][index2] == 1 and point2[1] == 400:  # both of these points' y values are on the top edge of the map
                        self.visibility_graph[index1][index2] = 0  # make them invisible to each other
                        self.visibility_graph[index2][index1] = 0

            # check bottom edge
            elif point1[1] == -400:  # the y value is on the bottom edge of the map
                for index2 in range(length):
                    point2 = self.points[index2]
                    if self.visibility_graph[index1][index2] == 1 and point2[1] == -400:  # both of these points' y values are on the bottom edge of the map
                        self.visibility_graph[index1][index2] = 0  # make them invisible to each other
                        self.visibility_graph[index2][index1] = 0


    def print_visibility_graph(self):
        print "Visibility Graph:"
        for row in self.visibility_graph:
            print row

    ##########################
    ### DEPTH FIRST SEARCH ###
    ##########################

    def get_depth_first_search_path(self):
        print "Running Depth First Search to Get Path"
        # clear everything and add the tank's start position to the frontier
        self.clear_history()
        self.frontier.append(self.points[0])

        if not self.r_dfs(self.frontier[0]):
            print >> sys.stderr, 'DFS failed to find the goal'

        return self.path

    def r_dfs(self, vertex):
        self.search_snapshots.append(Snapshot(list(self.visited), list(self.frontier)))
        self.frontier.remove(vertex)
        self.visited.append(vertex)

        # recursive base case, found the goal
        if self.is_goal(vertex):
            self.path.append(vertex)
            return True

        # find out which point we're dealing with
        try:
            index = self.points.index(vertex)
        except:
            print >> sys.stderr, 'Vertex not found in points'
            return False

        # prepare qualified new neighbors to be added to frontier
        row = self.visibility_graph[index]
        new_neighbors = []
        index = 0
        for item in row:
            neighbor = self.points[index]
            if item == 1 and neighbor not in self.visited:
                new_neighbors.append(neighbor)
            index += 1

        # recursive base case, no new neighbors
        if len(new_neighbors) == 0:
            return False

        # it's a beautiful day in the neighborhood
        for neighbor in new_neighbors:
            self.frontier.insert(0, neighbor)
            if self.r_dfs(neighbor):
                self.path.insert(0, vertex)
                return True

        # none of our children in this path returned true
        return False

    ############################
    ### BREADTH FIRST SEARCH ###
    ############################

    def get_breadth_first_search_path(self):
        print "Running Breadth First Search to Get Path"
         # clear everything and add the beginning node (with the tank's start position) to the frontier
        self.clear_history()
        self.frontier.append(BFSNode(self.points[0], None))

        self.breadth_first_search()
        return self.path

    def breadth_first_search(self):
        while self.frontier:
            if self.frontier[0].my_point in self.visited:
                # we've already visited this node, don't need to look at it again
                self.frontier.pop(0)
                continue

            self.search_snapshots.append(Snapshot(list(self.visited), list(self.frontier), uses_bfs_nodes=True))
            current_node = self.frontier.pop(0)
            vertex = current_node.my_point
            self.visited.append(vertex)

            # find out which (x,y) point we're dealing with
            try:
                index = self.points.index(vertex)
            except:
                print >> sys.stderr, 'Vertex not found in points'
                return

            # find the neighbors of this point
            row = self.visibility_graph[index]
            for i in range(0, len(row)):
                neighbor = self.points[i]
                if row[i] == 1 and neighbor not in self.visited:
                    if self.is_goal(neighbor):
                        # If this child is the goal node, we're done!
                        last_node = BFSNode(neighbor, current_node)
                        self.frontier.append(last_node)
                        self.search_snapshots.append(Snapshot(list(self.visited), list(self.frontier), uses_bfs_nodes=True))
                        self.reconstruct_path_from_last_node(last_node)
                        return
                    else:
                        # Add this child to the end of the queue
                        self.frontier.append(BFSNode(neighbor, current_node))

        # If we get to this point, then the frontier became empty before we found the goal
        print "BFS failed to find the goal"

    def reconstruct_path_from_last_node(self, last_node):
        self.path = []
        node = last_node
        while node:
            self.path.insert(0, node.my_point)
            node = node.parent

    ############################
    ###   A-STAR ALGORITHM   ###
    ############################
    def get_a_star_path(self):
        print "Running A* to Get Path"
        self.a_star_search()
        return self.path

    def a_star_search(self):
        self.clear_history()
        self.frontier = PriorityQueue()
        self.frontier.put(AStarNode(self.points[0], None, 0), 0)
        last_node = None

        # iterate until the frontier is empty
        while not self.frontier.empty():
            snapshot = Snapshot(list(self.visited), self.frontier.getNodes(), uses_a_star_nodes=True)
            self.search_snapshots.append(snapshot)
            current = self.frontier.get()
            if current.my_point in self.visited:
                #  Never mind, we didn't want that snapshot :)
                self.search_snapshots.remove(snapshot)
                continue
            self.visited.append(current.my_point)

            # end immediately if the goal is found
            if self.is_goal(current.my_point):
                last_node = current
                break

            # find out which point we're dealing with
            try:
                index = self.points.index(current.my_point)
            except:
                print >> sys.stderr, 'Vertex not found in points'
                return False

            # prepare qualified new neighbors to be added to frontier
            row = self.visibility_graph[index]
            index = 0
            for item in row:
                neighbor = self.points[index]
                if item == 1 and neighbor not in self.visited:
                    distance = current.cost
                    distance += self.distance(neighbor, current.my_point)   # distance so far
                    est_distance_remaining = distance + self.distance(neighbor, self.points[1])    # est. distance to go
                    self.frontier.put(AStarNode(neighbor, current, distance), est_distance_remaining)
                index += 1

        # unwind path back to start
        while not last_node == None:
            self.path.insert(0, last_node.my_point)
            last_node = last_node.parent


    ################################
    ### SEARCH ALGORITHM HELPERS ###
    ################################

    def clear_history(self):
        self.visited = []
        self.frontier = []
        self.path = []
        self.search_snapshots = []

    def is_goal(self, point):
        return point == self.points[1]  # the goal point is always the second one in our list of points

    def distance(self, point1, point2):
        return math.sqrt((point1[0]-point2[0])**2 + (point1[1] - point2[1]) ** 2)
Example #26
0
class DungeonMaster(object):
    def __init__(self, clock, dungeon, locale_id):
        self.clock = clock
        self.dungeon = dungeon
        self.path_finder = PathFinder(dungeon)
        self.locale_id = locale_id
        self.queue = PriorityQueue()
        self.factions = {}
        self.playing = True
        self.dungeon_expire = self.clock.max_locale_time
        self.char_id = 'DM'
        self.placement_locations = {
            'ne': [],
            'e': [],
            'se': [],
            'nw': [],
            'w': [],
            'sw': [],
        }
        self.init_placement_locations()

        self.clock.set_local_time(locale_id=locale_id, locale_time=0)

    def init_placement_locations(self):
        center = self.dungeon.get_hex(x=0, y=0, z=0)
        ring_1 = self.dungeon.ring(center, self.dungeon.map_radius - 1)
        ring_2 = self.dungeon.ring(center, self.dungeon.map_radius)
        rings = ring_1 + ring_2

        high = self.dungeon.map_radius - 1
        low = 1

        for point in rings:
            x = abs(point.x)
            y = abs(point.y)
            z = abs(point.z)

            if x >= high and y > low and y < high:
                if point.x < 0:
                    self.placement_locations['w'].append(point)
                else:
                    self.placement_locations['e'].append(point)
            elif y >= high and x > low and x < high:
                if point.y < 0:
                    self.placement_locations['se'].append(point)
                else:
                    self.placement_locations['nw'].append(point)
            elif z >= high and x > low and x < high:
                if point.z < 0:
                    self.placement_locations['ne'].append(point)
                else:
                    self.placement_locations['sw'].append(point)

    def run_dungeon(self):
        while self.is_playing():
            self.run()

    def run(self):
        char = self.next_char()
        self.increment_time()
        while self.get_time() < char.gcd:
            self.increment_time()
        self.activate_char(char)

    def is_playing(self):
        if self.get_time() > self.dungeon_expire:
            self.playing = False
        elif len(self.factions) <= 1:
            self.playing = False
        else:
            self.playing = True

        return self.playing

    def add_char(self, member, faction='dm', edge='dm', insert_time=0):
        if faction == 'dm':
            faction = self

        if faction.faction_id not in self.factions.keys():
            self.factions[faction.faction_id] = []

        if insert_time == 0:
            insert_time = self.get_time() + member.get_stat('initiative')

        self.factions[faction.faction_id].append(member)
        self.queue.put(member, insert_time)

        member.dm = self

        faction.place_char(member, self.get_placement_locations(edge))

    def remove_char(self, member):
        faction_id = member.faction.faction_id
        self.factions[faction_id].remove(member)
        if len(self.factions[faction_id]) == 0:
            self.factions.pop(faction_id, None)

    def next_char(self):
        return self.queue.get()

    def get_time(self):
        return self.clock.get_locale_time(self.locale_id)

    def increment_time(self):
        self.clock.increment_locale_time(self.locale_id)

    def activate_char(self, char):
        priority = char.activate()

        if char.health > 0:
            self.queue.put(char, priority)

    def get_placement_locations(self, edge):
        sides = ['ne', 'e', 'se', 'sw', 'w', 'nw']

        if edge in sides:
            return self.placement_locations[edge]

    def get_adjacent_enemies(self, requestor):
        hexes = self.dungeon.neighbors(requestor.dungeon_hex)
        return self.get_enemies(requestor, hexes)

    def get_nearby_enemies(self, requestor, radius=2):
        hexes = self.dungeon.spiral(requestor.dungeon_hex, radius)
        return self.get_enemies(requestor, hexes)

    def get_enemies(self, requestor, hexes):
        enemies = []

        for dungeon_hex in hexes:
            if dungeon_hex is None:
                next
            elif dungeon_hex.character is None:
                next
            elif dungeon_hex.character.faction != requestor.faction:
                enemies.append(dungeon_hex.character)

        return enemies

    def get_nearest_enemy(self, requestor):
        enemies = []
        min_dist = requestor.sight_range
        closest = None

        for faction in self.factions.keys():
            if faction != requestor.faction.faction_id:
                for member in self.factions[faction]:
                    enemies.append(member)

        for enemy in enemies:
            current = self.distance(requestor, enemy)
            if current < min_dist:
                min_dist = current
                closest = enemy

        requestor.target_enemy = enemy
        requestor.distance_to_enemy = min_dist

        return closest

    def distance(self, actor, target):
        return self.dungeon.distance(actor.dungeon_hex, target.dungeon_hex)

    def move_char_along_path(self, actor, source, dest, distance):
        path = self.path_finder.find_path(
            start=source,
            goal=dest,
        )
        if (len(path) - 1) < distance:
            distance = (len(path) - 1)
        actor.move(path[distance])
Example #27
0
class PathFinder(object):
    def __init__(self, bzrc, tank_index):
        self.bzrc = bzrc
        self.points = []
        self.edges = []
        self.visibility_graph = None

        self.frontier = []
        self.visited = []
        self.path = []

        self.search_snapshots = []
        self.create_visibility_graph(tank_index)

    def get_path(self):
        return self.get_a_star_path()

    ########################
    ### VISIBILITY GRAPH ###
    ########################

    def create_visibility_graph(self, tank_index):
        print "Generating Visibility Graph for Tank", tank_index

        tank = self.bzrc.get_mytanks()[tank_index]
        self.points = []

        # append tank position to points, this MUST be the first point in this list (we're relying on that for
        # our search algorithms below)
        self.points.append((tank.x, tank.y))

        # append goal flag position to points
        flags = self.bzrc.get_flags()
        for flag in flags:
            if tank.flag != '-' and flag.color in tank.callsign:  # if the tank has the flag, go home
                self.points.append(
                    (flag.x, flag.y)
                )  # TODO: this line only works if the other team hasn't already taken our flag and run with it. We should probably use our base instead...
                break
            elif flag.color not in tank.callsign:  # if the tank has no flag, go for one
                self.points.append((flag.x, flag.y))
                break

        # append obstacle corners to points, and obstacle edges to our list of edges
        for obstacle in self.bzrc.get_obstacles():
            i = 0
            for point in obstacle:
                self.points.append(point)
                self.edges.append([point, obstacle[(i + 1) % len(obstacle)]])
                i += 1

        # initialize the visibility graph to all -1's
        length = len(self.points)
        self.visibility_graph = [[-1 for _ in range(length)]
                                 for _ in range(length)]

        # figure out the visibility between each pair of points
        for col in range(length):
            for row in range(length):
                if self.visibility_graph[row][
                        col] == -1:  # we haven't considered this pair of points yet
                    if self.is_visible(self.points[col], self.points[row]):
                        # "if you are visible to me, than I am visible to you" mentality
                        self.visibility_graph[row][col] = 1
                        self.visibility_graph[col][row] = 1
                    else:
                        # "if you are not visible to me, than I am not visible to you" mentality
                        self.visibility_graph[row][col] = 0
                        self.visibility_graph[col][row] = 0

        # remove any edges that are on the very edge of the map (and therefore couldn't be traversed by the tank)
        self.remove_visibility_on_world_edges()

    def update_visibility_graph(self, tank_index):
        tank = self.bzrc.get_mytanks()[tank_index]
        self.points[0] = (tank.x, tank.y)  # update the tank position

        # update goal flag position in points
        flags = self.bzrc.get_flags()
        for flag in flags:
            if tank.flag != '-' and flag.color in tank.callsign:  # if the tank has the flag, go home
                self.points[1] = (
                    flag.x, flag.y
                )  # TODO: this line only works if the other team hasn't already taken our flag and run with it. We should probably use our base instead...
                break
            elif tank.flag == '-' and flag.color not in tank.callsign:  # if the tank has no flag, go for one
                self.points[1] = (flag.x, flag.y)
                break

        # update the first two rows and columns in our visibility graph (these are the only points that have changed)
        # initialize the visibility graph to all -1's
        length = len(self.points)

        # figure out the visibility between each pair of points
        for col in range(length):
            for row in range(length):
                if col > 1 and row > 1:
                    continue

                if self.is_visible(self.points[col], self.points[row]):
                    # "if you are visible to me, than I am visible to you" mentality
                    self.visibility_graph[row][col] = 1
                    self.visibility_graph[col][row] = 1
                else:
                    # "if you are not visible to me, than I am not visible to you" mentality
                    self.visibility_graph[row][col] = 0
                    self.visibility_graph[col][row] = 0

    def is_visible(self, point1, point2):
        # check if they are the same point...a point is not visible to itself
        if point1 == point2:
            return False

        # check if they share an edge
        p1_found = False
        for edge in self.edges:
            if point1 in edge:
                p1_found = True
                if point2 in edge:
                    return True

        # check if they are both in the same obstacle (but obviously don't share an edge because of the case above)
        if p1_found:
            for obstacle in self.bzrc.get_obstacles():
                if point1 in obstacle and point2 in obstacle:
                    return False

        # check if there are any intersecting edges between these two points
        temp_edge = [point1, point2]
        for edge in self.edges:
            if self.line_segments_intersect(temp_edge, edge):
                return False

        # No edges intersected, these two points are visible to each other
        return True

    # Determines if two line segments intersect by checking that the two ends of one segment are on different sides
    # of the other segment, AND vise-versa (both conditions must be true for the line segments to intersect).
    # See http://stackoverflow.com/questions/7069420/check-if-two-line-segments-are-colliding-only-check-if-they-are-intersecting-n
    # for further explanation & math.
    def line_segments_intersect(self, edge1, edge2):
        # if both points of edge1 are on the same side of edge2, or one of edge1's points is on edge2
        # then we already know the lines aren't crossing over each other.
        cp1 = self.cross_product(edge1[0], edge2)
        cp2 = self.cross_product(edge1[1], edge2)
        if (cp1 > 0 and cp2 > 0) or (cp1 < 0
                                     and cp2 < 0) or cp1 == 0 or cp2 == 0:
            return False

        # if both points of edge2 are on the same side of edge1, or one of edge2's endpoints is on edge1
        # then we know the lines aren't crossing over each other
        cp1 = self.cross_product(edge2[0], edge1)
        cp2 = self.cross_product(edge2[1], edge1)
        if (cp1 > 0 and cp2 > 0) or (cp1 < 0
                                     and cp2 < 0) or cp1 == 0 or cp2 == 0:
            return False

        return True

    # Returns the cross product between the given line segment and the vector from that line segment to the given point
    def cross_product(self, point, segment):
        seg_start = segment[0]
        seg_end = segment[1]
        x = 0
        y = 1

        return (seg_end[x] - seg_start[x]) * (point[y] - seg_end[y]) - (
            seg_end[y] - seg_start[y]) * (point[x] - seg_end[x])

    def remove_visibility_on_world_edges(self):
        length = len(self.points)

        for index1 in range(length):
            point1 = self.points[index1]

            # check left edge
            if point1[0] == -400:  # the x value is on the left edge of the map
                for index2 in range(length):
                    point2 = self.points[index2]
                    if self.visibility_graph[index1][index2] == 1 and point2[
                            0] == -400:  # both of these points' x values are on the left edge of the map
                        self.visibility_graph[index1][
                            index2] = 0  # make them invisible to each other
                        self.visibility_graph[index2][index1] = 0

            # check right edge
            elif point1[
                    0] == 400:  # the x value is on the right edge of the map
                for index2 in range(length):
                    point2 = self.points[index2]
                    if self.visibility_graph[index1][index2] == 1 and point2[
                            0] == 400:  # both of these points' x values are on the edge of the map
                        self.visibility_graph[index1][
                            index2] = 0  # make them invisible to each other
                        self.visibility_graph[index2][index1] = 0

            # check top edge
            elif point1[1] == 400:  # the y value is on the top edge of the map
                for index2 in range(length):
                    point2 = self.points[index2]
                    if self.visibility_graph[index1][index2] == 1 and point2[
                            1] == 400:  # both of these points' y values are on the top edge of the map
                        self.visibility_graph[index1][
                            index2] = 0  # make them invisible to each other
                        self.visibility_graph[index2][index1] = 0

            # check bottom edge
            elif point1[
                    1] == -400:  # the y value is on the bottom edge of the map
                for index2 in range(length):
                    point2 = self.points[index2]
                    if self.visibility_graph[index1][index2] == 1 and point2[
                            1] == -400:  # both of these points' y values are on the bottom edge of the map
                        self.visibility_graph[index1][
                            index2] = 0  # make them invisible to each other
                        self.visibility_graph[index2][index1] = 0

    def print_visibility_graph(self):
        print "Visibility Graph:"
        for row in self.visibility_graph:
            print row

    ##########################
    ### DEPTH FIRST SEARCH ###
    ##########################

    def get_depth_first_search_path(self):
        print "Running Depth First Search to Get Path"
        # clear everything and add the tank's start position to the frontier
        self.clear_history()
        self.frontier.append(self.points[0])

        if not self.r_dfs(self.frontier[0]):
            print >> sys.stderr, 'DFS failed to find the goal'

        return self.path

    def r_dfs(self, vertex):
        self.search_snapshots.append(
            Snapshot(list(self.visited), list(self.frontier)))
        self.frontier.remove(vertex)
        self.visited.append(vertex)

        # recursive base case, found the goal
        if self.is_goal(vertex):
            self.path.append(vertex)
            return True

        # find out which point we're dealing with
        try:
            index = self.points.index(vertex)
        except:
            print >> sys.stderr, 'Vertex not found in points'
            return False

        # prepare qualified new neighbors to be added to frontier
        row = self.visibility_graph[index]
        new_neighbors = []
        index = 0
        for item in row:
            neighbor = self.points[index]
            if item == 1 and neighbor not in self.visited:
                new_neighbors.append(neighbor)
            index += 1

        # recursive base case, no new neighbors
        if len(new_neighbors) == 0:
            return False

        # it's a beautiful day in the neighborhood
        for neighbor in new_neighbors:
            self.frontier.insert(0, neighbor)
            if self.r_dfs(neighbor):
                self.path.insert(0, vertex)
                return True

        # none of our children in this path returned true
        return False

    ############################
    ### BREADTH FIRST SEARCH ###
    ############################

    def get_breadth_first_search_path(self):
        print "Running Breadth First Search to Get Path"
        # clear everything and add the beginning node (with the tank's start position) to the frontier
        self.clear_history()
        self.frontier.append(BFSNode(self.points[0], None))

        self.breadth_first_search()
        return self.path

    def breadth_first_search(self):
        while self.frontier:
            if self.frontier[0].my_point in self.visited:
                # we've already visited this node, don't need to look at it again
                self.frontier.pop(0)
                continue

            self.search_snapshots.append(
                Snapshot(list(self.visited),
                         list(self.frontier),
                         uses_bfs_nodes=True))
            current_node = self.frontier.pop(0)
            vertex = current_node.my_point
            self.visited.append(vertex)

            # find out which (x,y) point we're dealing with
            try:
                index = self.points.index(vertex)
            except:
                print >> sys.stderr, 'Vertex not found in points'
                return

            # find the neighbors of this point
            row = self.visibility_graph[index]
            for i in range(0, len(row)):
                neighbor = self.points[i]
                if row[i] == 1 and neighbor not in self.visited:
                    if self.is_goal(neighbor):
                        # If this child is the goal node, we're done!
                        last_node = BFSNode(neighbor, current_node)
                        self.frontier.append(last_node)
                        self.search_snapshots.append(
                            Snapshot(list(self.visited),
                                     list(self.frontier),
                                     uses_bfs_nodes=True))
                        self.reconstruct_path_from_last_node(last_node)
                        return
                    else:
                        # Add this child to the end of the queue
                        self.frontier.append(BFSNode(neighbor, current_node))

        # If we get to this point, then the frontier became empty before we found the goal
        print "BFS failed to find the goal"

    def reconstruct_path_from_last_node(self, last_node):
        self.path = []
        node = last_node
        while node:
            self.path.insert(0, node.my_point)
            node = node.parent

    ############################
    ###   A-STAR ALGORITHM   ###
    ############################
    def get_a_star_path(self):
        print "Running A* to Get Path"
        self.a_star_search()
        return self.path

    def a_star_search(self):
        self.clear_history()
        self.frontier = PriorityQueue()
        self.frontier.put(AStarNode(self.points[0], None, 0), 0)
        last_node = None

        # iterate until the frontier is empty
        while not self.frontier.empty():
            snapshot = Snapshot(list(self.visited),
                                self.frontier.getNodes(),
                                uses_a_star_nodes=True)
            self.search_snapshots.append(snapshot)
            current = self.frontier.get()
            if current.my_point in self.visited:
                #  Never mind, we didn't want that snapshot :)
                self.search_snapshots.remove(snapshot)
                continue
            self.visited.append(current.my_point)

            # end immediately if the goal is found
            if self.is_goal(current.my_point):
                last_node = current
                break

            # find out which point we're dealing with
            try:
                index = self.points.index(current.my_point)
            except:
                print >> sys.stderr, 'Vertex not found in points'
                return False

            # prepare qualified new neighbors to be added to frontier
            row = self.visibility_graph[index]
            index = 0
            for item in row:
                neighbor = self.points[index]
                if item == 1 and neighbor not in self.visited:
                    distance = current.cost
                    distance += self.distance(
                        neighbor, current.my_point)  # distance so far
                    est_distance_remaining = distance + self.distance(
                        neighbor, self.points[1])  # est. distance to go
                    self.frontier.put(AStarNode(neighbor, current, distance),
                                      est_distance_remaining)
                index += 1

        # unwind path back to start
        while not last_node == None:
            self.path.insert(0, last_node.my_point)
            last_node = last_node.parent

    ################################
    ### SEARCH ALGORITHM HELPERS ###
    ################################

    def clear_history(self):
        self.visited = []
        self.frontier = []
        self.path = []
        self.search_snapshots = []

    def is_goal(self, point):
        return point == self.points[
            1]  # the goal point is always the second one in our list of points

    def distance(self, point1, point2):
        return math.sqrt((point1[0] - point2[0])**2 +
                         (point1[1] - point2[1])**2)
Example #28
0
    def A_star(self):
        """
        Returns the path from the start position to the goal position using the
        A-star (A*) algorithm. Returns <None> if no solution is found.
        """

        # Heuristic distance between two positions
        def heuristic(a, b):
            """
            Calculates the Manhattan distance between two positions.
            """
            x1, y1 = a
            x2, y2 = b
            dist = abs(x1 - x2) + abs(y1 - y2)

            return dist

        # Initialize the priority queue
        pq = PriorityQueue(queue_type='min')

        # Values for the start point
        g = 0
        h = heuristic(self.goal, self.start)
        f = g + h

        # Add the start point to the priority queue.
        pq.put(f, self.start)
        g_values = {self.start: g}
        previous = {self.start: None}
        self.added = 1

        # Loop until the priority queue is empty
        self.visited = 0
        while (not pq.is_empty()):

            # Get the highest priority position from the priority queue
            f, current = pq.get()
            self.visited += 1

            # Stop if it is the goal and return the path
            if (current == self.goal):
                path = self.get_path(previous)
                return path

            # Define the order in the directions
            idx = self.order_dir()

            # Add to the priority queue the neighbours of the current position
            for direction in idx:

                # Offset values
                row_offset, col_offset = self.offset[direction]

                # Neighbour position
                row_neigh = current[0] + row_offset
                col_neigh = current[1] + col_offset
                neighbour = (row_neigh, col_neigh)

                # If neighbour position is valid and not in the dictionary
                if (self.layout[row_neigh][col_neigh] != '#'
                        and self.layout[row_neigh][col_neigh] != '*'
                        and neighbour not in previous):

                    # Values (the g-value of all neighbour positions differ
                    # from the g-value of the current position by 1)
                    g = g_values[current] + 1
                    h = heuristic(self.goal, neighbour)
                    f = g + h

                    # Add it to the priority queue
                    pq.put(f, neighbour)
                    g_values[neighbour] = g
                    previous[neighbour] = current
                    self.added += 1

        return None
Example #29
0
class AStarPlanner(object):
    def __init__(self, planning_env):
        self.planning_env = planning_env
        self.nodes = dict()
        self.PQ = PriorityQueue()

    def Plan(self, start_config, goal_config):
        print start_config
        print goal_config
        waypoints = {}
        cost_at_way = {}
        plan = []
        start = self.planning_env.discrete_env.configuration_to_nodeID(
            start_config)
        goal = self.planning_env.discrete_env.configuration_to_nodeID(
            goal_config)
        print "start:", start
        print "goal:", goal
        x = []
        y = []
        count = 0
        waypoints = {}
        cost_at_way[start] = 0
        waypoints[start] = 0
        self.PQ.put(start, 0)
        weight = 1

        while not self.PQ.empty():
            current = self.PQ.get()
            count = count + 1
            #print "current",current
            if (current == goal):
                print "goal reached"
                thing = copy.copy(goal)
                path = numpy.array([
                    self.planning_env.discrete_env.nodeID_to_configuration(
                        thing)
                ])
                npath = numpy.array([thing])
                thing = waypoints[thing]
                while thing != 0:

                    path = numpy.vstack((numpy.array(
                        self.planning_env.discrete_env.nodeID_to_configuration(
                            thing)), path))
                    npath = numpy.vstack((numpy.array(thing), npath))
                    thing = waypoints[thing]
                print "nodes expanded:", count
                print "npath:", path
                print "self.planning_env.count", self.planning_env.count
                print "Final cost", cost_at_way[goal]
                if self.planning_env.space_dim == 2:
                    self.planning_env.plotthegraph(path)
                return path

            #print self.planning_env.get_successors(current)
            for next in self.planning_env.get_successors(current):
                #print "next:",next
                #print "waypoints[current]",waypoints[current]
                new_cost = cost_at_way[
                    current] + self.planning_env.compute_distance(
                        current, next) + 5 * self.planning_env.modeswitch(
                            current, next, waypoints[current])

                if next not in cost_at_way or new_cost < cost_at_way[next]:
                    #if next not in cost_at_way:
                    #print "new cost:",new_cost
                    #else:
                    #print "updated cost:",new_cost

                    cost_at_way[next] = new_cost
                    priority = new_cost + weight * self.planning_env.get_heuristic(
                        next, goal)
                    self.PQ.put(next, priority)
                    waypoints[next] = current
                    #print "waypoint:",waypoints

        print "Path Not Found"
        return 0
    def Plan(self, start_config, goal_config):
        if self.visualize and hasattr(self.planning_env, 'InitializePlot'):
            self.planning_env.InitializePlot(goal_config)
        ## INITIALIZATIONS
        #print "start_config",start_config
        #print "goal_config",goal_config
        start_time = time.time()
        startID = self.planning_env.find_ID(start_config)
        goalID = self.planning_env.find_ID(goal_config)
        print "IDs", startID, goalID
        PQ = PriorityQueue()
        g = {}
        closedlist = []
        PQ.put(startID, 0)
        truecost = {}
        g[startID] = 0
        truecost[startID] = True
        parent = {}
        parent[startID] = 0
        #   Starting of planner
        while not PQ.empty():
            current = PQ.get()

            #print "current",current
            if current == goalID:
                print "goal reached"
                thing = copy.copy(goalID)
                path = numpy.array([self.planning_env.IDtoconfig(thing)])
                npath = numpy.array([thing])
                thing = parent[thing]
                while thing != 0:
                    path = numpy.vstack(
                        (numpy.array(self.planning_env.IDtoconfig(thing)),
                         path))
                    npath = numpy.vstack((numpy.array(thing), npath))
                    thing = parent[thing]
                path = numpy.vstack(
                    (numpy.array(self.planning_env.IDtoconfig(thing)), path))
                npath = numpy.vstack((numpy.array(thing), npath))
                #print "nodes expanded:",count
                print "npath:", path
                #print "self.planning_env.count",self.planning_env.count
                print "Number of edge evalualtion", self.planning_env.count
                print "FInal TIme ", time.time() - start_time
                print "Final cost", g[goalID]
                #if self.planning_env.space_dim==2:
                #    self.planning_env.plotthegraph(path)
                return path
                break
            if current in closedlist:
                continue
            elif truecost[current]:  # tells if its in collision or not
                closedlist.append(current)
                for neighbor in self.planning_env.get_successors(current):
                    if neighbor not in closedlist:
                        #print "neighbor",neighbor

                        tempcost = g[
                            current] + self.planning_env.compute_distance(
                                current, neighbor)
                        if neighbor not in g or tempcost < g[neighbor]:
                            g[neighbor] = tempcost
                            priority = tempcost + self.planning_env.get_heuristic(
                                neighbor, goalID)
                            PQ.put(neighbor, priority)
                            truecost[neighbor] = False
                            parent[neighbor] = current

            else:
                temp = self.planning_env.gettruecost(parent[current], current)
                #print "temp,node",temp,current
                if temp < float('inf'):
                    truecost[current] = True
                    g_here = g[parent[current]] + temp
                    #self.planning_env.PlotEdge(neighbour,new_guy)
                    if current not in g or g_here <= g[current]:
                        #print "coming here"
                        g[current] = g_here
                        priority = g_here + self.planning_env.get_heuristic(
                            neighbor, goalID)
                        PQ.put(current, priority)

        print "Goal not found"

        #startID= self.planning_env.configuration_to_nodeID(start_config)
        plan = []

        plan.append(start_config)
        plan.append(goal_config)

        return plan
Example #31
0
class DStar_planner(object):
    def __init__(self, start, goal, known_map, r):  #The non-pset version
        # def __init__(self, start, goal, known_map, r, _uvu, _cspu): #PSET verison
        self.s_start = KeyedVertex(start)
        self.s_last = self.s_start
        self.s_goal = KeyedVertex(goal)
        self.k_m = 0
        self.U = PriorityQueue()  # Koenig-22
        self.map_known = known_map
        self.robRange = r
        self.encounteredVertices = []

        #further initialization
        self.s_goal.rhs = 0
        self.s_goal.key = self.s_goal.CalculateKey(self.s_start,
                                                   self.map_known, self.k_m)
        self.U.put(self.s_goal)
        self.encounteredVertices.append(self.s_goal)
        #This one is my addition, to help track initialized vertices
        self.encounteredVertices.append(self.s_start)

        #configurable pset functions
        # self.uvu = _uvu
        # self.cspu = _cspu

    def pathExists(self):
        if (self.s_start.g == inf):
            print(
                "No path exists by virtue of the start node having infinite g cost."
            )
            return False
        else:
            return True

    # For each of the update functions, check to see if we're tracking one already
    def updateStart(self, pos):
        self.s_start = next(
            (s for s in self.encounteredVertices if (s.pos == pos)),
            KeyedVertex(pos))

    # This goal refers to overall current target, not next waypoint
    def updateGoal(self, pos):
        self.s_goal = next(
            (s for s in self.encounteredVertices if (s.pos == pos)), False)
        if (
                not self.s_goal
        ):  #<Burn it to the ground> This means the above got false back, and the whole thing needs to be reset for the next pathfinding goal
            self.encounteredVertices = []  #abandon all the collected values
            self.s_start = KeyedVertex(
                self.s_start.pos)  #creating a new copy, forget about the old
            self.s_goal = KeyedVertex(pos)  # as originally fed in
            self.s_last = self.s_start
            self.k_m = 0
            self.U = PriorityQueue()
            # cont'd
            self.s_goal.rhs = 0
            self.s_goal.key = self.s_goal.CalculateKey(self.s_start,
                                                       self.map_known,
                                                       self.k_m)
            self.U.put(self.s_goal)
            self.encounteredVertices.append(self.s_goal)
            #This one is my addition, to help track initialized vertices
            self.encounteredVertices.append(self.s_start)

    def checkAndUpdate(self, path, planStep):
        # Starts at line 28; prior lines taken care of via main & stepping
        # print("C&U -> Plan step: {}".format(self.s_start)) #Plan step should always be 0 with this config
        changedEdges = []
        edgeFrom = self.s_start  #s
        for pos in path[1:]:  # Koenig-28
            edgeTo = next(
                (s for s in self.encounteredVertices if (s.pos == pos)),
                False)  # get corresponding vertex
            if (self.map_known.c(
                    edgeFrom,
                    edgeTo) == inf):  # Koenig-29 obstruction appeared
                changedEdges.append(edgeFrom)  #s
            edgeFrom = edgeTo

        if (len(changedEdges) > 0):
            # print("Replanning due to changed edges..."),
            # self.k_m = self.k_m + self.s_last.h(self.s_start,self.map_known)
            prvKm = self.k_m
            prvH = self.s_last.h(self.s_start, self.map_known)
            self.k_m = prvKm + prvH
            self.s_last = copy.deepcopy(
                self.s_start
            )  #so it doesn't link w/ and change when s_start changes. could just record pos, but then the nifty h function would need to be reworked

            for s in changedEdges:
                # print("Changed edges:{}".format(s))
                self.UpdateVertex(s)

            path = self.computeShortestPath()
            # path = retrieveShortestPath(map_known, agent1.getPos()) # Koenig-26a   (overkill, only need first element, but we want to record the whole map)
            if (not path):
                print("Path not retrieved successfully. Final (known) state:")
                self.map_known.display_terminal()
                #                 input("Exits on enter...")
                raise Exception("Path not found. Self destruct!")

            # input("Exits on enter...")
            return True, path
        else:
            return False, path
        #     # print("No new obstructions.")

    def computeShortestPath(self):
        # return self.cspu(self.map_known, self) #relic of PSET
        while( (self.U.key_peek() < self.s_start.CalculateKey(self.s_start,self.map_known,self.k_m)) \
                or (self.s_start.rhs != self.s_start.g) ): # Koenig-10")

            k_old = self.U.key_peek()  # Koenig-11
            u = self.U.get()  # Koenig-12
            if (k_old < u.CalculateKey(self.s_start, self.map_known,
                                       self.k_m)):  # Koenig-13
                u.key = u.CalculateKey(self.s_start, self.map_known,
                                       self.k_m)  # Koenig-14 (start)
                self.U.put(u)  # Koenig-14 (end)
            elif (u.g > u.rhs):  # Koenig-15
                u.g = u.rhs  # Koenig-16
                # Koenig-17 (start)
                for s in self.potentialPredeccessorPositions(u):
                    self.UpdateVertex(s)  # Koenig-17 (end)
            else:  # Koenig-18
                u.g = inf  # Koenig-19
                # Koenig-20 (start)
                for s in self.potentialPredeccessorPositions(u):
                    self.UpdateVertex(s)
                self.UpdateVertex(u)  # Koenig-20 (end)
        return self.retrieveShortestPath()

    # get list of potential movements
    # r dictates range (per dynamics, etc)
    # TODO: Should we consider dynamics to determine where you can actually get - immediately left /right may be in "range" of a ground robot, but it can't strafe
    # inits and adds to encountered list if not previously on it
    # Note: Do not consider obsticles here, that's should be in calculating the cost to go
    def potentialSuccessorPositions(
            self, slf
    ):  #Up down left right? requires some dynamics knowledge in future
        intRange = int(
            self.robRange)  #can round down for what range to iterate over
        xDim, yDim = self.map_known.dimensions()
        xRange = range(
            max(slf.pos[0] - intRange - 1, 0),
            min(slf.pos[0] + intRange + 1,
                xDim - 1))  #center around s.position, and limit to Map bounds
        #For y, visibly up is numerically down (origin is top-left) ; split up so can break on dist easier
        yRangeDown = range(slf.pos[1], min(
            slf.pos[1] + intRange + 1,
            yDim - 1))  #center around s.position, and limit to Map bounds
        yRangeUp = range(
            (slf.pos[1] - 1), max(slf.pos[1] - intRange - 1, 0),
            -1)  #center around s.position, and limit to Map bounds

        successors = []
        for x in xRange:
            for y in yRangeDown:
                if (slf.pos == (x, y)):
                    continue

                if (MAII_map.distance(slf.pos, (x, y)) > self.robRange):
                    break
                else:
                    s = next((s for s in self.encounteredVertices
                              if (s.pos == (x, y))), False)
                    if not s:
                        s = KeyedVertex((x, y))
                        self.encounteredVertices.append(s)
                    successors.append(
                        s)  #get from list of existing; if doesn't exist, init

            for y in yRangeUp:
                if (MAII_map.distance(slf.pos, (x, y)) > self.robRange):
                    break
                else:
                    s = next((s for s in self.encounteredVertices
                              if (s.pos == (x, y))), False)
                    if not s:
                        s = KeyedVertex((x, y))
                        self.encounteredVertices.append(s)
                    successors.append(s)
        return successors

    # For now, disregarding dynamics, successors=
    # See above commentary on self.potentialSuccessorPositions
    def potentialPredeccessorPositions(self, s):
        return self.potentialSuccessorPositions(s)

    def UpdateVertex(self, u):
        # self.uvu(self.map_known, self, u) # PSET relic
        if not (u == self.s_goal):  # Koenig-7 (start)
            successors = self.potentialSuccessorPositions(u)
            min_cost = inf

            for s in successors:  #over successors
                # self.map_known.setObs((1,3),False)
                cg = s.g + self.map_known.c(u, s)
                if (cg < min_cost):
                    min_cost = cg

            u.rhs = min_cost  # Koenig-7 (end)
        self.U.remove(u)  # Koenig-8
        u.key = u.CalculateKey(self.s_start, self.map_known,
                               self.k_m)  # Koenig-9 (start)

        if not (u.g == u.rhs):
            self.U.put(u)

    # Go from start to fin by following vertexes which minimize c(s,s')+g(s')
    def retrieveShortestPath(self):  #, known_map, cur):
        path = []
        curPos = next(
            (s
             for s in self.encounteredVertices if (s.pos == self.s_start.pos)),
            False)
        path.append(curPos.pos)
        nextPos = curPos
        iteration = 0
        while not (curPos.pos == self.s_goal.pos):  # Koenig-7 (start)
            succs = self.potentialSuccessorPositions(curPos)
            min_cost = inf
            for s_suc in succs:  #over successors
                cg = s_suc.g + self.map_known.c(curPos, s_suc)
                if (cg < min_cost):
                    min_cost = cg
                    nextPos = s_suc
            if (min_cost == inf):
                return False
            elif (iteration == 50):
                return False

            curPos = nextPos
            path.append(curPos.pos)
            iteration += 1
        return path
Example #32
0
def a_star_search(start, goal, D_cost_so_far):

    frontier = PriorityQueue()
    frontier.put(start)
    came_from = {}
    cost_so_far = {}
    came_from[start] = None
    cost_so_far[start] = 0
    while not frontier.empty():
        current = frontier.get()
        if current == goal:
            break
        for next in current.successors():
            new_cost = cost_so_far[current] + 1
            if next not in cost_so_far or new_cost < cost_so_far[next]:
                cost_so_far[next] = new_cost
                next.priority = new_cost + next.heuristic(D_cost_so_far)
                frontier.put(next)
                came_from[next] = current

    # find path
    current = goal
    path = []
    while current != start:
        path.append(current.pieces)
        current = came_from[current]
    path.append(start.pieces)
    path.reverse()

    # print result
    last = path[0]
    cur_piece = 0
    last_piece = 0
    actionNo = 0
    for cur in path:

        # print exit if length of path change
        if len(cur) < len(last):
            for piece_i in range(0, len(last)):
                if last[piece_i] not in cur:
                    last_piece = last[piece_i]
            print('EXIT from {0}.'.format(tuple(last_piece)))
            actionNo += 1
        else:
            for piece_i in range(0, len(cur)):
                if cur[piece_i] not in last:
                    cur_piece = cur[piece_i]
            for piece_i in range(0, len(last)):
                if last[piece_i] not in cur:
                    last_piece = last[piece_i]
            # print move if hexa distance is 1, jump if hexa distance is 2
            if type(cur_piece) != type(0):
                if hexe_distance(last_piece, cur_piece) > 1:
                    print('JUMP from {0} to {1}.'.format(
                        tuple(last_piece), tuple(cur_piece)))
                    actionNo += 1
                else:
                    print('MOVE from {0} to {1}.'.format(
                        tuple(last_piece), tuple(cur_piece)))
                    actionNo += 1
        last = cur
Example #33
0
    def Plan(self, start_config, goal_config):
        if self.visualize and hasattr(self.planning_env, 'InitializePlot'):
            self.planning_env.InitializePlot(goal_config)
        #   Starting of planner
        start_time=time.time()
        startID= self.planning_env.find_ID(start_config)
        goalID= self.planning_env.find_ID(goal_config)
        print "IDs",startID,goalID
        PQ= PriorityQueue()
        g={}
        PQ.put(startID,0)
        g[startID]=0
        parent={}
        parent[startID]=-1
        x=0
        memory=[]
        #   Starting of planner
        while not PQ.empty():
            current= PQ.get()
            if current==goalID:
                x=x+1
                print "goal reached ",x
                thing=copy.copy(goalID)
                path= numpy.array([self.planning_env.IDtoconfig(thing)])
                npath= numpy.array([thing])
                thing= parent[thing]

                while thing!=-1:
                    path= numpy.vstack((numpy.array(self.planning_env.IDtoconfig(thing)),path))
                    npath= numpy.vstack((numpy.array(thing),npath))
                    thing = parent[thing]
                thing=copy.copy(goalID)
                collision= False
                while thing!= startID:
                    temp= self.planning_env.gettruecost(parent[thing],thing)
                    if temp==float('inf'):
                        memory.append([parent[thing],thing])
                        collision =True
                        #print collision
                    thing = parent[thing]
                #path= numpy.vstack((numpy.array(self.planning_env.IDtoconfig(thing)),path))
                #npath= numpy.vstack((numpy.array(thing),npath))
                #print "npath:",npath
                #print "memory",memory
                #c=input("stop")

                if collision==True:
                    PQ= PriorityQueue()
                    g={}
                    PQ.put(startID,0)
                    g[startID]=0
                    parent={}
                    parent[startID]=-1
                    continue
                print "Number of edge evalualtion",self.planning_env.count
                print "FInal TIme ", time.time()-start_time
                print "npath:",path
                #print "self.planning_env.count",self.planning_env.count
                print "Final cost",g[goalID]
                #if self.planning_env.space_dim==2:
                #    self.planning_env.plotthegraph(path)
                return path
                break
            for neighbor in self.planning_env.get_successors(current):
                if [current,neighbor] not in memory:
                    if [neighbor,current] not in memory:
                        tempcost= g[current] + self.planning_env.compute_distance(current,neighbor)
                        if neighbor not in g or tempcost < g[neighbor]:
                            g[neighbor]=tempcost
                            priority= tempcost+ self.planning_env.get_heuristic(neighbor,goalID)
                            PQ.put(neighbor,priority)
                            parent[neighbor]= current


        print "Goal not found"
Example #34
0
class Game:
    """ Defines a running instance of a Murder Mystery.
        Handles the initialization of the various game states.
    """
    def __init__(self, abilities, players):
        self.gm = players[0]
        self.errorAbility = ErrorAbility()
        self.eventQueue = PriorityQueue()
        self.parser = Parser()
        self.inbox = Inbox()
        self.outbox = Outbox()

        self.players = {}
        for player in players[1:]:
            self.players[player.getName().lower()] = player

        self.abilities = {}
        for ability in abilities:
            self.abilities[ability.getName().lower()] = ability

    def getGameMaster(self):
        return self.gm

    def addEvent(self, event):
        """ Schedules an event to be run.
        """
        self.eventQueue.put(event)

    def addEvents(self, events):
        """ Schedules a list of events to be run.
        """
        if(events):
            for event in events:
                self.eventQueue.put(event)

    def removeEvent(self, event):
        """ Removes a specific event from the priority queue
        """
        self.eventQueue.remove(event)

    def getOutbox(self):
        return self.outbox

    def isValidAbility(self, name):
        return name.lower() in self.abilities

    def getAbility(self, name):
        return self.abilities[name.lower()]

    def getAbilityNames(self):
        return self.abilities.keys()

    def isValidPlayer(self, name):
        return name.lower() in self.players

    def getPlayer(self, name):
        return self.players[name.lower()]

    def getPlayerNames(self):
        return self.players.keys()

    def removePlayer(self, name):
        if( self.isValidPlayer(name) ):
            del self.players[name.lower()]

    def run(self):
        """ Run the game, and Don't stop.
            Ever.
        """
        print "Starting the main loop!"
        while( True ):
            self.step()
            time.sleep(5)

    def step(self):
        """ Perform one step of the game logic.
            You need to call this repeatedly to make the game run.
        """
        #process incoming messages
        newMessages = self.inbox.poll()
        commands = self.parser.parse(self.abilities.values(), newMessages, self.errorAbility)
        for (sender,ability,args) in commands:
            print "Handling '"+ability.getName()+"' for '"+sender+"'"
            for player in self.players.values():
                if( player.getContact() == sender ):
                    print "\tRunning the ability!"
                    self.addEvents(ability.getEventsFor(self, player, args))
                    break

        #Process the queue of events
        while( not self.eventQueue.empty() ):
            event = self.eventQueue.get()
            if( event.when() < datetime.now() ):
                print "Performing an event"
                self.addEvents(event.perform(self))
            else:
                #Doesn't support peeking, so shove it back in the queue if it
                #shouldn't happen yet
                self.eventQueue.put(event)
                break
    def a_star(self, start, goal):
        """
            A*
            This is where the A* algorithum belongs
            :param start: tuple of start pose
            :param goal: tuple of goal pose
            :return: dict of tuples
        """
        # Transform start and end
        start = map_helper.world_to_index2d(start, self.map)
        goal = map_helper.world_to_index2d(goal, self.map)

        # Priority queue for frontier
        frontier = PriorityQueue()
        frontier.put(start, 0)
        # To find path at end
        came_from = {}
        # Track cost to reach each point
        cost_so_far = {}

        # Initially start
        came_from[start] = None
        cost_so_far[start] = 0

        # Loop till finding a path
        while not frontier.empty():
            # Pop best cell from frontier
            current = frontier.get()
            rospy.logdebug("Current Node %s " % (current, ))

            # Done!
            if current == goal:
                break

            # Add neighbors to frontier
            for next in map_helper.get_neighbors(current, self.map):
                rospy.logdebug("Next node %s" % (next, ))

                # Find cost
                new_cost = cost_so_far[current] + self.move_cost(current, next)
                if next not in cost_so_far or new_cost < cost_so_far[next]:
                    cost_so_far[next] = new_cost
                    priority = new_cost + self.euclidean_heuristic(goal, next)
                    frontier.put(next, priority)
                    came_from[next] = current

        # Display frontier cells
        frontier_list = frontier.get_items()
        frontier_map = []
        frontier_to_display = []
        for point in frontier_list:
            frontier_map.append(map_helper.world_to_index2d(point, self.map))
            frontier_to_display.append(
                map_helper.index2d_to_world(point, self.map))

        # Print debug
        rospy.logdebug("Frontier list: %s " % frontier_list)

        # Generate path
        path = [map_helper.index2d_to_world(goal, self.map)]
        last_node = goal
        while came_from[last_node] is not None:
            next_node = came_from[last_node]
            path.insert(0, map_helper.index2d_to_world(next_node, self.map))
            last_node = next_node

        new_path = self.optimize_path(path)
        rospy.logdebug("Path %s " % new_path)

        self.paint_wavefront(frontier_to_display)

        self.paint_obstacles(new_path)
        self.paint_cells(frontier_list, new_path)
        self.points = new_path