def least_cost_path (graph, coord, start, dest, cost): '''This function takes in any graph supplied by the user, by default the only graph built by the script is the edmonton roads graph. This function can also take in any cost function of two variables, start and destination. ''' heap = MinHeap() # create a min heap heap.add(0, (start, start)) # dist, (vertice, prior vertice) reached = {} # dictionary of vertices reached with their shortest cost and prior vertice while not heap.isempty(): # run the program until the heap is empty curr_dist, (curr_vert, pri_vert) = heap.pop_min() # pop the min cost vertice and explore it, aka extract minimum distance runner for v in graph.neighbours(curr_vert): temp_dist = curr_dist + cost(coord, curr_vert, v) # Find new distance if (v in reached and temp_dist < reached[v][1]) or v not in reached: # Check if the key has been used already reached[v] = (curr_vert, temp_dist) # Previous Vertice, distance if v != dest: heap.add(temp_dist, (v, curr_vert)) min_path = [] # Trace back the shortest path if dest in reached: # First check if there is even a path min_path.insert(0,dest) curr_id = reached[dest][0] prior_id = dest while prior_id != start: # trace back until we reach the start from dest min_path.insert(0,curr_id) # keep adding prior vert to front of list prior_id = curr_id if prior_id not in reached: return min_path curr_id = reached[prior_id][0] return min_path, reached[dest]
def least_cost_path(graph, start, dest, cost): reached = {} # For faster implementation, use MinHeap to substitute runners tree = MinHeap() tree.add((0, start, start), None) while tree and dest not in reached: #print("tree: " + str(tree._array)) (dist, prev, curr) = tree.pop_min()[0] if curr in reached: continue reached[curr] = prev for succ in graph.neighbours(curr): tree.add((dist + cost(curr, succ), curr, succ), None) if dest not in reached: return [] #print("reached: ", reached) path = [] v = dest while True: path.append(v) if path[-1] == start: break v = reached[v] path = path[::-1] #print("path: ", path) return path
def least_cost_path(graph, coord, start, dest, cost): '''This function takes in any graph supplied by the user, by default the only graph built by the script is the edmonton roads graph. This function can also take in any cost function of two variables, start and destination. ''' heap = MinHeap() # create a min heap heap.add(0, (start, start)) # dist, (vertice, prior vertice) reached = { } # dictionary of vertices reached with their shortest cost and prior vertice while not heap.isempty(): # run the program until the heap is empty curr_dist, (curr_vert, pri_vert) = heap.pop_min( ) # pop the min cost vertice and explore it, aka extract minimum distance runner for v in graph.neighbours(curr_vert): temp_dist = curr_dist + cost(coord, curr_vert, v) # Find new distance if ( v in reached and temp_dist < reached[v][1] ) or v not in reached: # Check if the key has been used already reached[v] = (curr_vert, temp_dist ) # Previous Vertice, distance if v != dest: heap.add(temp_dist, (v, curr_vert)) min_path = [] # Trace back the shortest path if dest in reached: # First check if there is even a path min_path.insert(0, dest) curr_id = reached[dest][0] prior_id = dest while prior_id != start: # trace back until we reach the start from dest min_path.insert(0, curr_id) # keep adding prior vert to front of list prior_id = curr_id if prior_id not in reached: return min_path curr_id = reached[prior_id][0] return min_path, reached[dest]
def make_tree(freq_table): trees = MinHeap() trees.add(1, TreeLeafEndMessage()) for (symbol, freq) in freq_table.items(): trees.add(freq, TreeLeaf(symbol)) while len(trees) > 1: (rfreq, right) = trees.pop_min() (lfreq, left) = trees.pop_min() trees.add(lfreq + rfreq, TreeBranch(left, right)) (totalfreq, tree) = trees.pop_min() return tree
def make_tree (freq_table): trees = MinHeap() trees.add(1, TreeLeafEndMessage()) for (symbol, freq) in freq_table.items(): trees.add(freq, TreeLeaf(symbol)) while len(trees) > 1: (rfreq, right) = trees.pop_min() (lfreq, left) = trees.pop_min() trees.add(lfreq+rfreq, TreeBranch(left, right)) (totalfreq, tree) = trees.pop_min() return tree
def shortestpath(tilemap, startnode, goalnode): ''' Find the shortestpath between the startnode and the goalnode Input Arguments: tilemap: the tile map object startnode: the location of start tile on the map (xtile, ytile) goalnode: the location of the goal tile on the map (xtile, ytile) Note: startnode and goalnode must be walkable (in the tilemap.legaltileLoc set) Return: path: A shortest path list containing the tile locations from start tile to goal tile ''' # reached dict, key: v_to, value: (actualcost, v_from) reached = dict() # explorenode minheap, key: totalcost, value: (actualcost, v_from, v_to) # totalcost = actualcost + heuristiccost explorenode = MinHeap() explorenode.add(0, (0, startnode, startnode)) # The node to be explored, key: v_to, value: (actualcost, v_from) explorenodedict = dict() explorenodedict[startnode] = (0, startnode) while len(explorenode) > 0: # Get the node with minimun total cost totalcost, checknode = explorenode.pop_min() actualcost, v_from, v_to = checknode if v_to in reached: # node has already been reached continue # Add v_to to reached dict reached[v_to] = (actualcost, v_from) # Remove v_to from explorenodedict del explorenodedict[v_to] if v_to == goalnode: # reached goal break # Explore the neighbour nodes of v_to for neighbournode in nodeneighbour(tilemap, v_to): if neighbournode in reached: # Don't do anything if the neighbournode has already been reached continue # Check if the neighbournode is in the explorenode dict if neighbournode in explorenodedict: # Check if the new actualcost (v_to's actualcost + 1) is less than the old actualcost if explorenodedict[neighbournode][0] > (reached[v_to][0] + 1): # Update the actualcost and v_from for neighbournode explorenodedict[neighbournode] = (reached[v_to][0] + 1, v_to) newtotalcost = reached[v_to][0] + 1 + heuristiccost( neighbournode, goalnode) # Add the neighbournode with newtotalcost to minheap explorenode.add( newtotalcost, (reached[v_to][0] + 1, v_to, neighbournode)) else: # Add neighbournode to explorenodedict explorenodedict[neighbournode] = (reached[v_to][0] + 1, v_to) # Add neighbournode to explorenode minheap totalcost = reached[v_to][0] + 1 + heuristiccost( neighbournode, goalnode) explorenode.add(totalcost, (reached[v_to][0] + 1, v_to, neighbournode)) # The path from start to dest path = [] if goalnode in reached: path.append(goalnode) while reached[goalnode][1] != startnode: path.append(reached[goalnode][1]) goalnode = reached[goalnode][1] if goalnode != startnode: path.append(startnode) path.reverse() return path
#used to find top 10 job and states from count import Counting from minheap import MinHeap import sys #get the count for every job and state count = Counting(sys.argv[1]) job_count, state_count, sum_count = count.count() #find the top_10 jobs job_heap = MinHeap(10) job_fhandle = open(sys.argv[2],'w') for key,value in job_count.items(): job_heap.add(key,value) job_fhandle.write('TOP_OCCUPATIONS;NUMBER_CERTIFIED_APPLICATIONS;PERCENTAGE\n') result = dict() for i in range(min(10,len(job_count))): key,value = job_heap.extract() result[key.lstrip('""').rstrip('""')] = value result = sorted(result.items(), key = lambda item:item[0]) result.sort(key = lambda x:x[1], reverse = True) for item in result: key = item[0] value = item[1] p = round(value / sum_count * 100.0, 1) s = key + ';' + str(value) + ';' + str(p) + '%' + '\n' job_fhandle.write(s) #find the top_10 states state_heap = MinHeap(10) state_fhandle = open(sys.argv[3],'w')