def test_PriorityQueue_RemoveElement_ElementIsRemoved(self): priority_queue = PriorityQueue() priority_queue.add("a") priority_queue.remove("a") self.assertFalse("a" in priority_queue)
def test_PriorityQueue_ChangePriority_GetPriorityReturnsNewPriority(self): priority_queue = PriorityQueue() priority_queue.add("a", 0) priority_queue.change_priority("a", 5) p_a = priority_queue.get_priority("a") self.assertEquals(p_a, 5)
def test_PriorityQueue_Peek_ReturnsElementWithLowestPriority(self): priority_queue = PriorityQueue() priority_queue.add("a", 2) priority_queue.add("b", 3) priority_queue.add("c", 1) elm, pri = priority_queue.peek() self.assertEquals(elm, "c")
def test_PriorityQueue_PopAllSmallerThan_LIstIsEmpty(self): priority_queue = PriorityQueue() priority_queue.add("a", 2) priority_queue.add("b", 1) priority_queue.remove("b") l = priority_queue.pop_smaller_than(3) self.assertEquals(list(priority_queue), [])
def test_PriorityQueue_RemoveFirstElement_StatesRemaingCorrect(self): priority_queue = PriorityQueue() priority_queue.add("a", 1) priority_queue.add("b", 2) priority_queue.remove("a") self.assertEquals(list(priority_queue), [('b', 2)]) self.assertEquals(len(priority_queue), 1)
def test_PriorityQueue_NonEmptyQueueToString_ReturnsCorrectString(self): priority_queue = PriorityQueue() priority_queue.add("a", 2) priority_queue.add("b", 3) priority_queue.add("c", 1) s = str(priority_queue) self.assertEquals(s, "<PriorityQueue[(c,1),(a,2),(b,3)]>")
def test_PriorityQueue_GetPriority_ReturnsCorrectPriority(self): priority_queue = PriorityQueue() priority_queue.add("a", 0) priority_queue.add("b", 1) p_a = priority_queue.get_priority("a") p_b = priority_queue.get_priority("b") self.assertEquals(p_a, 0) self.assertEquals(p_b, 1)
def test_priority_and_sort_order(): p = PriorityQueue() p.add(1, 1) p.add(2, 1) p.add(3, 2) p.add(4, 1) assert p.pop() == 3 assert p.pop() == 1 assert p.pop() == 2 assert p.pop() == 4 assert p.peek() is None
class WorldSolverStatesSearch: def __init__(self): self.priority_queue = PriorityQueue() self.closed_set = set() self.debuging_list = [] def search(self, start_state): self.priority_queue.add( start_state, start_state.price + start_state.get_heuristic_estimate()) while not self.priority_queue.is_empty(): current = self.priority_queue.pop() # print(f"retrieving: {current.price + current.heuristic_estimate}") # print(f"adding - g:{int(current.price)} - h:{int(current.heuristic_estimate)} - f: {int(current.price + current.heuristic_estimate)}") if current.is_final(): return current self.closed_set.add(current) for neighbour in current.generate_all_neighbours(): if neighbour in self.closed_set: continue self.debuging_list.append(neighbour) heuristics = neighbour.get_heuristic_estimate() # if(heuristics + neighbour.price) < (current.heuristic_estimate + current.price): # print("wtf") # print(f"adding - g:{neighbour.price} - h:{heuristics} - f: {neighbour.price + heuristics}") self.priority_queue.add(neighbour, neighbour.price + heuristics) def get_path(self, final_state): id_to_states = { state.unique_solver_state_id: state for state in list(self.closed_set) } states = [final_state] previous_id = states[-1].previous_unique_solver_state_id while previous_id is not None: state = id_to_states[previous_id] states.append(state) previous_id = states[-1].previous_unique_solver_state_id states.reverse() return states
def get_min_cost_path(self, start, end): queue = PriorityQueue() previous = {vertex: None for vertex in self.__graph.parse_vertices()} distances = { vertex: math.inf for vertex in self.__graph.parse_vertices() } visited = set() queue.add(end, 0) visited.add(end) distances[end] = 0 while not queue.is_empty(): current_vertex = queue.pop() if current_vertex == start: # Build path path = [] while current_vertex is not None: path.append(current_vertex) next_vertex = None try: next_vertex = previous[current_vertex] except KeyError: pass current_vertex = next_vertex return path for edge in self.__graph.parse_in(current_vertex): next_vertex = edge.start current_distance = distances[current_vertex] + edge.cost if next_vertex not in visited: queue.add(next_vertex, current_distance) visited.add(next_vertex) if current_distance < distances[next_vertex]: distances[next_vertex] = current_distance previous[next_vertex] = current_vertex return []
def dijkstra(graph, start, end): pq = PriorityQueue() visited = {} costs = {} prev = {} costs[start] = 0 pq.add(start, costs[start]) visitCount = 0 while not pq.isEmpty(): current = pq.poll() visited[current] = True neighbors = graph.paths[current] neighborsCosts = graph.costs[current] for i in xrange(len(neighbors)): n = neighbors[i] currentCost = costs[current] + neighborsCosts[i] if not n in costs or costs[n] > currentCost: costs[n] = currentCost prev[n] = current unvisited = not n in visited if unvisited: pq.add(n, costs[n]) visited[n] = True if not end in costs: return "None" finalPath = [] current = end while costs[current] != 0: finalPath.append(current) current = prev[current] finalPath.append(start) return (list(reversed(finalPath)), costs[end])
def dijkstra(graph, start, end): queue = PriorityQueue() visited = {} costs = {} prev = {} costs[start] = 0 queue.add(start, costs[start]) visitCount = 0 while not queue.isEmpty(): current = queue.poll() visited[current] = True neighbors = graph.neighborsOf(current) for neighbor in neighbors: neighborCost = neighbors[neighbor] currentCost = costs[current] + neighborCost if not neighbor in costs or costs[neighbor] > currentCost: costs[neighbor] = currentCost prev[neighbor] = current unvisited = not neighbor in visited if unvisited: queue.add(neighbor, costs[neighbor]) visited[neighbor] = True if not end in costs: return "None" finalPath = [] current = end while costs[current] != 0: finalPath.append(current) current = prev[current] finalPath.append(start) return (list(reversed(finalPath)), costs[end])
def dijkstra(graph, source): parents = [None] * graph.V distances = [float('inf')] * graph.V distances[source] = 0 visited = set() queue = PriorityQueue() queue.add(source, 0) while len(queue) > 0: vertex, distance = queue.pop() visited.add(vertex) for neighbor, weight in graph.neighborsWithWeights(vertex): if neighbor in visited: continue candidateDistance = distance + weight if candidateDistance >= distances[neighbor]: continue distances[neighbor] = candidateDistance parents[neighbor] = vertex queue.update(neighbor, candidateDistance) return parents, distances
def dijkstras(initial_node, destination_node, edge_set_by_node): distances = {key: float('inf') for key in edge_set_by_node.keys()} distances[initial_node] = 0 current_node = initial_node visited = set() to_visit = PriorityQueue(distances) to_visit.add(current_node) while not to_visit.empty and destination_node not in visited: neighbors = edge_set_by_node[current_node] current_distance = distances[current_node] for neighbor in neighbors: node = neighbor[0] new_distance = current_distance + neighbor[1] if node not in visited and distances[node] > new_distance: distances[node] = new_distance if node not in to_visit.nodes: to_visit.add(node) visited.add(current_node) current_node = to_visit.get_next() return distances[destination_node]
def test_PriorityQueue_ChangePriorityUsingAddRemoveElement_PeekReturnsLowestElement(self): priority_queue = PriorityQueue() priority_queue.add("a", 2) priority_queue.add("b", 3) priority_queue.add("c", 1) priority_queue.add("d", 0) priority_queue.remove("c") priority_queue.add("c", 4) elm, pri = priority_queue.peek() self.assertEquals(elm, "d")
def testPQ(self): pq = PriorityQueue() self.assertEqual(len(pq), 0) pq.add(3, 0) self.assertEqual(len(pq), 1) pq.update(3, 1) self.assertEqual(len(pq), 1) item, priority = pq.pop() self.assertEqual(item, 3) self.assertEqual(priority, 1) self.assertEqual(len(pq), 0) pq.add(1, 10) pq.add(2, 5) self.assertEqual(pq.pop(), (2, 5)) self.assertEqual(pq.pop(), (1, 10))
def simulate_waiting(time_span=timedelta(days=1), time_delta=timedelta(minutes=3), verbose=False, queue_method="prioritize_treatment_time", number_of_exam_rooms=HospitalConstant.EXAM_ROOMS, number_of_doctors=HospitalConstant.NUM_DOCTORS, setAttributes=True, use_linear_rise_fall=True, basic_patients_per_hour=None, portion_time_doc_spend=False, portionChange=0.25, get_infected_percent=False): """Main simulation function. Simulates the cycle of treat-and-release patients going from the waiting room, to the exam room, to leaving in an Emergency Department. :param number_of_exam_rooms: Number exam rooms to use :param number_of_doctors: Number of doctors to use :param setAttributes: Parameter only used in making graphs :param use_linear_rise_fall: Parameter only used in making graphs :param basic_patients_per_hour: Parameter only used in making graphs :param portion_time_doc_spend: Parameter only used in making graphs :param portionChange: Parameter only used in making graphs :param get_infected_percent: Parameter only used in making graphs :return: Average waiting time, or if appropriate, portion of patients infected :param verbose: If True, print info in simulation. :param time_span: Length of full simulation. :param time_delta: Time between movements in simulation. :param queue_method: 2 alternative queuing method """ doctors = [Doctor() for _ in range(number_of_doctors)] exam_rooms = [ExamRoom() for _ in range(number_of_exam_rooms)] entrance_style = PatientEntranceStyles() # print("queue_method = ", queue_method) if (queue_method == "first_come_first_serve"): waiting_queue = PriorityQueue() elif (queue_method == "prioritize_treatment_time"): waiting_queue = PriorityQueue(alg=QueueingAlgorithm.fast_first) start_datetime = datetime.datetime(2020, 1, 1) cur_datetime = datetime.datetime(2020, 1, 1) # SIMULATION CURRENT TIME end_datetime = start_datetime + time_span # patients_to_generate = 0.0 # Place for all patients that came through the clinic. Used for # conclusions, not the actual simulation. patients_visiting = [] num_loops = 0 total_num_patients_infected = 0 # --- MAIN LOOP FOR SIMULATION --- while cur_datetime < end_datetime: num_loops += 1 cur_datetime += time_delta # Add elapsed time in simulation exam_rooms_available = [] # Exam rooms to fill for exam_r in exam_rooms: if exam_r.patient is None: exam_rooms_available.append(exam_r) # --- FILLING ROOMS WITH PATIENTS --- while waiting_queue.has_patients_waiting() and \ len(exam_rooms_available) > 0: cur_patient = waiting_queue.get() cur_exam_room = exam_rooms_available[-1] # Remove availability of selected exam room exam_rooms_available = exam_rooms_available[:-1] cur_patient.serve(cur_datetime) if verbose: print("Served patient", cur_patient.id) cur_exam_room.patient = cur_patient # --- UPDATE DOCTOR ACTIVITIES --- if portion_time_doc_spend == False: for doctor in doctors: doctor.update_activity(time_delta) # For different portion time if portion_time_doc_spend == True: for doctor in doctors: doctor.update_activity_change_portion_time( time_delta, portion=portionChange) # --- FILLING WITH DOCTORS --- doctors_available = [] for doctor in doctors: if doctor.state is DoctorState.READY: doctors_available.append(doctor) for exam_r in exam_rooms: if len(doctors_available) < 1: break if exam_r.doctor is None and exam_r.patient is not None and \ not exam_r.patient.seen_by_doctor: doctors_available[-1].enter_exam_room(cur_datetime) exam_r.doctor = doctors_available[-1] if verbose: print("Doctor", exam_r.doctor.id, "entered for patient", exam_r.patient.id) doctors_available = doctors_available[:-1] # --- DOCTOR VISIT COMPLETIONS --- for exam_r in exam_rooms: if exam_r.doctor is not None and \ exam_r.doctor.has_completed_patient_visit(cur_datetime): if verbose: print("Doctor", exam_r.doctor.id, "left for patient", exam_r.patient.id) # exam_r.doctor.exit_exam_room() exam_r.make_doctor_exit() exam_r.patient.seen_by_doctor = True # --- VACATE ROOMS APPROPRIATELY --- for exam_r in exam_rooms: if exam_r.patient is not None and \ exam_r.patient.has_completed_visit(cur_datetime): exam_r.patient.exit(cur_datetime) if verbose: print("Patient", exam_r.patient.id, "left") exam_r.reset() # --- GIVE INFECTIONS --- patients_waiting = waiting_queue.get_queue_patients() num_infected_waiting = 0 for patient in patients_waiting: if patient.infected: num_infected_waiting += 1 for patient in patients_waiting: if not patient.infected and \ patient.try_contract_infection( time_delta, num_infected_waiting): total_num_patients_infected += 1 if verbose: print("Patient infected!!") # For different configurations of the simulation, patients will be # added at different intervals here patients_to_generate = None if use_linear_rise_fall: patients_to_generate = entrance_style.rise_and_fall_linear( num_loops, time_delta) else: patients_to_generate = entrance_style.basic( time_delta, basic_patients_per_hour) for i in range(patients_to_generate): patient = Patient(setAttributes) waiting_queue.add(patient, cur_datetime) patients_visiting.append(patient) # mins_elapsed = time_delta.total_seconds() / 60 # # patients_per_minute = HospitalConstant.PATIENTS_PER_HOUR / 60.0 # # patients_to_generate += mins_elapsed * patients_per_minute # unqueued_patients = [Patient() for _ # in range(int(patients_to_generate))] # # patients_to_generate -= int(patients_to_generate) # # print("it would gen", entrance_style.rise_and_fall_linear(num_loops, # time_delta), "patients here") # # # --- QUEUE PATIENTS --- # for patient in unqueued_patients: # waiting_queue.add(patient, cur_datetime) # patients_visiting.append(patient) # Conclusions total_wait_time = 0 total_served_patients = 0 for i in range(len(patients_visiting)): if patients_visiting[i].time_queued is None or \ patients_visiting[i].time_served is None: continue total_served_patients += 1 wait_time_patient_delta = patients_visiting[i].time_served - \ patients_visiting[i].time_queued wait_time_patient_mins = time_delta_to_minutes(wait_time_patient_delta) total_wait_time += wait_time_patient_mins global avg_wait_time avg_wait_time = total_wait_time / total_served_patients # print("total_served_patients = ", total_served_patients) # print("Average wait time for simulation:", avg_wait_time, "minutes.") # Number of patients infected # print(total_num_patients_infected, "total_num_patients_infected") portion_patients_infected = total_num_patients_infected / len( patients_visiting) if get_infected_percent: return portion_patients_infected return avg_wait_time # , total_served_patients
def makePriorityQueue(distances): queue = PriorityQueue() for vertex, distance in enumerate(distances): queue.add(vertex, distance) return queue
def solve(self): """Algorithm for solving the 8-puzzle.""" # Set costs for the starting state current = self.start current.g = 0 current.h = self.getHeuristic(current) current.f = current.g + current.h # Initialize the OPEN and CLOSED sets OPEN = PriorityQueue() OPEN.add(current) OPENF = {} # f-value for the OPEN tiles CLOSED = set() CLOSEDF = {} # f-value for the CLOSED tiles # Current best f-value best = inf # A* algorithm while OPEN: # Pop the state with the lowest f-value current = OPEN.pop() # Terminate algorithm if lowest f-value from OPEN is higher than # current best if current.f >= best: return self.checkSolution(best, current, len(CLOSED)) # Move current from OPEN to CLOSED CLOSED.add(current) CLOSEDF[str(current.tiles)] = current.f # Investigate the successor states successors = current.getSuccessors() for successor in successors: # Change A and B to change the algorithm operation # A = 1, B = 1 -> A* # A = 0, B = 1 -> GBF # A = 1, B > 1 -> WA* A = self.A B = self.B successor.g = current.g + 1 successor.h = self.getHeuristic(successor) successor.f = A * successor.g + B * successor.h # Check if successor goal state better than current best if successor.tiles == self.goal.tiles: best = min(best, successor.g) # If successor state can be found in OPEN or CLOSED with a # better f-value move to next successor if self.findInSet(successor, OPENF): continue if self.findInSet(successor, CLOSEDF): continue # Append valid successor to OPEN OPEN.add(successor) OPENF[str(successor.tiles)] = successor.f return self.checkSolution(best, current, len(CLOSED))
import random from priority_queue import PriorityQueue # Test the priority queue returns the elements in ascending order of priority pq = PriorityQueue() N = 20 ordered = list(range(N)) shuffled = list(range(N)) random.shuffle(shuffled) for x in shuffled: pq.add(x, x) popped = [] while not pq.is_empty(): popped.append(pq.pop()) assert ordered == popped # Test the priority queue returns the elements in descending order of priority pq = PriorityQueue() ordered = list(range(N))[::-1] # reversed order shuffled = list(range(N)) random.shuffle(shuffled) for x in shuffled: pq.add(x, -x) # use '-' to change the priority
def test_PriorityQueue_AddElement_ElementIsAdded(self): priority_queue = PriorityQueue() priority_queue.add("a", 0) self.assertTrue("a" in priority_queue)
def test_PriorityQueue_PopSmallerThan_ReturnsThePopedElements(self): priority_queue = PriorityQueue() priority_queue.add("a", 2) priority_queue.add("b", 3) priority_queue.add("c", 1) priority_queue.add("d", 0) priority_queue.remove("c") priority_queue.add("c", 4) priority_queue.remove("b") priority_queue.add("e", 7) priority_queue.add("f", 5) priority_queue.add("g", 6) priority_queue.add("h", 10) l = priority_queue.pop_smaller_than(6) self.assertEquals(l, [('d', 0), ('a', 2), ('c', 4), ('f', 5)]) self.assertEquals(list(priority_queue), [('g', 6), ('e', 7), ('h', 10)])