首页 > 编程语言 >一步一步写算法(之 A*算法)

一步一步写算法(之 A*算法)

时间:2022-11-23 11:03:56浏览次数:42  
标签:count index 一步 int pData VALUE 算法 data



    在前面的博客当中,其实我们已经讨论过​​寻路​​的算法。不过,当时的示例图中,可选的路径是唯一的。我们挑选一个算法,就是说要把这个唯一的路径选出来,怎么选呢?当时我们就是采用穷尽递归的算法。然而,今天的情形有点不太一样了。在什么地方呢?那就是今天的路径有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*尤其适合于网格型的路径查找


标签:count,index,一步,int,pData,VALUE,算法,data
From: https://blog.51cto.com/u_15888909/5880567

相关文章

  • 一步一步写算法(之 可变参数)
       可变参数是C语言编程的一个特色。在我们一般编程中,函数的参数个数都是确定的,事先定下来的。然而就有那么一部分函数,它的个数是不确定的,长度也不一定,这中间有什么秘密......
  • 算法基础 数据结构
    单调队列概念单调队列题目154.滑动窗口题目描述给定一个大小为n≤106的数组。有一个大小为k的滑动窗口,它从数组的最左边移动到最右边。你只能在窗口中看到k......
  • GCD算法
    以下是记录的一些笔记:有些混乱,寒假再来细细整理。   python实现:defgcd(a,b):while(b!=0):r=a%ba,b=b,rreturnaprint(gc......
  • 代码随想录算法训练营第七天 | 454.四数相加II ● 383. 赎金信 ● 15. 三数之和 ●
    今日任务●454.四数相加II●383.赎金信●15.三数之和●18.四数之和●总结详细布置454.四数相加II建议:本题是使用map巧妙解决的问题,好好体......
  • 代码随想录算法训练营Day07|454. 四数相加 II、383. 赎金信、15. 三数之和、18. 四数
    代码随想录算法训练营Day07|454.四数相加II、383.赎金信、15.三数之和、18.四数之和454.四数相加II题目链接:454.四数相加II题干交代四个数组的长度相等,所以我......
  • golang算法—— 使用两个栈实现一个队列
    前言阅读本文,假定已经了解了基本数据结构概念。队列:先入先出。栈:先进后出。分析使用两个栈串联,可以实现先进先出。但是,得注意以下两点:队列在入列时,stack2必须为空,stac......
  • Union-Find算法
    目录Union-Find算法简介思路代码实现应用应用1:Leetcode.130题目分析代码实现Union-Find算法简介UnionFind算法用于处理集合的合并和查询问题,它定义了两个用于并查集的......
  • 最小生成树之普利姆算法与克鲁斯卡尔算法(贪心算法)
    最小生成树(贪心算法)概念一个有n个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有n个结点,并且有保持图连通的最少的边。连通图有多种连接方式,而其中......
  • 【算法】最后一个单词的长度,颠倒二进制位,排列序列等三道题目
    颠倒二进制位题目描述颠倒给定的32位无符号整数的二进制位。提示:请注意,在某些语言(如Java)中,没有无符号整数类型。在这种情况下,输入和输出都将被指定为有符号整数类型,并......
  • 384. 打乱数组(洗牌算法)
    给你一个整数数组 nums ,设计算法来打乱一个没有重复元素的数组。打乱后,数组的所有排列应该是 等可能 的。实现 Solution class:Solution(int[]nums) 使用整数数......