c - 将 Dijkstra 算法修改为 A* 实现

标签 c implementation graph-algorithm dijkstra a-star

我正在创建一个老鼠穿过迷宫的迷宫模拟。 Dijkstra 的算法很棒,但当涉及到猫时,效果并不是特别明显,这就是为什么我尝试将现有的 Dijkstra 实现修改为 A* 搜索,并采用启发式方法来避免在迷宫中移动的猫。

当我查看一些伪代码时,我遇到的问题是我不确定哪些结构是等效的,或者我需要引入什么才能使其正常工作。任何人都可以提供任何提示或插入正确的方向吗?

struct path_node *shortestPath(float A[GsizeSqr][GsizeSqr], int xi, int yi, int xf, int yf)
{
    /*
    Solves for the shortest path between grid point (xi,yi) and (xf,yf)
    on the graph encoded by A using Dijkstra's shortest path method.

    The shortest path is returned as a linked list of nodes to be visited.

    Keep track of visited nodes, and the predecessor
    for each node that has been explored while computing the shortest path.*/

    if (xi<0||xi>=Gsize&&yi<0&&yi>=Gsize||xf<0||xf>=Gsize||yf<0||yf>=Gsize)
    {
        fprintf(stderr,"shortestPath(): Endpoint(s) outside of the graph!\n");
        return(NULL);
    }

    int i, j, pCount, findN, row, col, icnt, stNode, finNode, xcnt, ycnt;
    finNode = yf * ceil(sqrt(GsizeSqr)) + xf; //index of start node given its row and col value
    stNode = yi * ceil(sqrt(GsizeSqr)) + xi; //index of finish node given its row and col value

    int p[GsizeSqr]; //predecessors
    int d[GsizeSqr]; //distance from source
    int flags[GsizeSqr]; //(0, 1) for unvisited, visited)

    int g_score[GsizeSqr];
    int f_score[GsizeSqr];

    PriorityQueue Q; //Initialize priority queue that stores (priority, key) values
    Q = init_heap(GsizeSqr);    

    path_node *start; //Maintain a pointer to the starting node
    start = newPathNode(xi, yi);
    start->next = NULL;

    //Initialize p and d with infinity and NULL values (note: -1 means null and 1000000 means inf)
    for(i=0; i < GsizeSqr; i++){
        p[i] = -1;
        d[i] = 10000000;
        flags[i] = 0;
    }

    for(i=0; i < GsizeSqr; i++){
        node in;
        in = create_node(10000000, i);
        enqueue(Q, in);
    }

    //(Note: PQ uses 0 as a sentinel node to make calculating left, right, and parents easier, elements begin at 1)
    decrease_priority(Q, stNode+1, 0); //setting start node in PQ.
    d[stNode] = 0;

    g_score[stNode] = 0;
    //For my heuristic, I'm thinking just using manhattan distances between mouse and cat agents
    f_score[stNode] = g_score[stNode] + heuristic(xi, yi, xf, yf);

    while(Q->heap_size != 1){ //while Q not empty
        node u;
        u = dequeue(Q);
        flags[u.key] = 1;

        //For each adjacent node A[u.key][i]
        for(i=0; i < GsizeSqr; i++){
            if(A[u.key][i] != 0){
                findN = find_node(Q, i);
                if(flags[i] == 0){ //If it is unvisited and new path distance is shorter
                    if(findN != 0 && (d[i] >= A[u.key][i] + d[u.key])){ //reset values and update PQ and mark visited
                        d[i] = A[u.key][i] + d[u.key];
                        p[i] = u.key;                       
                        flags[i] = 1;
                        decrease_priority(Q, findN, d[i]);
                    }
                }
            }
        }
    }

    // Begin selectively filling our LL with values from p[]
    icnt = finNode;
    appendLL(start, xf, yf);
    while(icnt != stNode){
        icnt = p[icnt];
        xcnt = icnt % (int)ceil(sqrt(GsizeSqr));
        ycnt = icnt / (int)ceil(sqrt(GsizeSqr));
        appendLL(start, xcnt, ycnt);
    }

    clean_heap(Q);
    return reverseLL(start);
}

最佳答案

您可能已经知道这一点,但就最佳优先搜索而言,A* 和 Dijkstra 算法之间唯一的理论上区别在于成本函数 f(n)。 Dijkstra 算法为 f(n) = g(n),而 A* 为 f(n) = g(n) + h(n)。阅读 AIMA了解详情。

就您的代码而言,它当前将g(n) = A[u.key][i] + d[u.key]存储在d[i]中code>,所以你需要将其更改为存储 g(n) + h(n)。您不需要这些新的 g_scoref_score 变量,只需将启发式添加到该行的末尾以及 d[stNode] 的初始化>.

关于c - 将 Dijkstra 算法修改为 A* 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11810516/

相关文章:

c - 二分法实现中的意外 C 行为

generics - 为什么具有 const 泛型 bool 值的方法不能调用为 true 和 false 都实现的方法?

python - 二叉搜索树 Python,实现删除

c - 用户定义的数据类型/操作到 CPU 指令集

c - sizeof 运算符不计算子表达式?

c - 如何在 xcode 4 的库项目中使用自定义 dylib?

c++ - 必须做什么才能将程序转换为强大的 OpenMP 感知版本?

algorithm - 使用高程查找最短路径的图算法

algorithm - 运行 Johnson 算法后回溯

algorithm - 寻找最大重量的子图