def astar(graph, start, goal): # Fringe. Nodes not visited yet openList = PriorityQueue() # Visited Nodes. Each one will store it's parent position closedList = {} node = Node(start) openList.push(node) while openList: node, _ = openList.pop() position, cost = node.position, node.cost if position in closedList: # Oops. Already expanded. continue # Save the node in the closed list, and keep track of its parent closedList[position] = node.parent if position == goal: break for childPosition, actionCost in graph.getChildren(position): # Only add to the open list if it's not expanded yet if not childPosition in closedList: childNode = Node(childPosition, cost + actionCost, position) openList.push( childNode, childNode.cost + graph.getHCost(childPosition, goal)) path = [] if position == goal: # Ensure a path has been found path.insert(0, position) while position and position != start: position = closedList[position] path.insert(0, position) return path
class WaitingQueue: def __init__(self): self.queue = PriorityQueue() self.log = [] def push(self, current_time, p): self.queue.push([p.healthy, current_time], p) self.log.append((Log.ENTER, p.healthy, current_time)) def empty(self): return self.queue.empty() def pop(self, current_time): p = self.queue.pop()[-1] self.log.append((Log.EXIT, p.healthy, current_time)) return p def remove(self, current_time, p): self.queue.remove(p) self.log.append((Log.EXIT, p.healthy, current_time)) def size(self): return self.queue.size()
def astar(graph, start, goal): # Fringe. Nodes not visited yet openList = PriorityQueue() # Visited Nodes. Each one will store it's parent position closedList = {} node = Node(start) openList.push(node) while openList: node, _ = openList.pop() position, cost = node.position, node.cost if position in closedList: # Oops. Already expanded. continue # Save the node in the closed list, and keep track of its parent closedList[position] = node.parent if position == goal: break for childPosition, actionCost in graph.getChildren(position): # Only add to the open list if it's not expanded yet if not childPosition in closedList: childNode = Node(childPosition, cost + actionCost, position) openList.push(childNode, childNode.cost + graph.getHCost(childPosition, goal)) path = [] if position == goal: # Ensure a path has been found path.insert(0, position) while position and position != start: position = closedList[position] path.insert(0, position) return path
def astarItemsMultiPath(graph, start, goal, itemsAvailable, initialRaftState, illegalEdges): #itemsAvailable = intialItems.copy() #print("initial state") print(itemsAvailable) # Fringe. Nodes not visited yet openList = PriorityQueue() # Visited Nodes. Each one will store it's parent position closedList = {} nodeTable = {} # assign some start and goal points # and push start point as a node to openList. start_tuple = tuple(start) goal_tuple = tuple(goal) node = PathNode(start_tuple, itemsAvailable.copy()) node.setRaftState(initialRaftState) openList.push(node) while openList: # if openList does not contain any node # we will break. curr_node, _ = openList.pop() if not curr_node: break position, cost = curr_node.position, curr_node.cost if position in closedList: # Oops. Already expanded. continue # Save the node in the closed list, and keep track of its parent if curr_node.parent != None: closedList[position] = curr_node.parent.position else: closedList[position] = curr_node.position #track of its items remainings nodeTable[position] = curr_node # arrived to goal so save it as goal node. if position == goal_tuple: goalNode = curr_node break # copy some parent properties curr_available = curr_node.getItemAvailable() raftState = curr_node.getRaftState() parentStonePlace = curr_node.getStonePlaced().copy() # for each legal child for current parent, for childPosition, actionCost, itemRequired, element in graph.getChildren( position, curr_available, raftState, parentStonePlace): copyStonePlaced = parentStonePlace.copy() # if illegal edges were given # and current one is illegal, ignore current child. pos1 = list(position).copy() pos2 = childPosition if illegalEdges and ([pos1, pos2] in illegalEdges or [pos2, pos1] in illegalEdges): continue # Only add to the open list if it's not expanded yet if not tuple(childPosition) in closedList: # copyAvailableItem copy_available_item = curr_available.copy() # deduct from item list if it was required if itemRequired: copy_available_item = deductItem(copy_available_item, itemRequired) childRaftSate = raftState # updating child raftstate based on where current child is # and the item required to get to the child. if itemRequired == 'r': childRaftSate = 1 elif childRaftSate == 1 and element != '~': childRaftSate = 0 # updating the stone coordinate that was used for child. # append to the parent ones. stoneCoord = [] if itemRequired == 'o': stoneCoord = [childPosition] #print(stoneCoord) copyStonePlaced += stoneCoord # creating new child node and push to the openlist childNode = PathNode(tuple(childPosition), copy_available_item, cost + actionCost, curr_node, childRaftSate) childNode.addStonePlaced(copyStonePlaced) openList.push( childNode, childNode.cost + graph.getHCost(childPosition, goal)) # intialize the returning variables path = [] totalItemUsed = [] totalNewItemCollected = [] itemUsedState = False finalItemList = itemsAvailable finalRaftState = 1 finalStonePlace = [] # if we arrive goal, we are updating those variables. if position == goal_tuple: finalItemList = goalNode.getItemAvailable() itemUsedState = confirmItemUsed(finalItemList, itemsAvailable) finalRaftState = goalNode.getRaftState() finalStonePlace = goalNode.getStonePlaced() # Ensure a path has been found position_list = list(position) path.insert(0, position_list) while position and position != start_tuple: position = closedList[position] position_list = list(position) path.insert(0, position_list) return [ path, itemUsedState, finalItemList, finalRaftState, finalStonePlace, nodeTable ] #finalItemList, ]
def get_ready_queue(job_list, pattern, time_quantum): # obtain job key function as key for priority queue comparison job_key = job_keys[pattern] if job_key == round_robin: job_list.sort(key=first_come_first_serve) i = 0 while i < len(job_list): job = job_list[i] job.instance_id = i if job.duration > time_quantum: split_job = Job(job.arrival + time_quantum, job.duration - time_quantum, job.priority, job.id, True) job.terminate = False job.duration = time_quantum job_list.append(split_job) i += 1 global last_index last_index.clear() # prepare job queue job_queue = PriorityQueue(job_list, key=job_key) # prepare the ready queue ready_queue = [] global time_elapsed time_elapsed = 0 global idd idd = 0 def schedule(job): # schedule a job to the ready queue if ready_queue and ready_queue[-1].id == job.id: # merge with the previous job because same ID # this happens when pre-emptive ready_queue[-1].duration += job.duration ready_queue[-1].terminate = job.terminate else: # append new job ready_queue.append(job) # update time elapsed after scheduling global time_elapsed time_elapsed = ready_queue[-1].end() global last_index, idd last_index[job.id] = idd idd += 1 # simulate scheduling algorithm while job_queue: # get the next job job = job_queue.pop() global last_index if job.idd != (last_index[job.id] if job.id in last_index else -1): job.idd = (last_index[job.id] if job.id in last_index else -1) job_queue.push(job) elif job.arrival < time_elapsed: # this job will arrive later, repush to the queue job.arrival = time_elapsed #job.instance_id = Job.instance_id #Job.instance_id += 1 job_queue.push(job) elif job_key == round_robin and job.duration > time_quantum: # split job into two for round robin part_two = Job( arrival = job.arrival + time_quantum, duration = job.duration - time_quantum, priority = job.priority, job_id = job.id, terminate = job.terminate ) # part_two.instance_id = job.instance_id + len(job_list) job_queue.push(part_two) # repush part 2 # process part 1 job.duration = time_quantum job.terminate = False job_queue.push(job) # schedule(job) elif not pre_emptive(job_key): # schedule immediately schedule(job) else: # pre_emptive # special case: find possible jobs that can interrupt put_back = [] interrupted = False while job_queue and job_queue.top().arrival < job.end(): # check if the next job is better than having the other end of the current job interrupt = job_queue.top() split_job = Job( arrival = interrupt.arrival, duration = job.end() - interrupt.arrival, priority = job.priority, job_id = job.id, terminate = job.terminate ) # print interrupt, 'wants to interrupt', split_job # print job_key(interrupt), job_key(split_job) if job_key(interrupt) < job_key(split_job): # job has been interrupted! split then repush into the queue job.duration -= split_job.duration job.terminate = False # push new parts of the job job_queue.push(job) job_queue.push(split_job) interrupted = True break put_back.append(job_queue.pop()) # return tested jobs back into queue for tested_job in put_back: job_queue.push(tested_job) if not interrupted: # finalize job schedule schedule(job) return ready_queue
def solve(mode): if mode == 1: # test code for grid class print("sup") a = Grid([0, 1, 2, 3, 4, 5, 6, 7, 8]) b = Grid([1, 2, 3, 8, 0, 4, 7, 6, 5]) c = Grid([0, 1, 2, 3, 4, 5, 6, 7, 8]) print(a) print(b) print(c) print("a = b? %s" % a.equals(b)) print("a = c? %s" % a.equals(c)) print("a = c? %s" % Grid.equal(a, c)) print("is a soln? %s" % a.is_solution()) print("is b soln? %s" % b.is_solution()) if mode == 2: # test code for node class a = Node(Grid([0, 1, 2, 3, 4, 5, 6, 7, 8]), 0, 0) b = Node(a.data, a, 0) a.print_tree() if mode == 3: # test code for get_moves() soln = Grid([1, 2, 3, 8, 0, 4, 7, 6, 5]) a = Node(generate_problem(soln), 0, 0) a.print_tree() for move in a.data.get_moves(): print(move) Node(Grid(a.data.move(move)), a, 0) a.print_tree() if mode == 4: # A* search algorithm pq = PriorityQueue() soln = Grid([1, 2, 3, 8, 0, 4, 7, 6, 5]) root = Node(generate_problem(soln), 0, 0) def expand_node(node): # expands node to generate all possible moves if len(node.children) == 0: for move in node.data.get_moves(): m = Grid(node.data.move(move)) if not root.find_item(m): # makes sure there are no duplicates Node(m, node, move) if root.data.is_solution(): return pq.push(root, 0) gui = EightPuzzleGUI() best = B(root) gui.draw_grid(best.data.data, gui.mainFrame, 50) def increment(button, button1): gui.mainFrame.update() nxt = pq.pop() # gets next thing in PQ expand_node(nxt) if len(pq) > 0: gui.draw_grid(pq.data.data[0][0].data, gui.rightFrame1, 12) if len(pq) > 1: gui.draw_grid(pq.data.data[1][0].data, gui.rightFrame2, 12) if len(pq) > 2: gui.draw_grid(pq.data.data[2][0].data, gui.rightFrame3, 12) if len(pq) > 3: gui.draw_grid(pq.data.data[3][0].data, gui.rightFrame4, 12) if len(pq) > 4: gui.draw_grid(pq.data.data[4][0].data, gui.rightFrame5, 12) for child in nxt.children: # adds children to PQ with h(n) + g(n) # gui.draw_grid(child.data, gui.mainFrame, 50) if child.data.h_score() < best.data.data.h_score(): best.data = child gui.draw_grid(best.data.data, gui.mainFrame, 50) pq.push(child, child.data.h_score() + 0.5 * child.level) if child.data.is_solution(): button.destroy() button1.destroy() # print(child.moves) gui.draw_moves(child.moves) return True # pq.print() return False def loop_to_end(button, button1): # loops until solution is found while True: if increment(button, button1): return start = tk.Button(gui.root, text="Increment", command=lambda: increment(start, loop), width=5, height=5) start.grid(column=0, row=4, sticky=tk.N + tk.S + tk.E + tk.W) loop = tk.Button(gui.root, text="Loop", command=lambda: loop_to_end(start, loop), width=5, height=5) loop.grid(column=1, row=4, sticky=tk.N + tk.S + tk.E + tk.W) gui.root.mainloop()
def get_ready_queue(job_list, pattern, time_quantum): # obtain job key function as key for priority queue comparison job_key = job_keys[pattern] if job_key == round_robin: job_list.sort(key=first_come_first_serve) i = 0 while i < len(job_list): job = job_list[i] job.instance_id = i if job.duration > time_quantum: split_job = Job(job.arrival + time_quantum, job.duration - time_quantum, job.priority, job.id, True) job.terminate = False job.duration = time_quantum job_list.append(split_job) i += 1 global last_index last_index.clear() # prepare job queue job_queue = PriorityQueue(job_list, key=job_key) # prepare the ready queue ready_queue = [] global time_elapsed time_elapsed = 0 global idd idd = 0 def schedule(job): # schedule a job to the ready queue if ready_queue and ready_queue[-1].id == job.id: # merge with the previous job because same ID # this happens when pre-emptive ready_queue[-1].duration += job.duration ready_queue[-1].terminate = job.terminate else: # append new job ready_queue.append(job) # update time elapsed after scheduling global time_elapsed time_elapsed = ready_queue[-1].end() global last_index, idd last_index[job.id] = idd idd += 1 # simulate scheduling algorithm while job_queue: # get the next job job = job_queue.pop() global last_index if job.idd != (last_index[job.id] if job.id in last_index else -1): job.idd = (last_index[job.id] if job.id in last_index else -1) job_queue.push(job) elif job.arrival < time_elapsed: # this job will arrive later, repush to the queue job.arrival = time_elapsed #job.instance_id = Job.instance_id #Job.instance_id += 1 job_queue.push(job) elif job_key == round_robin and job.duration > time_quantum: # split job into two for round robin part_two = Job(arrival=job.arrival + time_quantum, duration=job.duration - time_quantum, priority=job.priority, job_id=job.id, terminate=job.terminate) # part_two.instance_id = job.instance_id + len(job_list) job_queue.push(part_two) # repush part 2 # process part 1 job.duration = time_quantum job.terminate = False job_queue.push(job) # schedule(job) elif not pre_emptive(job_key): # schedule immediately schedule(job) else: # pre_emptive # special case: find possible jobs that can interrupt put_back = [] interrupted = False while job_queue and job_queue.top().arrival < job.end(): # check if the next job is better than having the other end of the current job interrupt = job_queue.top() split_job = Job(arrival=interrupt.arrival, duration=job.end() - interrupt.arrival, priority=job.priority, job_id=job.id, terminate=job.terminate) # print interrupt, 'wants to interrupt', split_job # print job_key(interrupt), job_key(split_job) if job_key(interrupt) < job_key(split_job): # job has been interrupted! split then repush into the queue job.duration -= split_job.duration job.terminate = False # push new parts of the job job_queue.push(job) job_queue.push(split_job) interrupted = True break put_back.append(job_queue.pop()) # return tested jobs back into queue for tested_job in put_back: job_queue.push(tested_job) if not interrupted: # finalize job schedule schedule(job) return ready_queue
def solve_cube(): def expand_node(node): # expands node to generate all possible moves if len(node.children) == 0: for i in range(6): m = deepcopy(node.data) m.rotate_face(list(Facing)[i]) if not root.find_item(m): # makes sure there are no duplicates Node(m, node, list(Facing)[i]) def increment(button, button1): gui.mainFrame.update() nxt = pq.pop() # gets next thing in PQ expand_node(nxt) # print(nxt.data) if len(pq) > 0: gui.draw_cube(pq.data.data[0][0].data, gui.rightFrame1, 10) if len(pq) > 1: gui.draw_cube(pq.data.data[1][0].data, gui.rightFrame2, 10) if len(pq) > 2: gui.draw_cube(pq.data.data[2][0].data, gui.rightFrame3, 10) if len(pq) > 3: gui.draw_cube(pq.data.data[3][0].data, gui.rightFrame4, 10) if len(pq) > 4: gui.draw_cube(pq.data.data[4][0].data, gui.rightFrame5, 10) for child in nxt.children: # adds children to PQ with h(n) + g(n) # gui.draw_grid(child.data, gui.mainFrame, 40) if child.data.h_score() < best.data.data.h_score(): best.data = child gui.draw_grid(best.data.data, gui.mainFrame, 40) pq.push(child, child.data.h_score() + 4 * child.level) if child.data.h_score() == 0: button.destroy() button1.destroy() # print(child.data) # print(child.moves) # print("done idiot") gui.draw_moves(child.moves) return True # pq.print() return False def loop_to_end(button, button1): for i in range(999): if increment(button, button1): return pq = PriorityQueue() root = Node(Cube(), 0, -1) root.data.scramble(6) # print(root.data) gui = EightPuzzleGUI() pq.push(root, 0) best = B(root) start = tk.Button(gui.root, text="Increment", command=lambda: increment(start, loop), width=5, height=5) start.grid(column=0, row=4, sticky=tk.N + tk.S + tk.E + tk.W) loop = tk.Button(gui.root, text="Loop", command=lambda: loop_to_end(start, loop), width=5, height=5) loop.grid(column=1, row=4, sticky=tk.N + tk.S + tk.E + tk.W) gui.root.mainloop()