社区
游戏开发
帖子详情
Show Time: 请高手具体介绍一下A*算法的思想
boyfling
2002-12-22 08:23:24
Show Time: 请高手具体介绍一下A*算法的思想
...全文
70
19
打赏
收藏
Show Time: 请高手具体介绍一下A*算法的思想
Show Time: 请高手具体介绍一下A*算法的思想
复制链接
扫一扫
分享
转发到动态
举报
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函数构造有关的一个引理就可以了。
a*
算法
代码 python,python isalpha方法
黄宁然,看过你看过的
算法
,数学不好是硬伤。SIFT全称为Scale Invariant Feature Transform,译为尺度不变特征变换。主要是用来求取图像的特征。其具有尺度不变性、旋转不变性、亮度不变性[1]。一般,找图像的特征,即是找图像中的特征点,SIFT
算法
也是如此,其主要任务就是找到图像中的特征点。而特征点,一般就是找图像在某些方面的极值点,例如像素值上的极值点。找极值点,一般会比较差值,例如通过差值,找图像边缘。
游戏中的
算法
与数学
凸多边形指如果把一个多边形的所有边中,任意一条边向两方无限延长成为一直线时,其他各边都在此直线的同旁,那么这个多边形就叫做凸多边形;相反其他各边不都在此直线的同旁,那么这个多边形就叫做凹多边形,其内角中至少有一个优角(大于180°而小于360°角)。多边形的一个内角是由两条相邻边形成的多边形边界之内的角。如果一个多边形的所有内角均小于180°,则该多边形为凸 (convex) 多边形。... 不是凸多边形的多边形称为凹 (concave) 多边形。如何判别凹多边形 - 知乎如何判别凹多边形 - 知乎。
【白话机器学习】
算法
理论+实战之PageRank
算法
1. 写在前面如果想从事数据挖掘或者机器学习的工作,掌握常用的机器学习
算法
是非常有必要的,常见的机器学习
算法
:监督学习
算法
:逻辑回归,线性回归,决策树,朴素贝叶斯,K近邻,支持向量机,集...
算法
之八皇后问题详解暨终极极限挑战
八皇后问题是一个以国际象棋为背景的问题:如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。八皇后问题可以推广为更一般的n皇后摆放问题:这时棋盘的大小变为n1×n1,而皇后个数也变成n2。而且仅当 n2 = 1 或 n1 ≥ 4 时问题有解。 八皇后问题最早是由国际西洋棋棋手马克斯...
深入浅出EM
算法
概率论基础你没见过的概率 1约定 2链式法则 3贝叶斯定理 4独立性 5条件独立 6随机变量独立性性质 61对称 62分解 63弱联合 64收缩 65相交 琴声不等式 坐标上升方坐标下降法 EM
算法
导出 1 从最大似然估计MLE说起 2 我们遇到了什么问题 3 EM
算法
的导出 4 最后一点小尾巴 5 EM
算法
收敛性证明 EM
算法
与高斯混合模型学习 网友问题解答 推荐资料
游戏开发
8,325
社区成员
23,684
社区内容
发帖
与我相关
我的任务
游戏开发
游戏开发相关内容讨论专区
复制链接
扫一扫
分享
社区描述
游戏开发相关内容讨论专区
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章