Show Time: 请高手具体介绍一下A*算法的思想

boyfling 2002-12-22 08:23:24
Show Time: 请高手具体介绍一下A*算法的思想
...全文
70 19 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
IO_X 2003-02-08
  • 打赏
  • 举报
回复
从一个点(sx,sy)出发到(dx,dy),
需要一颗网状树,树根所在就是(sx,sy),
而从(sx,sy)开始有n个方向可以走,
那么每个分支点至多有n个child,
(一般小于n个,因为要排除不可行走或走回头路的情况,而且有可能两个parent指向同一child)
以次类推...
(注意每个分支点要包含parent成员,以便逆向返回,有时一个child有
多个parent,那么就指向已走距离最短的那个parent)

A 例如:AB距离<AC距离,那么E的parent应该指向B。
/\
B C
/\/\
D E F

但关键是个优先问题,每次循环必须用最有价值的分支点
(即:已走距离+离目标点的最短距离 的值最小的分支点)进行下一步分支,
(分支点必须是未访问的或价值有更改的)
因而最后找到的一个最有价值的分支点往往是目标点(如果有解)。

然后从目标点开始通过每个分支点的parent逆向返回,
记录下每个坐标,或做一些需要做的事。
loneststar 2003-02-08
  • 打赏
  • 举报
回复
A* 算法实际是一种启发式搜索,
f(n) = g(n) + h(n).
g(n) 是从开始节点到当前节点的 价值.
h(n) 是从当前节点到目标节点的 估价值.一般可采用 两点间的距离来衡量.
算法的关键是找到最小的f(n)
实际上,搜索过程中需要不断的更新当前节点的子节点的.因为,从某个时刻得到的当前节点的最优子节点并不一直是最佳的.
如:
************************
* A *
* 213 *
* ************* *
* B *
************************
从A 到B,一般先找到1,A就指向了1,然后1指向2或3.事实上,A的下一个节点此时就不应该是1了,而应该更新为2或3.
因此,A* 中
设置两个表:OPEN和CLOSED。OPEN表保存了所有已生成而未考察的节点,CLOSED表中记录已访问过的节点。算法中有一步是根据估价函数重排OPEN表。这样循环中的每一步只考虑OPEN表中状态最好的节点。
popkiler 2003-01-15
  • 打赏
  • 举报
回复
A*其实就是A算法的特例啊,A算法是属于一种启发信息的搜索算法
用f(n)=g(n)+h(n)来启发搜索过程的。g(n)是用来记录从
开始节点到现在节点的耗散值,h(n)是到达目标节点还需多少
不过h(n)可以自己定义的,条件不限

而A*限制h(n)《=h*(n);即必须小于等于实际需要的耗散值

ZhangYv 2003-01-12
  • 打赏
  • 举报
回复
确切的说是在负极大值(极大极小值算法)上多了个分枝限界的剪枝过程,你去看专门的书籍才可能详细知道是怎么回事。
ZhangYv 2003-01-12
  • 打赏
  • 举报
回复
就是多了个分枝限界的剪枝过程。
看看博奕论和人工智能方面的书,国内这方面的书比较少,所以最好去找英文资料
Numbfish 2003-01-08
  • 打赏
  • 举报
回复
你好,你想做即时战略吗?交个朋友吧!QQ:39226611
关于a*的思想就是一种搜索,我自己感觉就是"从近到远,从自己指向目标"
简单做法就是
a | b | c
_________
d | e | f
_________
g | h | i
判断e要满足: e-1<=b/d/f/h e-1.414<=a/c/g/i
其他的以此类推
献丑了:)
feng 2003-01-07
  • 打赏
  • 举报
回复
是广度优先搜索算法的改良。就是在当前点,根据特定的评估函数,计算出到达目的点的最优点,依次类推,直到得到最短路径。
nuclear_all 2003-01-05
  • 打赏
  • 举报
回复
《人工智能》这本书在书店的哪部分找啊??
计算机部分吗??
mountainfrank 2002-12-27
  • 打赏
  • 举报
回复
最短路径问题,看看算法书,会有帮助
boyfling 2002-12-26
  • 打赏
  • 举报
回复
只是思想 不是代码
boyfling 2002-12-26
  • 打赏
  • 举报
回复
呵呵 好吧
zhang_jiang 2002-12-26
  • 打赏
  • 举报
回复
你慢慢看啊,程序里还有不少缺点,比如一个“回”字形的图就会产生错误了。:(你去改改吧,我现在忙着考试呢,改完了发给我,谢谢。
zhang_jing333@yahoo.com.cn
madmanahong 2002-12-25
  • 打赏
  • 举报
回复
<<人工智能>>有 中文版吗?
晕~中国不可能落后到没有~:)

天堂里的死神 2002-12-25
  • 打赏
  • 举报
回复
有的啊,还很多呢,清华大学的,还有机械工业出版社的。我们学得是清华的,太差劲了!机工那本翻译过来的书还行,你可以去书市看看,好好挑一本心爱的:)
zhang_jiang 2002-12-25
  • 打赏
  • 举报
回复
// .cpp file:
////////////////////////////////////////////////////////////////////////
// A*搜寻路径法
//#define NDEBUG
#include <stdio.h>
#include <conio.h>
#include <assert.h>
#include <stdlib.h>
#include <memory.h>
#include "astar_ai.h"

LINK sort_queue; // 保存没有处理的行走方法的节点
LINK store_queue; // 保存已经处理过的节点 (搜索完后释放)

// 障碍物——空格,无物——'0'
unsigned char map[48][65]=
{
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000000"},
}; //地图数据
unsigned int dis_map[48*65]; //保存搜索路径时,中间目标地最优解

int map_w=64,map_h=48; //地图宽和高
int start_x=0,start_y=0,end_x=0,end_y=0; //地点,终点坐标


// 初始化开始地点和终结地点:
void init_dots(int sx,int sy,int ex,int ey)
{
start_x=sx;
start_y=sy;
end_x=ex;
end_y=ey;
}

// 初始化队列,两个队列的第一个节点都没有用到!
void init_queue()
{
sort_queue=(LINK)malloc(sizeof(*sort_queue));
sort_queue->node=NULL;
sort_queue->f=-1;
sort_queue->next=(LINK)malloc(sizeof(*sort_queue));
sort_queue->next->node=NULL;
sort_queue->next->f=MAXINT;
sort_queue->next->next=NULL;

store_queue=(LINK)malloc(sizeof(*store_queue));
store_queue->node=NULL;
store_queue->f=-1;
store_queue->next=NULL;
}

// 待处理节点入队列, 依靠对目的地估价距离插入排序,不分层次、只凭大小,故能找到最短的路径!
void enter_queue(TREE node,int f)
{
LINK p=sort_queue,father,q;
while(f>p->f)
{
father=p;
p=p->next;
assert(p);
}
q=(LINK)malloc(sizeof(*q));
assert(sort_queue);
q->f=f,q->node=node,q->next=p;
father->next=q;
}

// 将离目的地估计最近的方案出队列,放到store_queue中去
TREE get_from_queue()
{
LINK bestchoice=sort_queue->next;
LINK next=sort_queue->next->next;
sort_queue->next=next;

bestchoice->next=store_queue->next;
store_queue->next=bestchoice;
return bestchoice->node;
}

// 释放栈顶节点,从store_queue中!
void pop_stack()
{
LINK s=store_queue->next;
assert(s);
store_queue->next=store_queue->next->next;
free(s->node);
free(s);
}

// 释放申请过的所有节点
void freetree()
{
LINK p;
while(store_queue)
{
p=store_queue;
free(p->node);
store_queue=store_queue->next;
free(p);
}
while (sort_queue)
{
p=sort_queue;
free(p->node);
sort_queue=sort_queue->next;
free(p);
}
}

// 估价函数,估价 x,y 到目的地的距离,估计值必须保证比实际值小
int judge(int x,int y)
{
int distance;
distance=abs(end_x-x)+abs(end_y-y);
return distance;
}

// 尝试下一步移动到 x,y 可行否
int trytile(int x,int y,TREE father)
{
TREE p=father;
int h;
if (map[y][x]!='0') return 1; // 如果 (x,y) 处是障碍,失败

h=father->h+1;
if (h>=dis_map[tile_num(x,y)]) return 1; // 如果曾经有更好的方案移动到 (x,y) 失败
dis_map[tile_num(x,y)]=h; // 记录这次到 (x,y) 的距离为历史最佳距离

// 将这步方案记入待处理队列
p=(TREE)malloc(sizeof(*p));
p->father=father;
p->h=father->h+1;
p->tile=tile_num(x,y);
enter_queue(p,p->h+judge(x,y));
return 0;
}

// 路径寻找主函数
void findpath(int * path)
{
TREE root;
int i;
if(map[end_y][end_x]==' ')
{
path[0]=tile_num(start_x,start_y);
path[1]=-1;
goto a;
}
memset(dis_map,0xff,map_h*map_w*sizeof(*dis_map)); //填充dis_map为0XFF,表示各点未曾经过
init_queue();
root=(TREE)malloc(sizeof(*root));
assert(root);
root->tile=tile_num(start_x,start_y);
root->h=0;
root->father=NULL;
enter_queue(root,judge(start_x,start_y));
for (;;)
{
int x,y,child;
root=get_from_queue();
if (!root)
{
goto a;
}
x=tile_x(root->tile);
y=tile_y(root->tile);
if (x==end_x && y==end_y) break; // 达到目的地成功返回

child=trytile(x,y-1,root); //尝试向上移动
child&=trytile(x,y+1,root); //尝试向下移动
child&=trytile(x-1,y,root); //尝试向左移动
child&=trytile(x+1,y,root); //尝试向右移动
child&=trytile(x+1,y-1,root);//尝试向右上移动
child&=trytile(x+1,y+1,root); //尝试向右下移动
child&=trytile(x-1,y+1,root); //尝试向左下移动
child&=trytile(x-1,y-1,root); //尝试向左上移动

if (child!=0)
pop_stack(); // 如果四个方向均不能移动,释放这个死节点
}

// 回溯树,将求出的最佳路径保存在 path[] 中

for (i=0;root;i++)
{
path[i]=root->tile;
root=root->father;
}
path[i]=-1;
freetree();
a: ;
}
zhang_jiang 2002-12-25
  • 打赏
  • 举报
回复
// .h file:
#ifndef ASTAR
#define ASTAR
#define tile_num(x,y) ((y)*map_w+(x)) //将 x,y 坐标转换为地图上块的编号
#define tile_x(n) ((n)%map_w) //由块编号得出 x,y 坐标
#define tile_y(n) ((n)/map_w)

#define MAPMAXSIZE 180 //地图面积最大为 180x180,如果没有64K内存限制可以更大
#define MAXINT 32767

//树结构, 比较特殊, 是从叶节点向根节点反向链接,方便从叶节点找到根节点
typedef struct tree_node *TREE;

struct tree_node {
int h; //节点所在的高度,表示从起始点到该节点所有的步数
int tile; //该节点的位置
TREE father; //该节点的上一步
};

//链接结构,用于保存处理过的和没有处理过的结点
typedef struct link_node *LINK;

struct link_node {
TREE node;
int f;
LINK next;
};
//int map_w=64,map_h=48; //地图宽和高

void init_dots(int sx,int sy,int ex,int ey);
void init_queue();
void enter_queue(TREE node,int f);
TREE get_from_queue();
void pop_stack();
void freetree();
int judge(int x,int y);
int trytile(int x,int y,TREE father);
void findpath(int * path);
#endif
yechao 2002-12-22
  • 打赏
  • 举报
回复
<<人工智能>>有 中文版吗?
DarthVader 2002-12-22
  • 打赏
  • 举报
回复
知道最短路径算法吗?
只要从起始节点到目的节点路程之和最小就可以。
节点间的路程就是衡量优劣的指标。
所谓A*算法,不过是把指标复杂化了一点,就我所知,好像是用两个指标的。
详细情况你可以上网查一下。
举个例子,《帝国时代》的寻路算法就是用的A*算法。
sameboat 2002-12-22
  • 打赏
  • 举报
回复
你还是找一本《人工智能》书自己学一下吧。
看看算法以及和f函数构造有关的一个引理就可以了。

8,325

社区成员

发帖
与我相关
我的任务
社区描述
游戏开发相关内容讨论专区
社区管理员
  • 游戏开发
  • 呆呆敲代码的小Y
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧