A星寻路:
  结构:N叉树
  直线代价斜线代价:符合勾股定理
  代价:每走一步,距离终点所付出的
  计算公式:f = g + h + w;
  f : 当前点到终点的代价
  g : 起点到当前点的代价
  h : 当前点到终点的预估代价(只计算直线距离,并忽略障碍)
  w : 权重 路: 平地 上坡路 丘陵 沼泽 坑

代码演示:

#include <string.h>>
#include <iostream>
#include <vector>
#include <windows.h>
using namespace std; //代价 : 每走一步 距离终点所付出的 // f = g + h + w;
// f : 当前点到终点的代价
// g : 起点到当前点的代价
// h : 当前点到终点的预估代价(只计算直线距离,并忽略障碍)
// w : 权重 路: 平地 上坡路 丘陵 沼泽 坑 //直线代价斜线代价:符合勾股定理
//直线代价
#define ZXDJ 10
//斜线代价
#define XXDJ 14 //地图高 Y 竖着 行数 列
#define ROWS 12
//地图宽 X 横着 列数 行
#define COLS 12 struct MyPoint{
int row;//x
int col;//y
//f = g+h
int h; //当前点到终点预估代价
int f; //当前点的代价
int g; //起点到当前点的代价 void setF(){ f = g + h; }
}; //辅助地图
struct pathNode{
int val;//值
bool isFind;//有没有走过
}; //方向枚举 :上下左右/左上左下右上右下
enum direct{p_up,p_down,p_left,p_right,lup,ldown,rup,rdown}; //树节点类型
struct treeNode{
MyPoint pos;
treeNode* pParent;
vector<treeNode*> child;
};
//创建一个树节点并返回节点首地址
//treeNode* CreateNode(const MyPoint& point);
treeNode* CreateNode(int row,int col); //判断pos点能不能走,能走返回true,否则返回false
bool canWalk(pathNode pathMap[ROWS][COLS], MyPoint pos); //计算h值并返回
int getH(const MyPoint& currentPos, const MyPoint& endPos); int main()
{
int map[ROWS][COLS] = {
{ 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0 },
{ 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0 },
{ 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0 },
{ 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }
}; pathNode pathMap[ROWS][COLS] = { 0 };
for (int i = 0; i < ROWS; i++){
for (int j = 0; j < COLS; j++){
pathMap[i][j].val = map[i][j];
}
}
MyPoint begPos = { 1, 1 };
MyPoint endPos = { 4, 9 };
//准备树结构
treeNode* pRoot = NULL;
//起点成为树根节点
pRoot = CreateNode(begPos.row, begPos.col);
//标记起点走过
pathMap[begPos.row][begPos.col].isFind = true; //临时指针 指向当前节点
treeNode* pTemp = pRoot;
//临时指针 暂时保存当前点的孩子
treeNode* pTempChild = NULL;
//保存当前备选点的数组
vector<treeNode*> buff; //准备两个迭代器 //遍历整个容器
vector<treeNode*>::iterator it;
//定位容器中f值最小的元素
vector<treeNode*>::iterator itMin;
//临时点类型
MyPoint tempPos;
bool isFindEnd = false; //寻路
while (1){ //1 一个点压出八个点
for (int i = 0; i < 8; i++){
tempPos = pTemp->pos;
//1.1 每个点做个临时的出来
switch (i)
{
//上下左右 左上左下右上右下
//同时需要改变g值
case p_up:tempPos.row--;tempPos.g += ZXDJ;break;
case p_down:tempPos.row++;tempPos.g += ZXDJ;break;
case p_left:tempPos.col--;tempPos.g += ZXDJ;break;
case p_right:tempPos.col++;tempPos.g += ZXDJ;break;
case lup:tempPos.row--;tempPos.col--;tempPos.g += XXDJ;break;
case ldown:tempPos.row++;tempPos.col--;tempPos.g += XXDJ;break;
case rup:tempPos.row--;tempPos.col++;tempPos.g += XXDJ;break;
case rdown:tempPos.row++;tempPos.col++;tempPos.g += XXDJ;break;
}
//1.2 这个点可以走
if (canWalk(pathMap, tempPos)){
//1.2.1 创建树节点
pTempChild = CreateNode(tempPos.row, tempPos.col);
//1.2.2 计算节点的g值 h值 f值:f=g+h
pTempChild->pos.g = tempPos.g;
pTempChild->pos.h = getH(pTempChild->pos, endPos);//计算h值:到终点预估代价
pTempChild->pos.setF();//计算f printf("(%d,%d) ",
pTempChild->pos.row, pTempChild->pos.col); //1.2.3 新结点入树
pTemp->child.push_back(pTempChild);
pTempChild->pParent = pTemp;
//1.2.4 新节点保存到数组中
buff.push_back(pTempChild);
} }
printf("\n"); //2 遍历buff数组,找出其中f值最小的一个
itMin = buff.begin();
for (it = buff.begin(); it != buff.end(); it++){
itMin = ((*itMin)->pos.f > (*it)->pos.f) ? it : itMin;
} //3 当前点变成这个点
pTemp = *itMin;
//标记当前点走过
pathMap[pTemp->pos.row][pTemp->pos.col].isFind = true; //4 buff数组中删除这个点
buff.erase(itMin); //5 判断是否找到终点
if (pTemp->pos.row == endPos.row &&
pTemp->pos.col == endPos.col){
isFindEnd = true;
break;
} //6 判断地图是否没有出口
if (0 == buff.size()) break;
} // 打印路径
if (isFindEnd){
printf("找到终点啦!\n");
printf("打印路径:终点-->起点\n");
printf("\n");
printf("\n");
while (pTemp){
printf("(%d,%d) ", pTemp->pos.row, pTemp->pos.col);
pTemp = pTemp->pParent;
}
printf("\n");
}
return 0;
} treeNode* CreateNode(int row, int col){
treeNode* pNew = new treeNode;
memset(pNew, 0, sizeof(treeNode));
pNew->pos.row = row;
pNew->pos.col = col;
return pNew;
} //判断pos点能不能走,能走返回true,否则返回false
bool canWalk(pathNode pathMap[ROWS][COLS], MyPoint pos){
//不在地图范围内
if (pos.row >= ROWS || pos.row < 0 || pos.col >= COLS || pos.col < 0)
return false;
//是障碍
if (pathMap[pos.row][pos.col].val) return false;
//走过
if (pathMap[pos.row][pos.col].isFind) return false;
return true;
} //计算h值并返回
int getH(const MyPoint& currentPos, const MyPoint& endPos){
int x = (currentPos.col > endPos.col) ? (currentPos.col - endPos.col) : (endPos.col - currentPos.col);
int y = (currentPos.row > endPos.row) ? (currentPos.row - endPos.row) : (endPos.row - currentPos.row);
return (x+y)*ZXDJ;
}

《算法九》(A星寻路算法)的更多相关文章

  1. A星寻路算法介绍

    你是否在做一款游戏的时候想创造一些怪兽或者游戏主角,让它们移动到特定的位置,避开墙壁和障碍物呢? 如果是的话,请看这篇教程,我们会展示如何使用A星寻路算法来实现它! 在网上已经有很多篇关于A星寻路算法 ...

  2. A星寻路算法

    A星寻路算法 1.准备一个close关闭列表(存放已被检索的点),一个open开启列表(存放未被检索的点),一个当前点的对象cur 2.将cur设成开始点 3.从cur起,将cur点放入close表中 ...

  3. cocos2d-x学习日志(13) --A星寻路算法demo

    你是否在做一款游戏的时候想创造一些怪兽或者游戏主角,让它们移动到特定的位置,避开墙壁和障碍物呢?如果是的话,请看这篇教程,我们会展示如何使用A星寻路算法来实现它! A星算法简介: A*搜寻算法俗称A星 ...

  4. 无递归 A星寻路算法

    整理硬盘的时候,发现我早些年写的A星寻路算法.特放上来,待有缘人拿去,无递归噢,性能那是杠杠的. 码上伺候 public class Node { public int X { get; set; } ...

  5. A星寻路算法(A* Search Algorithm)

    你是否在做一款游戏的时候想创造一些怪兽或者游戏主角,让它们移动到特定的位置,避开墙壁和障碍物呢? 如果是的话,请看这篇教程,我们会展示如何使用A星寻路算法来实现它! 在网上已经有很多篇关于A星寻路算法 ...

  6. A星寻路算法入门(Unity实现)

    最近简单学习了一下A星寻路算法,来记录一下.还是个萌新,如果写的不好,请谅解.Unity版本:2018.3.2f1 A星寻路算法是什么 游戏开发中往往有这样的需求,让玩家控制的角色自动寻路到目标地点, ...

  7. A星寻路算法-Mind&Hand(C++)

    //注1:Mind & Hand,MIT校训,这里指的理解与实现(动脑也动手) //注2:博文分为两部分:(1)理解部分,为参考其他优秀博文的摘要梳理:(2)代码部分,是C++代码实现的,源码 ...

  8. 【Android】基于A星寻路算法的简单迷宫应用

    简介 基于[漫画算法-小灰的算法之旅]上的A星寻路算法,开发的一个Demo.目前实现后退.重新载入.路径提示.地图刷新等功能.没有做太多的性能优化,算是深化对A星寻路算法的理解. 界面预览: 初始化: ...

  9. [转载]A星寻路算法介绍

    转载自:http://www.raywenderlich.com/zh-hans/21503/a%E6%98%9F%E5%AF%BB%E8%B7%AF%E7%AE%97%E6%B3%95%E4%BB% ...

  10. 基于Unity的A星寻路算法(绝对简单完整版本)

    前言 在上一篇文章,介绍了网格地图的实现方式,基于该文章,我们来实现一个A星寻路的算法,最终实现的效果为: 项目源码已上传Github:AStarNavigate 在阅读本篇文章,如果你对于里面提到的 ...

随机推荐

  1. 【一起学源码-微服务】Nexflix Eureka 源码十三:Eureka源码解读完结撒花篇~!

    前言 想说的话 [一起学源码-微服务-Netflix Eureka]专栏到这里就已经全部结束了. 实话实说,从最开始Eureka Server和Eureka Client初始化的流程还是一脸闷逼,到现 ...

  2. 小白学 Python 爬虫(32):异步请求库 AIOHTTP 基础入门

    人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...

  3. 洛谷P5664 Emiya 家今天的饭 题解 动态规划

    首先来看一道题题: 安娜写宋词 题目背景 洛谷P5664 Emiya 家今天的饭[民间数据] 的简化版本. 题目描述 安娜准备去参加宋词大赛,她一共掌握 \(n\) 个 词牌名 ,并且她的宋词总共有 ...

  4. 用python做推荐系统(一)

    一.简介: 推荐系统是最常见的数据分析应用之一,包含淘宝.豆瓣.今日头条都是利用推荐系统来推荐用户内容.推荐算法的方式分为两种,一种是根据用户推荐,一种是根据商品推荐,根据用户推荐主要是找出和这个用户 ...

  5. Django 单表查询

    前言 如何只单独测试django中的某一个py文件呢?或者说如何书写测试脚本? 我们可以在任意一个py文件(应用下的tests或者自己新建一个)中书写以下代码: 前期准备 创建一个电影表 class ...

  6. 移动web 1像素边框

    实现方法 border-image 图片 实现 这篇文章是腾讯github上的解决方案border-image来实现的 链接走起 <使用border-image实现类似iOS7的1px底边> ...

  7. 理解 SQL 开窗函数

    一次面试被问到开窗函数,懵逼了,赶紧补补总结一下.... 开窗函数也是函数,所以 比如在原来的查询上添加一个总数列 create table ztest( id int identity, c1 in ...

  8. Python爬虫入门教程 33-100 电影评论数据抓取 scrapy

    1. 海王评论数据爬取前分析 海王上映了,然后口碑炸了,对咱来说,多了一个可爬可分析的电影,美哉~ 摘录一个评论 零点场刚看完,温导的电影一直很不错,无论是速7,电锯惊魂还是招魂都很棒.打斗和音效方面 ...

  9. HTML中使用Vue+Dhtmlxgantt制作任务进度图

    HTML中使用Vue+Dhtmlxgantt制作任务进度图 Dhtmlxgantt官网: https://dhtmlx.com/docs/products/dhtmlxGantt/ 参考文章 甘特图配 ...

  10. hdu - 4990

    Read the program below carefully then answer the question.    #pragma comment(linker, "/STACK:1 ...