简体   繁体   中英

Python, Dijkstra's Algorithm visualization

I'm trying to visualize Dijkstra's Algorithm in python where each node is a square - see picture below. but something feels a bit off. I compared the result of the shortest path with standard A* and im not getting exactly the same path. I think my code is off but I don't realize how exactly.

I'm using PriorityQueue

grid is a List of lists of objects -

each object represents a cube on the screen-

draw - draws the grid onto screen

the code inside ** -code- ** is the part I edited after posting the question.


def dijkstra_algorithm(grid, start, end):
    # set up dist (distance to start) with infinity
    dist = {elem: float("inf") for row in grid for elem in row}

    # distance from start to start is 0.
    dist[start] = 0

    # set up prev dict - prev[V] = U - represents that the shortest current path to X is through U
    prev = {}

    # create Priority Queue based on distance from origin and insert start to PQ
    PQ = PriorityQueue()
    counter = 0
    # create hash table to check if element is inside PQ.
    PQ.put((0, counter, start))
    PQ_hash = {start}

    # insert every elem except start into PQ with distance infinity
    for row in grid:
        for elem in row:
            if elem != start:
                PQ.put((dist[elem],**float("inf")**, elem))
                PQ_hash.add(elem)


    # iterate untill PQ is empty
    while not PQ.empty():
        

        current = PQ.get()[1]  # get element with min distance - index 1 in (dist[elem], elem)

        # if what's left is infinitly far - there is no path from start to end
        if dist[current] == float('inf'):
            return False

        PQ_hash.remove(current)  # remove element from Hash table (PQ.get removes elem from PQ)
        current.set_closed() #(color - red)
        draw_func() #(draw the grid)
              
        if current == end: #end node found

            reconstruct_path(prev, current, draw_func) #draw path from end to start
            end.set_end()
            start.set_start()
            return True # found

        #iterate over all neighbors of current node

        for neighbor in current.neighbors:
            # if neighbor inside PQ

            if neighbor in PQ_hash: 
                #calculate distance if we go to neighbor through current (+1 distance)
                alt = dist[current] + 1

                #if quicker - update
                if alt < dist[neighbor]:
                    dist[neighbor] = alt
                    prev[neighbor] = current
                  **counter += 1 **
                    PQ.put((dist[neighbor],**counter**, neighbor))
                    neighbor.set_open() #color green
                    draw_func() #draw the grid
    #path not found
    return False

I think it has something to do with the fact that im Adding into PQ instead of editing, but I'm not sure. Also, I'm sorry about the lack of PEP8, I've tried to comment my thoughts as I went I hope it's understandable.

Tech with time - 黑色块是障碍,紫色是最短路径 - A* 搜索

Adding a counter to the elements that go into the PQ sorts everything out. PQ.put((0, counter, start)), the counter starts at zero at the beggining of the program, and each time we put an element into the PQ (the last if statement) we increment the counter, thus reducing the priority.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM