A star 搜索入门

终于学习了传说中的A*搜索~...

先通俗的说一下A*搜索的原理,然后用代码实现~

A*搜索是在基于广搜的基础上的一种启发式搜索方式(我也不知道启发式是什么意思),可以大大降低搜索时间,找出相对正确的最优路径。

这里用到了特殊的存储结构---优先队列,可以优化将查找的复杂度从O(n)有化成O(logn);

1、首先我们从原点开始进行A*搜索,把原点入队列,然后标记为已访问

2.接收优先队列队列第一个元素并pop掉,判断第一个元素相邻的八个位置,如果其中有的位置是障碍物或者超出地图范围或者已经访问过,则排除,其他位置入栈,并用pre指针指向父节点

3.找出其中相对h+g最优的解(可用优先队列实现),重复2步骤,直到找到终点;

代码实现

#include <iostream>
#include <cstdio>
#include <queue>
#include <cmath>
using namespace std;

int dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}};

struct node
{
    bool visit;
    int x,y;
    double hx,gx;//核心
    char ch;
    node *pre;

    node()
    {
        visit = 0;
        pre = NULL;
    }
}map[51][51],start,end;

bool judge(int x, int y)
{
    if(x>=0 && x<=50 && y>=0 && y<=50)
        return true;
    else
        return false;
}

double Euclidean_dis(int sx,int sy,int ex,int ey){//欧几里德
    double nn;
    nn=sqrt((sx-ex)*(sx-ex)+(sy-ey)*(sy-ey));
    return nn;
}

double Chebyshev_dis(int sx,int sy,int ex,int ey){//切比雪夫
    double nn;
    nn=max(abs(sx-ex),abs(sy-ey));
    return nn;
}

double jiaquan_Manhattan(int sx,int sy,int ex,int ey){//加权曼哈顿   //better
    double nn,dx,dy;
    dx=abs(sx-ex);
    dy=abs(sy-ey);
    if(dx>dy)
        nn=10*dx+6*dy;
    else
        nn=6*dx+10*dy;
    return nn;
}

//重载运算符
bool operator<(node a, node b)
{
    return a.gx + a.hx > b.gx + b.hx;
}

//寻找路径
void viewback()
{
    node *p;
    p = map[end.x][end.y].pre;

    while(p)
    {
        if(p->pre)
        {
            p->ch = ‘v‘;
        }
        p = p->pre;
    }
    return;
}

void Astar()
{
    priority_queue<node> q;
    q.push(start);

    int xx,yy;
    int i;

    while(!q.empty())
    {
        node now = q.top();
        q.pop();

        if(now.x==end.x&&now.y == end.y)
        {
            break;
        }

        for(int i=0; i<4; i++)
        {
            xx = now.x + dir[i][0];
            yy = now.y + dir[i][1];

            if(!judge(xx, yy)||map[xx][yy].ch == ‘x‘ || map[xx][yy].visit == 1)
            {
                continue;
            }

            map[xx][yy].visit = 1;
            map[xx][yy].pre = &map[now.x][now.y];

            map[xx][yy].hx = jiaquan_Manhattan(xx, yy, end.x, end.y);

            map[xx][yy].gx = now.gx + 1;

            q.push(map[xx][yy]);
        }
    }
    return ;
}

int main()
{
    freopen("t.txt", "r", stdin);
    int i,j,visi_num=0;
    for(i=0;i<50;i++){
        for(j=0;j<50;j++){
            cin>>map[i][j].ch;
            map[i][j].x=i;
            map[i][j].y=j;
            if(map[i][j].ch==‘s‘){
                map[i][j].gx=0;
                map[i][j].visit=1;

                start=map[i][j];
            }
            if(map[i][j].ch==‘e‘)
                end=map[i][j];
        }
        getchar();
    }
    cout<<"结果---------------------------------------------------"<<endl;
    Astar();
    viewback();

    for(i=0;i<50;i++){
        for(j=0;j<50;j++){
            visi_num+=map[i][j].visit;
            if(map[i][j].ch==‘v‘ || map[i][j].ch==‘e‘ || map[i][j].ch==‘s‘)
                printf("%c",map[i][j].ch);
            else if(map[i][j].visit)
                printf("%d",map[i][j].visit);
            else
                printf("%c",map[i][j].ch);
        }
        cout<<"\n";
    }
    printf("\n遍历节点 %d 个\n",visi_num);
    return 0;
}

这个代码写的很好,我从网上好不容易找到的~...

时间: 2024-10-26 19:40:56

A star 搜索入门的相关文章

搜索入门之dfs--经典的迷宫问题解析

今天来谈一下dfs的入门,以前看到的dfs入门,那真的是入门吗,都是把dfs的实现步骤往那一贴,看完是知道dfs的步骤了,但是对于代码实现还是没有概念.今天准备写点自己的心得,真的是字面意思--入门. DFS,即深度优先搜索,是一种每次搜索都向尽可能深的地方去搜索,到达尽头时再回溯进行其他结点去搜索的搜索策略.形象的说,这是一种“不撞南墙不回头”的策略. 其实也就是遍历,只不过不像一个线性数组的遍历那么直观罢了.说到回溯,每次看到这个词我都得思考一会,到底是怎么用栈进行回溯的呢?今天实际操作了一

POJ 1579 Function Run Fun 【记忆化搜索入门】

题目传送门:http://poj.org/problem?id=1579 Function Run Fun Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 20560   Accepted: 10325 Description We all love recursion! Don't we? Consider a three-parameter recursive function w(a, b, c): if a <=

深度搜索入门

深度优先搜索是搜索的手段之一.它从某个状态开始,不断地转移状态,直到无法转移,然后回退到前一步的状态,继续转移到其他状态,如此重复,直到找到最终的解. 做这类题目,抓住两样东西:1.总体上递归几次(几层)?每一次递归确定一层上的数. 2.每次递归,有几种选择的情况.所以dfs()函数,只有两部分(if.else结构):1.(if部分)若每一层都选择了,判断是否符合条件,做出题目要求的操作.2.(else部分)若还有层没有选择,就做出选择,所有选择的情况列出. 下面是几个考察dfs的题目: 1.部

app后端搜索入门

现在人们的网络生活已经离不开搜索了,遇到不懂的问题,想知道的事情,搜索一下,就知道答案. 在app中,最常见的搜索情景就是搜索用户.只有几百,几千的用户量时,可以直接用用like这样的模糊查询,但是,如果数据有几百万,甚至上千万的时候,一次like查询数据库就堵了.到了一定量级的时候,不得不考虑使用专门的搜索技术. 1.    一个简单的搜索例子 有三行数据: (1)近2周8成股民亏损超10%. (2)满仓中国梦. (3)股民两天亏一套三居. 例如,有个需求,从上面的3行数据中,把包含“股民”这

DFS搜索入门(第一次写不完善的还请指出,谢谢大家支持)

题意:给定从1到n的n个数,这些数中有一些和其他数存在一种关系.给定所有关系,并给初值ans为1:将这n个数以一种顺序取出,(每当取出的数与之前已取出的数存在关系,ans值将翻倍.)最后使得ans值最大. 思路解析:本题中数字间关系可以在图中表示出来.列如n = 9:m = 9:(1,2): (1,4): (2,3): (2,4): (7,2):(4,7):(5,8):(5,6):(8,6): 这样就可以将数字间的关系用图清晰的表示出来,而任意一个连通图中的点的个数p决定ans值最大的翻倍次数为

深度优先搜索入门:POJ1164城堡问题(递归、用栈模拟递归)

将问题的各状态之间的转移关系描述为一个图,则深度优先搜索遍历整个图的框架为:Dfs(v) {if( v 访问过)return;将v标记为访问过;对和v相邻的每个点u: Dfs(u);}int main() {while(在图中能找到未访问过的点 k) Dfs(k);} 例题: POJ1164 The Castle Description 1 2 3 4 5 6 7 ############################# 1 # | # | # | | # #####---#####---#-

35.app后端搜索入门

现在人们的网络生活已经离不开搜索了,遇到不懂的问题,想知道的事情,搜索一下,就知道答案. 在app中,最常见的搜索情景就是搜索用户.只有几百,几千的用户量时,可以直接用用like这样的模糊查询,但是,如果数据有几百万,甚至上千万的时候,一次like查询数据库就堵了.到了一定量级的时候,不得不考虑使用专门的搜索技术. 1.    一个简单的搜索例子 有三行数据: (1)近2周8成股民亏损超10%. (2)满仓中国梦. (3)股民两天亏一套三居. 例如,有个需求,从上面的3行数据中,把包含"股民&q

N皇后//搜索入门

P1080 N皇后 时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 检查一个如下的6 x 6的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行.每列只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子. 列号  1  2  3  4  5  6 ------------------------- 1 |  | O |  |  |  |  | ------------------------- 2 |  |  |  | O |  |  | --

简单搜索入门

1.query string search2.query DSL3.query filter4.full-text search5.phrase search6.highlight search*****************************************************************************************1.query string search搜索全部商品:GET /index/type/_search例如: GET /ecom