【问题标题】:Why isn't my implementation of the A* search algorithm working?为什么我的 A* 搜索算法的实现不起作用?
【发布时间】:2020-07-25 21:30:02
【问题描述】:

我试图找到从N*N 网格的左上角到右下角的最短路径。我已经为此编写了广度优先搜索解决方案,但我想知道是否可以改用 A* 搜索算法来提高算法的运行时间。

我的 A* 搜索算法代码如下:

int H(int item, int end, int N){ // heuristic function: euclidean distance from item to exit
    return ((item/N-end/N)*(item/N-end/N) + (item%N-end%N)*(item%N-end%N));
}

int Astar(int start, int end, const vector <vector<int>> &adj, int N){
    vector <bool> visited(adj.size(), false);
    vector <int> dist(adj.size(), INF);
    priority_queue <pi, vector<pi>, greater<pi>> Q;

    Q.push({0, start});
    dist[0] = 0;

    while(!Q.empty()){
        int curr = Q.top().second;
        Q.pop();

        if(visited[curr]){continue;}
        visited[curr] = true;

        if(curr == end){break;}

        for(int item : adj[curr]){
            if(dist[curr] + 1 < dist[item]){
                dist[item] = dist[curr] + 1;
                Q.push({dist[item] + H(item), item});
            }
        }
    }

    print(visited, N);

    return dist[end];
}

但是,我的实现似乎不起作用。我很困惑,因为 A* 搜索算法被描述为与 Dijkstra 算法几乎完全相同,除了在优先级队列中添加了一个启发式函数。这是我上面的实现找不到最短路径的情况:

S.........
..........
..........
...#######
...#......
..##.###..
.....#.#..
..####....
.....#....
..####..#E

# are obstacles
S is the start and E is the end
Can move up, down, left, or right only

The answer should be 22 but my function returns 24

请注意,在我的代码中,通过将每个 (x, y) 坐标映射到 (x*N + y),我将每个正方形表示为单个整数而不是一对整数,其中 N 是高度和宽度网格。

那么,我的问题是,我是否误解了我的代码中的 A* 搜索算法?有人可以告诉我如何更改我的代码以产生正确的输出吗?

【问题讨论】:

  • 考虑visited[curr]检查的效果,当重新访问的成本低于原始访问时。
  • H 有三个参数时,你只能用一个参数调用它。
  • 你为什么只用一个 arg 调用 H?预计 3 个参数。

标签: c++ algorithm a-star


【解决方案1】:

您的实施无法正常工作,因为您的启发式方法与您拥有的移动选项不匹配。具体来说,您的启发式是欧几里得距离启发式,而移动仅限于上、下、左和右。

换句话说,你的启发式是可以接受的,但不是一致的。这意味着它不能保证第一次访问目的地会返回最优路径。为了保证这一点,您需要一个一致的启发式算法,例如曼哈顿距离。

Wikipedia Admissible Heuristics

Wikipedia Consistent Heuristics

上述两篇文章的关键要点是,您的启发式应该 (A) 是可接受的,或者总是低估实际成本(您的欧几里德距离启发式所做的)和 (B) 是一致的,这意味着它的估计总是 不满足(B)。然而,曼哈顿距离(在没有障碍物的情况下,只有上、下、左和右达到目标的最小可能方式)完全符合这两个要求。

【讨论】:

    猜你喜欢
    • 2023-03-29
    • 1970-01-01
    • 2016-10-16
    • 2016-12-20
    • 2021-12-15
    • 1970-01-01
    • 2015-03-30
    • 1970-01-01
    • 2017-07-11
    相关资源
    最近更新 更多