启发式搜索

一,启发式搜索

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

二,无信息搜索

DFS、BFS 【精选】DFS-CSDN博客

双向BFS BFS、双向BFS-CSDN博客

一致代价搜索(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-CSDN博客

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算法的基础之上加以改进,保证能得到最优解,而且搜索速度很快。

  • 4
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
启发搜索(Heuristic Search)是一种基于估价函数的搜索算法,它可以在大规模的状态空间中找到最优解或者近似最优解。在Python中,我们可以使用A*算法来实现启发搜索。 A*算法是一种启发搜索算法,它通过估价函数来评估每个状态的优先级,并选择优先级最高的状态进行扩展。估价函数通常是由两部分组成:启发函数和代价函数。启发函数用来估计当前状态到目标状态的距离,代价函数用来估计从起始状态到当前状态的代价。 以下是一个简单的A*算法实现: ```python def astar(start, goal, h_func, cost_func): open_set = {start} closed_set = set() g_score = {start: 0} f_score = {start: h_func(start, goal)} while open_set: current = min(open_set, key=lambda x: f_score[x]) if current == goal: return reconstruct_path(current) open_set.remove(current) closed_set.add(current) for neighbor in get_neighbors(current): if neighbor in closed_set: continue tentative_g_score = g_score[current] + cost_func(current, neighbor) if neighbor not in open_set or tentative_g_score < g_score[neighbor]: g_score[neighbor] = tentative_g_score f_score[neighbor] = tentative_g_score + h_func(neighbor, goal) if neighbor not in open_set: open_set.add(neighbor) return None ``` 其中,`start`和`goal`分别表示起始状态和目标状态,`h_func`和`cost_func`分别表示启发函数和代价函数。`get_neighbors`函数用来获取当前状态的所有邻居状态,`reconstruct_path`函数用来重构路径。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值