【 声明:版权全部,欢迎转载,请勿用于商业用途。  联系信箱:feixiaoxing @163.com】

在前面的博客其中,事实上我们已经讨论过寻路的算法。只是,当时的演示样例图中,可选的路径是唯一的。我们挑选一个算法,就是说要把这个唯一的路径选出来,怎么选呢?当时我们就是採用穷尽递归的算法。然而,今天的情形有点不太一样了。在什么地方呢?那就是今天的路径有n条,这条路径都能够达到目的地,然而我们在挑选的过程中有一个要求,那就是挑选的路径距离最短?有没有什么办法呢?

那么,这时候就要A*算法就能够排上用场了。A*算法和普通的算法有什么差别呢?我们能够用一个演示样例说明一下:

/*
* 0 0 0 0 0
* 1 1 1 1 1
* 1 0 0 0 1
* 1 0 0 0 1
* A 1 1 1 1
*/

这是一个5*5的数组。如果我们从array[1][0]出发,目标为A点。我们发现,在图中有两种方法能够到达目的地,可是往下直达的方法最短。那么怎么找到这个最短的算法呢?朋友们能够好好思考一下。

我们能够把时光回到到达的前几个步骤?我们为什么要选方向朝下的点,而不选水平方向的点?原因不复杂,就是由于全部点中,当时我们要选的这个点和目标点之间距离最短。那么这中间,路径的选择有没有发生改变呢?事实上是有可能的,由于选路的过程本省就是一个pk的过程,我们所能做的就是寻找当时那个离目标近期的点而已,而这个点是时刻变化的,所以最后选出来的路应该是这种。

/*
* 0 0 0 0 0
* 1 0 0 0 0
* 1 0 0 0 0
* 1 0 0 0 0
* A 0 0 0 0
*/

算法编程算法,应该怎么改动呢?当然首先定义一个数据结构?

typedef struct _VALUE
{
int x;
int y;
}VALUE;

然后呢,寻找到和目标点距离最短的那个点,

int find_most_nearest_neigh(VALUE data[], int length, int x, int y)
{
int index;
int number;
int current;
int median; if(NULL == data || 0 == length)
return -1; current = 0;
number = (int) sqrt((data[0].x - x) * (data[0].x - x)+ (data[0].y - y) * (data[0].y - y)); for(index = 1; index < length; index ++){
median = (int) sqrt((data[index].x - x) * (data[index].x - x)+ (data[index].y - y) * (data[index].y - y)); if(median < number){
number = median;
current = index;
}
} return current;
}

寻找到这个点,一切都好办了,那么如今我们就须要又一次对data进行处理,毕竟有些点须要弹出,另一些新的点须要压入处理的。

VALUE* updata_data_for_queue(VALUE* data, int length, int* newLen)
{
int index;
int count;
int max;
VALUE* pData; if(NULL == data || 0 == length || NULL == newLen)
return NULL; max = length << 2;
pData = (VALUE*)malloc(max * sizeof(VALUE));
memset(pData, 0, max * sizeof(VALUE)); count = 0;
for(index = 0; index < length; index ++){
if(check_pos_valid(data[index].x, data[index].y - 1)){
pData[count].x = data[index].x;
pData[count].y = data[index].y -1;
count ++;
} if(check_pos_valid(data[index].x -1, data[index].y)){
pData[count].x = data[index].x -1;
pData[count].y = data[index].y;
count ++;
} if(check_pos_valid(data[index].x, data[index].y + 1)){
pData[count].x = data[index].x;
pData[count].y = data[index].y +1;
count ++;
} if(check_pos_valid(data[index].x + 1, data[index].y)){
pData[count].x = data[index].x + 1;
pData[count].y = data[index].y;
count ++;
}
} *newLen = count;
return pData;
}

有了上面的函数之后,那么find_path就十分简单了。

void find_path(int x, int y)
{
while(/* 最短距离不为0 */){ /* 更新列表 */ /* 寻找近期点 */ };
}

总结:

(1)A*的重点在于设计权重推断函数,选择最佳下一跳

(2)A*的目标是已知的

(3)A*尤其适合于网格型的路径查找

一步一步写算法(之 A*算法)的更多相关文章

  1. 一步一步写算法(之prim算法 下)

    原文:一步一步写算法(之prim算法 下) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 前两篇博客我们讨论了prim最小生成树的算法,熟悉 ...

  2. 一步一步写算法(之prim算法 中)

    原文:一步一步写算法(之prim算法 中) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] C)编写最小生成树,涉及创建.挑选和添加过程 MI ...

  3. 一步一步写算法(之prim算法 上)

    原文:一步一步写算法(之prim算法 上) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 前面我们讨论了图的创建.添加.删除和保存等问题.今 ...

  4. 一步一步写算法(之挑选最大的n个数)

    原文:一步一步写算法(之挑选最大的n个数) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 从一堆数据中挑选n个最大的数,这个问题是网上流传的 ...

  5. 一步一步写算法(之n!中末尾零的个数统计)

    原文:一步一步写算法(之n!中末尾零的个数统计) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 在很多面试的题目中,求n!结果中零的个数也是 ...

  6. 一步一步写平衡二叉树(AVL树)

    平衡二叉树(Balanced Binary Tree)是二叉查找树的一个进化体,也是第一个引入平衡概念的二叉树.1962年,G.M. Adelson-Velsky 和 E.M. Landis发明了这棵 ...

  7. .NET跨平台:在Mac上跟着错误信息一步一步手写ASP.NET 5程序

    今天坐高铁时尝试了一种学习ASP.NET 5的笨方法,从空文件夹开始,根据运行dnx . kestrel命令的错误信息,一步一步写代码,直至将一个最简单的ASP.NET程序运行起来. 尝试的具体步骤如 ...

  8. 一步一步理解Paxos算法

    一步一步理解Paxos算法 背景 Paxos 算法是Lamport于1990年提出的一种基于消息传递的一致性算法.由于算法难以理解起初并没有引起人们的重视,使Lamport在八年后重新发表到 TOCS ...

  9. 《一步一步写嵌入式操作系统》读书笔记1—Skyeye介绍、安装和HelloWorld

    2013-11-14 最近在看<一步一步写嵌入式操作系统>,感觉此书甚好,许多地方讲得很清楚.可操作性强,计划边读边实践边写笔记,希望能够逐步熟悉嵌入式操作系统底层的东西,最终剪裁出一套实 ...

随机推荐

  1. js简版定时器

    <html> <head> <meta http-equiv="Content-Type" content="text/html; char ...

  2. php5下载,apache2.4与php5整合

    step1 php5下载 百度“php下载”,找到php官网 2. 点进去,选择windows downloads 3. 同样,X86对应32位,X64对应64位,Non Thread Safe是非线 ...

  3. laravel学习:修改时区

    config/app.php 'timezone' => 'UTC', 改为 'timezone' => 'PRC',

  4. WPF布局容器综合展示

    Border控件,以及几个重要要的属性:Background:背景的 Brush 对象BorderBrush:用来绘制边框BorderThickness: Border 边框的宽度,设置边框每一边的线 ...

  5. App接口设计原则-b

    1.记住密码不是真的让你记住密码,这里仅仅指的是一种自动登录的手段.不管在任何地方,明文存储的密码都是安全隐患,是必须尽量避免的.你可以采用某种方式对用户名.密码以及时间戳(重要)进行签名,再次登录时 ...

  6. property测试代码:

    // // main.m // TestVar2 // // Created by lishujun on 14-9-4. // Copyright (c) 2014年 lishujun. All r ...

  7. [小知识]不显示没有内容的UITableViewCell

    开发过程中常常使用到UITableView,当tableView的内容不足一屏时,若设置了talbeView的高度为屏幕高度,就会出现没有内容的cell显示出来,效果非常不好看,要想让没有内容的cel ...

  8. Hadoop 学习笔记 (十一) MapReduce 求平均成绩

    china:张三 78李四 89王五 96赵六 67english张三 80李四 82王五    84赵六 86math张三 88李四 99王五 66赵六 77 import java.io.IOEx ...

  9. Arrays.fill方法的陷阱

            昨晚调试程序时发现的,该方法不能初始化二维数组,不过当时没有报CE,提交的时候也是WA:今早上单独测试该方法,也没有CE,不过运行时异常.切记

  10. mysql 2006

    1.在my.ini文件中添加或者修改以下两个变量:wait_timeout=2880000interactive_timeout = 2880000 关于两个变量的具体说明可以google或者看官方手 ...