def __init__(self): """ Initializes CPU with no active processes and empty non-frozen Priority Queue """ self.active = None self._dev_name = "CPU" PriorityQueue.__init__(self)
def __init__(self, dname, cyl): self._dev_type = "Disk Drive" self._dev_name = dname self._cylinders = cyl # Two priority queues to implement FSCAN. Q2 is frozen self._q1 = PriorityQueue() self._q2 = PriorityQueue(True)
def ready_to_CPU(self): """ Moves process at head of ready queue to CPU """ if not PriorityQueue.empty(self): self.active = PriorityQueue.dequeue(self) self.active.set_proc_loc(self._dev_name) else: # Nothing in ready queue self.active = None print io.nothing_in_ready()
def snapshot(self): """ Prints processes in ready queue, plus active process in CPU with headers """ print io.snapshot_header("ready") PriorityQueue.snapshot(self) if self.active: print " ACTIVE IN CPU (Est time remaining: {0:}) ".format( str(self.active.next_est_burst)).center(78, "=") self.active.headers() print io.ruler() self.active.snapshot() else: print "\n" + "No active process in the CPU".center(78)
def dijkstra(start_tile, end_tile): """ Dijkstra's algorithm :param start_tile: Tile object, start tile of board :param end_tile: Tile object, end tile of board :return: """ queue = PriorityQueue() queue.put(start_tile, 0) came_from = {start_tile: None} cost_so_far = {start_tile: 0} has_been_next_tile = [] while not queue.empty(): current_tile = queue.get() current_tile.visit() if current_tile == end_tile: break for next_tile in current_tile.neighbours: if next_tile not in has_been_next_tile: has_been_next_tile.append(next_tile) new_cost = cost_so_far[current_tile] + next_tile.weight if next_tile not in cost_so_far or new_cost < cost_so_far[ next_tile]: cost_so_far[next_tile] = new_cost priority = new_cost queue.put(next_tile, priority) came_from[next_tile] = current_tile return came_from, cost_so_far, has_been_next_tile
def __init__(self, dataStructure): super(interactiveDataStructures, self).__init__() # rich module elements pretty.install() traceback.install() self.console = Console() # Datastructure elements availableDataStrutuces = { 'DynamicArray': DynamicArray(), 'SingleLinkedList': SinglyLinkedList(), 'DoublyLinkedList': DoublyLinkedList(), 'Stack': Stack(), 'Queue': Queue(), 'PriorityQueue': PriorityQueue() } correspondingNodes = { 'DynamicArray': None, 'SingleLinkedList': ListNode(None), 'DoublyLinkedList': ListNode(None), 'Stack': StackNode(None), 'Queue': QueueNode(None), 'PriorityQueue': PQNode(None) } if dataStructure in availableDataStrutuces: self.dataStructure = availableDataStrutuces[dataStructure] self.DSNode = correspondingNodes[dataStructure] self.DSname = dataStructure interactiveDataStructures.prompt = text.Text(f'({dataStructure}) ', style="bold magenta") # doesn't quite work else: raise ValueError(f'Please choose one of the following available data structure: {availableDataStrutuces.keys()}')
def terminate(self, pid=None): """ If no pid given, terminates active process in CPU. Else, terminates process with given pid. If active process is terminated, moves head of Ready Queue to CPU. Precondition: pid is a valid PID for a process in the ready queue or CPU """ proc = None if self.active: # Terminate active process if no pid given or if active process has # given pid if not pid or self.active.pid == pid: proc = self.active self.ready_to_CPU() self.record_burst(proc) else: # Look for process in ready queue and remove proc = PriorityQueue.pop(self, pid) # Prompt for time since last interrupt # Update burst time for active process elapsed = io.get_valid_int("Time since last interrupt") self.active.update_burst_time(elapsed) # Print stats print "\n" + "{:-^78}".format(" Terminated Process Report ") print "PID: {:<4} Avg CPU Burst Time: {:<5} Total CPU Time: {:<5}".format( proc.pid, proc.avg_burst_time(), proc.tot_burst_time()).center(78, " ") del proc else: raise IndexError
def contains(self, pid): # CPU is empty if not self.active: return False if pid == self.active.pid: return True else: return PriorityQueue.contains(self, pid)
def dijkstra(self, origin_vertex_value, destination_vertex_value) -> collections.deque([Vertex]): labels = {} parents = {} for v in self.vertices(): labels[v] = math.inf parents[v] = None labels[self[origin_vertex_value]] = 0 table = PriorityQueue([v for v in self.vertices()], key=lambda v: labels[v], reverse=True) # min-heap while table: start = table.pop() for adjacent_edge in start.outgoing_edges: end = adjacent_edge.destination index = table.find(end) if index != -1: weighted_distance = labels[start] + adjacent_edge.weight if weighted_distance < labels[end]: labels[end] = weighted_distance table.remove(index) table.push(end) parents[end] = start result = collections.deque() start = self[destination_vertex_value] while start is not None: result.appendleft(start) start = parents[start] return result
def Dijkstra(num_nodes, mission, f_next, heuristic=None, num_controls=0): """Djikstra planner.""" t = Timer() t.tic() unvis_node = -1 previous = np.full(num_nodes, dtype=np.int, fill_value=unvis_node) cost_to_come = np.zeros(num_nodes) control_to_come = np.zeros((num_nodes, num_controls), dtype=np.int) startNode = mission['start']['id'] goalNode = mission['goal']['id'] #Priority queue based on the lower cost-to-go q = PriorityQueue() q.insert(0,startNode) foundPlan = False while not q.IsEmpty(): x_ctc = q.pop() x = x_ctc[1] if x == goalNode: foundPlan = True break neighbours, u, d = f_next(x) for xi, ui, di in zip(neighbours, u, d): if previous[xi] == unvis_node or cost_to_come[xi] > cost_to_come[x] + di: previous[xi] = x cost_to_come[xi] = cost_to_come[x] + di q.insert(cost_to_come[xi],xi) if num_controls > 0: control_to_come[xi] = ui # Recreate the plan by traversing previous from goal node if not foundPlan: return [] else: plan = [goalNode] length = cost_to_come[goalNode] control = [] while plan[0] != startNode: if num_controls > 0: control.insert(0, control_to_come[plan[0]]) plan.insert(0, previous[plan[0]]) return {'plan': plan, 'length': length, 'num_visited_nodes': np.sum(previous != unvis_node), 'name': 'Djikstra', 'time': t.toc(), 'control': control, 'visited_nodes': previous[previous != unvis_node]}
def enqueue(self, proc, updateburst=True): """ Adds process to back of ready queue and updates PCB status/location """ if not self.active: # No processes in CPU, process goes straight to CPU # No need to prompt for time proc.set_proc_loc(self._dev_name) self.active = proc else: if updateburst: # Prompt for time since last interrupt elapsed = io.get_valid_int("Time since last interrupt") # Update burst time for current process self.active.update_burst_time(elapsed) # Insert into ready queue proc.set_proc_loc("ready") PriorityQueue.enqueue(self, proc) # Move active process to ready queue if it now has a higher # remaining burst time left than any process in the ready queue if PriorityQueue.head(self) < self.active: p = PriorityQueue.dequeue(self) self.active.set_proc_loc("ready") p.set_proc_loc("CPU") PriorityQueue.enqueue(self, self.active) self.active = p print proc.status()
def a_star(start, end): """ A* Pathfinding algorithm. Takes a start tile and end tile, and uses their neighbour list to traverse. Uses the heapq queue in queues.py. :param start: Tile :param end: Tile :return: came_from, dictionary with all tiles as key, and where we came from (parent tile) as value. cost_so_far, dictionary with tiles as key, and their cost so far as value. success, True or False. If the algorithm found the end tile or not. has_been_next, list over tiles that has been considered as the next tile. """ frontier = PriorityQueue() frontier.put(start, 0) came_from = {start: None} cost_so_far = {start: 0} has_been_next = [] success = False while not frontier.empty(): current = frontier.pop() current.visit() if current == end: print("A* Pathfinder, successful.") success = True break for next_tile in current.neighbours: if next_tile not in has_been_next: has_been_next.append(next_tile) new_cost = cost_so_far[current] + next_tile.weight if next_tile not in cost_so_far or new_cost < cost_so_far[ next_tile]: cost_so_far[next_tile] = new_cost priority = new_cost + heuristic(end, next_tile) frontier.put(next_tile, priority) came_from[next_tile] = current return came_from, cost_so_far, success, has_been_next
def best_first_graph_search(problem, fun, stats=False): """Search the nodes with the lowest f scores first. You specify the function f(node) that you want to minimize; for example, if f is a heuristic estimate to the goal, then we have greedy best first search; if f is node.depth then we have breadth-first search. There is a subtlety: the line "f = memoize(f, 'f')" means that the f values will be cached on the nodes as they are computed. So after doing a best first search you can examine the f values of the path returned.""" memfun = memoize(fun, 'f') node = Node(problem.initial) if problem.goal_test(node.state): return node frontier = PriorityQueue(order='min', f=memfun) frontier.append(node) explored = set() number_explored = 0 added_frontier = 0 while frontier: node = frontier.pop() #print "\n popped off frontier: " + str(node.state) if problem.goal_test(node.state): if stats: return node, number_explored, added_frontier else: return node explored.add(node.state) number_explored += 1 for child in node.expand(problem): #print "child: " + str(child.state) if child.state not in explored and child not in frontier: frontier.append(child) added_frontier += 1 elif child in frontier: incumbent = frontier[child] if memfun(child) < memfun(incumbent): del frontier[incumbent] frontier.append(child) added_frontier += 1 return None
def graph_search(problem): """graph_search(problem) - Given a problem representation attempt to solve the problem. Returns a tuple (path, path_cost) where: path - list of actions to solve the problem or None if no solution was found path_cost - Cost to execute the given path """ initial_node = Node(problem, problem.initial, problem.nodes[problem.initial]) frontier_nodes = PriorityQueue(min, Node.get_total_cost) frontier_nodes.append(initial_node) explored_nodes = Explored() nodes_explored = 0 while len(frontier_nodes) > 0: # Pop the next node from the frontier, add it to the explored set, # and increment the nodes_explored counter current_node = frontier_nodes.pop() explored_nodes.add(current_node.state) nodes_explored += 1 #Check to see if the current node is a goal state if current_node.problem.goal_test(current_node.state): return (current_node.path(), current_node.total_cost) #Generate the possible actions from the current_node successor_nodes = current_node.expand(problem) #For each successor_node, if it hasn't been explored, add it to the frontier set for node in successor_nodes: if explored_nodes.exists(node.state) is False: frontier_nodes.append(node) print("No solution found.") return (None, nodes_explored)
def min_route_distance(self, node_from, node_to): """ Gets the shortest route between two points, using Dijkstra's algorithm. This version is modified to allow for a route that traverses back to the origin if such a route is possible. Arguments: node_from - The origin point of the connection being queried. Method throws a ValueError if the node does not exist. node_to - The destination of the connection being queried. Method throws a ValueError if the node does not exist. Returns: int/float - The minimum distance to traverse to complete the shortest possible route. If the route is origin to origin and no path can be made that traverses other routes to get back to the origin, 0 is returned. If it is impossible to get from the origin to the destination when the two are different, float("inf") (i.e. infinity) is returned. """ if self.get(node_from) is None or self.get(node_to) is None: raise ValueError("Non-existant origin or destination node was " \ "given") min_distances = {} node_queue = PriorityQueue() # First, initialize min_distances with assumed min_distances for # the time being (i.e. 0 for origin, float("inf") for all possible # destinations for key in self._nodes.keys(): if key == node_from: init_minimum = 0 else: init_minimum = float("inf") min_distances[key] = init_minimum # Items in the priority queue are tuples, with the min_distance # listed first for sorting, then the key of the final point node_queue.add((init_minimum, key)) while not node_queue.is_empty(): minimum, current_node = node_queue.remove() for connected_node, connected_distance in self.get( current_node).items(): new_distance = minimum + connected_distance # If the minimum distance from here plus the distance to the # next node is less than the current minimum distance to that # node from the origin, replace it # OR - if the distance is the origin (i.e. min_distance # from origin to connected_node is zero) - this allows us to # loop back to the origin! if new_distance < min_distances[connected_node] or \ min_distances[connected_node] == 0: min_distances[connected_node] = new_distance # Prevents the origin node from being added back into the # queue, so we don't re-evaluate the whole graph again if not connected_node == node_from: node_queue.add((new_distance, connected_node)) # Now we have a dict of all of the Dijkstra min distances to # those points from the origin -- we want to return the distance # to just one point (the destination) return min_distances[node_to]
def _num_trips(self, node_from, node_to, minimum, maximum, is_distance): """ Determines the number of trips that can be made between two points within a certain number of moves, or less than a certain distance. Arguments: node_from - The origin point of the connection being queried. Method throws a ValueError if the node does not exist. node_to - The destination of the connection being queried. Method throws a ValueError if the node does not exist. minimum - The minimum moves/distance required to be made before trips are counted. Method will throw a ValueError if less than zero. maximum - The maximum moves/distance until the number of trips stop being counted and the method exits. Will throw a ValueError if less than minimum. is_distance - Whether or not we're calculating the number of trips possible based on distance (True) or number of moves (False). Returns: int - The number of possible trips given the restrictions. """ if maximum < minimum: raise ValueError("maximum ({:d}) is less than " \ "minimum ({:d})".format(maximum, minimum)) elif minimum <= 0: raise ValueError("minimum requires a value greater than zero") if self.get(node_from) is None or self.get(node_to) is None: raise ValueError("Non-existant origin or destination node was " \ "given") available_routes = 0 # We start by building a priority queue made of tuples, which contains # origin node and the number of moves or distance needed to get there. # Then, we start populating the queue with the # name of connecting nodes and the number of connections traversed # or distance traversed to get from the origin to that point. trip_queue = PriorityQueue() trip_queue.add((0, node_from)) while not trip_queue.is_empty(): current_node = trip_queue.remove() # leave the loop now if we've reached the maximum. # in the current data set, our maximum move count limit is based # on being less than OR EQUAL TO the maximum, while the distance # limit is based on being LESS THAN to the maximum ONLY. That # conditional is reflected here. if is_distance and current_node[0] >= maximum: break elif not is_distance and current_node[0] > maximum: break # add to the count if we've reached the destination and # we're above our minimum if current_node[1] == node_to and current_node[0] >= minimum: available_routes += 1 # continue adding to the queue - if we're measuring by distance, # add the distance to the next node. Else, just increment by one # and keep going. for connected_node, distance in self.get(current_node[1]).items(): if is_distance: increment = distance else: increment = 1 trip_queue.add((current_node[0] + increment, connected_node)) return available_routes
def timedGameScoreSearch(graph, playerKey, timeout): startPos = graph.getPosition(playerKey) counter = 0 frontier = PriorityQueue() graphKey = graph.getStateKey() foundKey = None frontier.put(graphKey, 0) cameFrom = {} costSoFar = {} startKey = graph.getStateKey() expandedNodes[startKey] = graph cameFrom[startKey] = None costSoFar[startKey] = 0 bestHeuristicSoFar = 99999 bestFoundSoFar = startKey targetScore = 50 while not frontier.empty(): counter += 1 if counter > 1999: break currentKey = frontier.get() current = expandedNodes[currentKey] if time.time() > timeout: foundKey = bestFoundSoFar logger.info("breaking because of timeout, counter: " + str(counter)) break #check for goal if current.getScore() > targetScore: foundKey = currentKey logger.info("breaking because found, counter: " + str(counter)) break nCounter = 0 for next in current.neighbors(playerKey): nCounter += 1 nextKey = next.getStateKey() expandedNodes[nextKey] = next newCost = costSoFar[currentKey] + 1 #graph.cost(current, next, playerKey) if nextKey not in costSoFar or newCost < costSoFar[nextKey]: costSoFar[nextKey] = newCost heuristic = next.cleverScoreHeuristic(targetScore) if heuristic < bestHeuristicSoFar and len(next.neighbors(playerKey)) > 0: bestFoundSoFar = nextKey bestHeuristicSoFar = heuristic priority = newCost + heuristic cameFrom[nextKey] = currentKey if len(next.neighbors(playerKey)) > 0: # add to frontier if I am alive in this NODE #Add large penalty for states where an opponent can blow me up so we only remove from frontier if absolutely nescecerry #get position nextPosition = next.getPosition(playerKey) inOpponentDangerZone = next.testIfInOpponentDanger(nextPosition) #logger.info("inOpponentDangerZone: %s" % inOpponentDangerZone) #check if in simulatedBombZone opponentDangerPenalty = 0 if inOpponentDangerZone: opponentDangerPenalty = 999 frontier.put(nextKey, priority + opponentDangerPenalty) #logger.info("returning from timedGameStarSearch, counter: " + str(counter)) return cameFrom, costSoFar, foundKey, startKey
from queues import PriorityQueue class Golfer: def __init__(self, name, score): self.name = name self.score = score def __str__(self): return "{0:16}: {1}".format(self.name, self.score) def __gt__(self, other): return self.score < other.score # less is more tiger = Golfer("Tiger Woods", 61) phil = Golfer("Phil Mickelson", 72) hal = Golfer("Hal Sutton", 69) pq = PriorityQueue() for g in [tiger, phil, hal]: pq.insert(g) while not pq.is_empty(): print(pq.remove())
class DiskDrive(PriorityQueue): """ Initializes new disk drive with device name and two empty queues to implement FLOOK disk scheduling """ def __init__(self, dname, cyl): self._dev_type = "Disk Drive" self._dev_name = dname self._cylinders = cyl # Two priority queues to implement FSCAN. Q2 is frozen self._q1 = PriorityQueue() self._q2 = PriorityQueue(True) ## Methods to check/return device properties def get_num_cylinders(self): return self._cylinders def is_device_name(self, query_name): return True if self._dev_name == query_name else False def get_dev_name(self): return self._dev_name def is_device_type(self, query_type): return True if self._dev_type == query_type else False def get_dev_type(self): return self._dev_type def contains(self, pid): return (self._q1.contains(pid) or self._q2.contains(pid)) ## Scheduling methods def enqueue(self, proc): """ Enqueue processes to unfrozen queue. Update process location. If frozen queue is empty, unfreeze and freeze other queue """ if self._q1.is_frozen(): #Q1 is frozen, add to Q2 proc.set_proc_loc(self._dev_name) self._q2.enqueue(proc) if self._q1.empty(): self._q2.freeze() self._q1.unfreeze() else: #Q2 frozen, add to Q1 proc.set_proc_loc(self._dev_name) self._q1.enqueue(proc) if self._q2.empty(): self._q1.freeze() self._q2.unfreeze() def dequeue(self): """ Remove and return process at head of frozen queue. Clear any parameters passed when queued. Only dequeue processes from whichever queue is frozen. If dequeuing empties queue, freeze queue and unfreeze other queue """ if self._q1.is_frozen(): proc = self._q1.dequeue() if self._q1.empty(): self._q2.freeze() self._q1.unfreeze() else: proc = self._q2.dequeue() if self._q2.empty(): self._q1.freeze() self._q2.unfreeze() proc.clear_params() return proc def terminate(self, pid): if self._q1.contains(pid): self._q1.terminate(pid) if self._q1.is_frozen() and self._q1.empty(): self._q1.unfreeze() self._q2.freeze() elif self._q2.contains(pid): self._q2.terminate(pid) if self._q2.is_frozen() and self._q2.empty(): self._q2.unfreeze() self._q1.freeze() else: raise IndexError ## Methods to print device in human readable form to console def __repr__(self): return self._dev_name + " (" + self._dev_type.lower() + ")" def __str__(self): """ Returns device name and type as a string """ return self._dev_type + " " + self._dev_name def snapshot(self): """ Prints active processes in disk drive queue, in order they will be processed """ print io.snapshot_header(self._dev_name) if self._q1.empty() and self._q2.empty(): print '{:^78}'.format("EMPTY: No processes in queue") else: if self._q1.is_frozen(): print io.snapshot_header("PROCESSING [FROZEN]", "-") self._q1.snapshot() print io.snapshot_header("NEW REQUESTS", "-") self._q2.snapshot() else: print io.snapshot_header("PROCESSING [FROZEN]", "-") self._q2.snapshot() print io.snapshot_header("NEW REQUESTS", "-") self._q1.snapshot()