启发式搜索

一,启发式搜索

相对于经典搜索(无信息搜索),搜索方式只取决于搜索空间的直观结构,和数据之间的直观关系(一般就是朴素的大小关系),启发式搜索引入了一种基于数据的抽象关系,用来引导更快的接近搜索目标。

二,无信息搜索

DFS、BFS 【精选】DFS-优快云博客

双向BFS BFS、双向BFS-优快云博客

一致代价搜索(Uniform-cost Search,UCS),其实就是迪杰斯特拉

三,启发式搜索

1,贪婪最佳优先搜索(A算法)

也叫最佳优先搜索,关于为什么叫A算法,没找到具体的解释,据说和admissible 这个词有关:A search algorithm is said to be admissible if it is guaranteed to return an optimal solution.  optimal即最佳的。但是A算法并不能保证得到最优路径,所以这就很迷惑了。

A算法思路:

和BFS一样,初始队列中只有起点,然后每次取出一个点,把与它的相邻的不在队列中的点都加入到队列中,直到到达终点。

不同之处在于,BFS实际上是根据起点到每个点的距离进行排序的,而A算法需要根据每个点到终点的估计距离进行排序。

以HackerRank - pacman-astar为例,BFS、双向BFS-优快云博客

A算法代码:

#include<iostream>
#include<queue>
#include<unordered_map>
#include<stack>
#include<vector>
using namespace std;

#define M 100
char ch[M][M];
int row, col;


struct Point
{
    int x, y;
};
Point s, e;

int PtoI(Point s)
{
    return s.x * M + s.y;
}
Point  ItoP(int x)
{
    return { x / M,x % M };
}

bool inBoard(Point s)
{
    return s.x >= 0 && s.x < row&& s.y >= 0 && s.y < col;
}
bool available(Point s)
{
    return ch[s.x][s.y] != '%';
}

vector<Point> neighbor(Point s)
{
    int dx[] = { -1,0,1,0 };
    int dy[] = { 0,1,0,-1 };
    Point t;
    vector<Point>ans;
    for (int i = 0; i < 4; i++)
    {
        t.x = s.x + dx[i], t.y = s.y + dy[i];
        if (!inBoard(t))continue;
        if (!available(t))continue;
        ans.push_back(t);
    }
    return ans;
}

int h(Point a)
{
    return abs(a.x - e.x) + abs(a.y - e.y);
}

class cmp
{
public:
    bool operator()(Point a, Point b)
    {
        return h(a) > h(b);
    }
};


int main()
{
    cin >> s.x >> s.y >> e.x >> e.y;
    cin >> row >> col;
    for (int i = 0; i < row; i++)for (int j = 0; j < col; j++)cin >> ch[i][j];
    priority_queue<Point, vector<Point>, cmp>q;
    q.push(s);
    unordered_map<int, int>m;
    m[PtoI(s)] = 1;
    while (true)
    {
        s = q.top();
        q.pop();
        if (m[PtoI(e)])break;
        vector<Point>v = neighbor(s);
        for (auto vs : v)
        {
            if (m[PtoI(vs)])continue;
            m[PtoI(vs)] = m[PtoI(s)] + 1;
            q.push(vs);
        }
    }
    cout << m[PtoI(e)] -1 << endl;
    s = e;
    stack<Point>sp;
    for (int i = m[PtoI(e)]; i > 1; i--)
    {
        sp.push(s);
        vector<Point>v = neighbor(s);
        for (auto vs : v)
        {
            if (m[PtoI(vs)] == i - 1) {
                s = vs;
                break;
            }
        }
    }
    sp.push(s);
    while (!sp.empty()) {
        s = sp.top();
        cout << s.x << " " << s.y << endl;
        sp.pop();
    }
    return 0;
}

A算法最大的问题在于,往往得不到最优解,比如如下数据:

2 7
2 0
6 8
--------
-%%%%%%-
.%%%---P
-%%%----
-%------
--------

A算法输出的是13,

双向BFS输出的是11,这才是最优解。

2,A*搜索

A*,中文名A星,英文名A star

A*搜索是在A算法的基础之上加以改进,保证能得到最优解,而且搜索速度很快。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值