def receiveTxt(): aa = FibHeap() ll = input().split(', ') nums = [] for item in ll: aa.insert(int(item)) nums.append(int(item)) return aa, nums
def randomTest(): a = FibHeap() nums = [] for i in range(randint(1, 100)): num = randint(-100, 100) a.insert(num) nums.append(num) return a, nums
class FibPQ(PriorityQueue): def __init__(self): self.heap = FibHeap() def __len__(self): return self.heap.count def insert(self, node): self.heap.insert(node) def minimum(self): return self.heap.minimum() def removeminimum(self): return self.heap.removeminimum() def decreasekey(self, node, new_priority): self.heap.decreasekey(node, new_priority)
def solve(maze): # Width is used for indexing, total is used for array sizes width = maze.width total = maze.width * maze.height # Start node, end node start = maze.start startpos = start.Position end = maze.end endpos = end.Position # Visited holds true/false on whether a node has been seen already. Used to stop us returning to nodes multiple times visited = [False] * total # Previous holds a link to the previous node in the path. Used at the end for reconstructing the route prev = [None] * total # Distances holds the distance to any node taking the best known path so far. Better paths replace worse ones as we find them. # We start with all distances at infinity infinity = float("inf") distances = [infinity] * total # The priority queue. We are using a Fibonacci heap in this case. unvisited = FibHeap() # This index holds all priority queue nodes as they are created. We use this to decrease the key of a specific node when a shorter path is found. # This isn't hugely memory efficient, but likely to be faster than a dictionary or similar. nodeindex = [None] * total # To begin, we set the distance to the start to zero (we're there) and add it into the unvisited queue distances[start.Position[0] * width + start.Position[1]] = 0 startnode = FibHeap.Node(0, start) nodeindex[start.Position[0] * width + start.Position[1]] = startnode unvisited.insert(startnode) # Zero nodes visited, and not completed yet. count = 0 completed = False # Begin Dijkstra - continue while there are unvisited nodes in the queue while unvisited.count > 0: count += 1 # Find current shortest path point to explore n = unvisited.minimum() unvisited.removeminimum() # Current node u, all neighbours will be v u = n.value upos = u.Position uposindex = upos[0] * width + upos[1] if distances[uposindex] == infinity: break # If upos == endpos, we're done! if upos == endpos: completed = True break for v in u.Neighbours: if v != None: vpos = v.Position vposindex = vpos[0] * width + vpos[1] if visited[vposindex] == False: # The extra distance from where we are (upos) to the neighbour (vpos) - this is manhattan distance # https://en.wikipedia.org/wiki/Taxicab_geometry d = abs(vpos[0] - upos[0]) + abs(vpos[1] - upos[1]) # New path cost to v is distance to u + extra newdistance = distances[uposindex] + d # If this new distance is the new shortest path to v if newdistance < distances[vposindex]: vnode = nodeindex[vposindex] # v isn't already in the priority queue - add it if vnode == None: vnode = FibHeap.Node(newdistance, v) unvisited.insert(vnode) nodeindex[vposindex] = vnode distances[vposindex] = newdistance prev[vposindex] = u # v is already in the queue - decrease its key to re-prioritise it else: unvisited.decreasekey(vnode, newdistance) distances[vposindex] = newdistance prev[vposindex] = u visited[uposindex] = True # We want to reconstruct the path. We start at end, and then go prev[end] and follow all the prev[] links until we're back at the start from collections import deque path = deque() current = end while (current != None): path.appendleft(current) current = prev[current.Position[0] * width + current.Position[1]] return [path, [count, len(path), completed]]
def solve(maze): width = maze.width total = maze.width * maze.height start = maze.start startpos = start.Position end = maze.end endpos = end.Position visited = [False] * total prev = [None] * total infinity = float("inf") distances = [infinity] * total unvisited = FibHeap() nodeindex = [None] * total distances[start.Position[0] * width + start.Position[1]] = 0 startnode = FibHeap.Node(0, start) nodeindex[start.Position[0] * width + start.Position[1]] = startnode unvisited.insert(startnode) count = 0 completed = False while unvisited.count > 0: count += 1 n = unvisited.minimum() unvisited.removeminimum() u = n.value upos = u.Position uposindex = upos[0] * width + upos[1] if distances[uposindex] == infinity: break if upos == endpos: completed = True break for v in u.Neighbours: if v != None: vpos = v.Position vposindex = vpos[0] * width + vpos[1] if visited[vposindex] == False: d = abs(vpos[0] - upos[0]) + abs(vpos[1] - upos[1]) # New path cost to v is distance to u + extra. Some descriptions of A* call this the g cost. # New distance is the distance of the path from the start, through U, to V. newdistance = distances[uposindex] + d # A* includes a remaining cost, the f cost. In this case we use manhattan distance to calculate the distance from # V to the end. We use manhattan again because A* works well when the g cost and f cost are balanced. # https://en.wikipedia.org/wiki/Taxicab_geometry remaining = abs(vpos[0] - endpos[0]) + abs(vpos[1] - endpos[1]) # Notice that we don't include f cost in this first check. We want to know that the path *to* our node V is shortest if newdistance < distances[vposindex]: vnode = nodeindex[vposindex] if vnode == None: # V goes into the priority queue with a cost of g + f. So if it's moving closer to the end, it'll get higher # priority than some other nodes. The order we visit nodes is a trade-off between a short path, and moving # closer to the goal. vnode = FibHeap.Node(newdistance + remaining, v) unvisited.insert(vnode) nodeindex[vposindex] = vnode # The distance *to* the node remains just g, no f included. distances[vposindex] = newdistance prev[vposindex] = u else: # As above, we decrease the node since we've found a new path. But we include the f cost, the distance remaining. unvisited.decreasekey(vnode, newdistance + remaining) # The distance *to* the node remains just g, no f included. distances[vposindex] = newdistance prev[vposindex] = u visited[uposindex] = True from collections import deque path = deque() current = end while (current != None): path.appendleft(current) current = prev[current.Position[0] * width + current.Position[1]] return [path, [count, len(path), completed]]
graph.AddVertex(v) graph.AddEdge(u, v, float(weight)) src = input().strip() tar = input().strip() fibHeap = FibHeap() heapNodeIndex = {} dist = {} prev = {} visited = {} for node in graph.vertices: if node == src: dist[node] = 0.0 prev[node] = None visited[node] = True heapNodeIndex[node] = fibHeap.insert(0.0, node) else: dist[node] = float('inf') prev[node] = None visited[node] = False heapNodeIndex[node] = fibHeap.insert(float('inf'), node) node = src while node != tar: node = fibHeap.extractMin().value print("======") print(node) visited[node] = True for neighbor in graph.vertices[node].neighbors: print(neighbor) if visited[neighbor]:
print('Finish graph') start_point = input() if get_input: print('Finish start', start_point) end_point = input() if get_input: print('Finish end', end_point) fib = FibHeap() vis = {} info = {} # store distance / node, used to decrease key nodes = list(set(nodes)) for node in nodes: fib_node = fib.insert(x=float('inf'), vertex=(node, graph[node])) vis[node] = False info[node] = [float('inf'), fib_node] if get_input: print('Finish fib') fib.decrease_key(info[start_point][1], 0) vis[start_point] = True prev = {} # store the previous point # print(info.values()) while False in vis.values(): node_min = fib.extract_min() v = node_min.value[1] # dict object vis[node_min.value[0]] = True for adj_v, w in v.items(): # adj_v: vertex's name, w: weight