0

我正在创建一个迷宫模拟老鼠穿过迷宫的过程。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);
}
4

1 回答 1

1

您可能已经知道这一点,但 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],因此您需要将其更改为存储 g(n) + h(n)。您不需要那些新变量g_scoref_score变量,只需将启发式添加到该行的末尾并初始化d[stNode].

于 2013-02-04T08:55:15.007 回答