我正在创建一个老鼠穿过迷宫的迷宫模拟。 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_score
和 f_score
变量,只需将启发式添加到该行的末尾以及 d[stNode]
的初始化>.
关于c - 将 Dijkstra 算法修改为 A* 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11810516/