精华内容
下载资源
问答
  • A 星寻路算法

    2013-01-23 06:30:51
    A*寻路算法,只是保证在低消耗的情况在最短的时间找出路径,但A*寻路算法寻出来的路不一定是最近,但也绝对不会远的离谱,可也不排除你对路径评分算法的优化可以做到最快最短最低消耗,或者对最终路径优化来达到...
  • A星寻路算法

    2021-04-16 10:19:23
    A*寻路其实就是对广度寻路优化(广度寻路太傻所有可能的路都走),最大不同就是增加了对角线的四个方向并且增加了相应的权重去判断选取最小的权重所对应的路径去走,那么最终总的权重就是最小,此时就是最短路径。...

    1、寻路规则
    A*寻路其实就是对广度寻路的优化(广度寻路太傻所有可能的路都走),最大不同就是增加了对角线的四个方向并且增加了相应的权重去判断选取最小的权重所对应的路径去走,那么最终总的权重就是最小,此时就是最短路径。
    需要说明的是,权重的计算:
    F=G+H,其中F为某点到终点的权重,G为起始点到当前点的权重,H为当前点到终点的预估权重。
    H的计算公式为:((终点位置行-起点位置行)+(终点位置列-起点位置列))*预估权值(注:H不考虑障碍物啥的,只考虑直线距离)
    G就是每走一个方向,如上下左右就加10,如对角线的话就是加14(注:程序中是这样定义并且实现的)。
    2、程序实现
    在程序实现中基本与广度寻路大差不差,就是增加了寻找最小F与四个对角线方向而已还有就是计算H的权重的函数。
    3、具体程序如下:

    // A星寻路算法.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include<vector>
    #include<iostream>
    using namespace std;
    
    #define ROW 11
    #define COL 11
    
    #define ZXDJ 10 //直线代价
    #define XXDJ 14 //斜线代价
    #define YGDJ 10 //预估代价
    
    enum emNodeDir
    {
    	em_Up,
    	em_Down,
    	em_Left,
    	em_Right,
    	em_LUP,//左上
    	em_LDown,//左下
    	em_RUP,//右上
    	em_RDown,//右下
    };
    
    int gMap[ROW][COL] = {         //9
    		{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
    		{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
    		{ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
    		{ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
    		{ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
    		{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
    		{ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
    		{ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
    		{ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 }, //8
    		{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
    		{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
    };
    
    
    struct MapNode
    {
    	int value;//值
    	bool isWalk;//是否走过
    };
    
    struct MapPoint
    {
    	int row;
    	int col; 
    	int f, g, h;//f是衡量某个点到终点的代价
    	//g是起始点到当前点以及付出的代价 h 为已经付出的代价,不考虑障碍物只考虑直线距离
    };
    
    struct treeNode
    {
    	MapPoint pos;//当前点的位置
    	treeNode* parent;//父节点
    	vector<treeNode*>Child;//子节点
    };
    
    MapNode gMapNode[ROW][COL];
    
    void InitMapNode();//初始化地图点
    treeNode* CreatNode(MapPoint point);//增加新的节点
    bool isCanWalk(MapPoint point);//判断是否可以走
    int GetHValue(MapPoint startPos, MapPoint endPos);//计算H值
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	MapPoint startPos = { 4, 1 }, endPos = { 8, 9 };
    	gMapNode[startPos.row][startPos.col].isWalk = true;
    
    	InitMapNode();
    	treeNode* pRoot = CreatNode(startPos);
    	treeNode* currentPos = pRoot;
    
    	vector<treeNode*>nextNodeVec;
    	vector<treeNode*>::iterator minNodeiter;//最小节点迭代器
    
    	bool isWalkEnd = false;
    
    	while (!isWalkEnd)
    	{
    		for (int i = 0; i < 8; i++)
    		{
    			treeNode* pNew = new treeNode;
    			memset(pNew, 0x00, sizeof(treeNode));
    			pNew->pos = currentPos->pos;
    
    			switch (i)
    			{
    			case em_Up:
    				pNew->pos.row--;
    				pNew->pos.g += ZXDJ;
    				break;//跳出switch选择结构
    			case em_Down:
    				pNew->pos.row++;
    				pNew->pos.g += ZXDJ;
    				break;
    			case em_Left:
    				pNew->pos.col--;
    				pNew->pos.g += ZXDJ;
    				break;
    			case em_Right:
    				pNew->pos.col++;
    				pNew->pos.g += ZXDJ;
    				break;
    			case em_LDown://左下
    				pNew->pos.g += XXDJ;
    				pNew->pos.row++;
    				pNew->pos.col--;
    				break;
    			case em_RDown://右下
    				 pNew->pos.row++;
    				 pNew->pos.col++;
    				pNew->pos.g += XXDJ;
    				break;
    			case em_LUP://左上
    				pNew->pos.g += XXDJ;
    				pNew->pos.row--;
    				pNew->pos.col--; 
    				break;
    			case em_RUP://右上
    				pNew->pos.g += XXDJ;
    				pNew->pos.row--;
    				pNew->pos.col++; 
    				break;
    			}
    			if (isCanWalk(pNew->pos))
    			{
    				pNew->pos.h = GetHValue(pNew->pos, endPos);//H值
    				pNew->pos.f = pNew->pos.g + pNew->pos.h;//F值
    
    				currentPos->Child.push_back(pNew);//将该点入树
    
    				pNew->parent = currentPos;//上一个节点作为当前节点的父亲
    
    				nextNodeVec.push_back(pNew);//将新节点放入数组,需要找到最小的f值
    			}
    			else
    			{
    				delete pNew;
    			}
    		}
    		//找数组中f值最小的
    		vector<treeNode*>::iterator it = nextNodeVec.begin();
    		minNodeiter = it;
    		for ( ; it!= nextNodeVec.end();it++)//遍历这一层或者说当前节点可能要走的所有点
    		{
    			if ((*minNodeiter)->pos.f > (*it)->pos.f)//找出最小的f值
    			{
    				minNodeiter = it;
    			}
    		}
    		currentPos = *minNodeiter;//最小的点作为当前点
    		
    		gMapNode[currentPos->pos.row][currentPos->pos.col].isWalk = true;//标记已经走过
    
    		nextNodeVec.erase(minNodeiter);//这个点已经走过,从数组中移除
    		if (currentPos->pos.col == endPos.col&&currentPos->pos.row == endPos.row)
    		{
    			isWalkEnd = true;
    			break;
    		}
    
    		if (nextNodeVec.size()==0)
    		{
    			break;
    		}
    	}
    	if (isWalkEnd==true)
    	{
    		printf("找到了终点了");
    		cout << endl;
    		printf("Path:");
    		while (currentPos)
    		{
    			printf("(%d,%d)", currentPos->pos.row, currentPos->pos.col);
    			currentPos = currentPos->parent;
    		}
    
    		printf("\n");
    	}
    	else
    	{
    		printf("找不到出口");
    	}
    
    	return 0;
    }
    
    void InitMapNode()
    {
    	for (int i = 0; i < ROW; i++)
    	{
    		for (int j = 0; j < COL; j++)
    		{
    			gMapNode[i][j].value = gMap[i][j];
    		}
    	}
    }
    
    treeNode* CreatNode(MapPoint point)
    {
    	treeNode* pNode = new treeNode;
    	pNode->pos = point;
    	pNode->parent = 0;
    	return pNode;
    }
    
    bool isCanWalk(MapPoint point)
    {
    	if (point.row>=ROW || point.row<0 || point.col>=COL||point.col<0)
    	{
    		return false;
    	}
    
    	if (gMapNode[point.row][point.col].value==1||gMapNode[point.row][point.col].isWalk==true)
    	{
    		return false;
    	}
    
    	return true;
    }
    
    int GetHValue(MapPoint startPos, MapPoint endPos)
    {
    	int x = abs(endPos.col - startPos.col);
    	int y = abs(endPos.row - startPos.row);
    
    	return (x + y)*YGDJ;
    }
    

    4、结果展示
    在这里插入图片描述在这里插入图片描述

    展开全文
  • 简介 基于【漫画算法-小灰的...没有做太多的性能优化,算是深化对A星寻路算法的理解。 界面预览: 初始化: 寻路: 后退: 提示: 完成: 刷新地图: 下载地址: 项目地址: https://github.com/milovetingting/Maze ...

    个人博客:
    http://www.milovetingting.cn

    简介

    基于【漫画算法-小灰的算法之旅】上的A星寻路算法,开发的一个Demo。目前实现后退、重新载入、路径提示、地图刷新等功能。没有做太多的性能优化,算是深化对A星寻路算法的理解。

    界面预览:

    初始化:

    初始化

    寻路:

    寻路

    后退:

    后退

    提示:

    提示

    完成:

    完成

    刷新地图:

    刷新地图

    下载地址:

    下载地址

    项目地址:

    https://github.com/milovetingting/Maze

    展开全文
  • A星寻路算法JAVA源码及JAR演示DEMO 1 源码未经优化,非最段路径 2 DEMO为JAR文件,安装JRE可双击运行
  • A星寻路算法(A*)

    2010-11-21 13:56:44
    寻路,经典A星算法(A*): 1。采用静态内存方案,寻路过程不会出现动态内存分配,杜绝内存泄漏的可能 2。CloseList采用直接寻址方式实现 3。OpenList采用优化过的遍历查找插入算法,实现简单高效。如果哪位有二叉堆...
  • A*算法是比较流行的启发式搜索算法之一,被广泛应用于路径优化领域[。它的独特之处是检查最短路径中每个可能的节点时引入了全局信息,对当前节点距终点的距离做出估计,并作为评价该节点处于最短路线上的可能性的...

    A*算法是比较流行的启发式搜索算法之一,被广泛应用于路径优化领域[。它的独特之处是检查最短路径中每个可能的节点时引入了全局信息,对当前节点距终点的距离做出估计,并作为评价该节点处于最短路线上的可能性的量度。

    算法思想参考了https://www.cnblogs.com/zhoug2020/p/3468167.htm
    想了解主要算法思想可以参考上述博客,很好理解。
    具体实现代码如下

    // AStarArithmetic.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
    //
    
    #include "pch.h"
    #include <iostream>
    #include <Vector>
    using namespace std;
    struct Pos
    {
    	int x;
    	int y;
    	int F;
    };
    
    //分别存放下一步可以走的位置信息和已经走过的位置信息
    vector<Pos> open;
    vector<Pos> close;
    
    //显示地图信息和运动轨迹
    void ShowImage(int *arr, int row, int col)
    {
    	for (int i = 0; i < row; i++)
    	{
    		for (int j = 0; j < col; j++)
    		{
    			if (*(arr + i * col + j) == 0)
    			{
    				cout << "0 ";
    			}
    			else if (*(arr + i * col + j) == 1)
    			{
    				cout << "* ";
    			}
    			else if (*(arr + i * col + j) == 5)
    			{
    				cout << "- ";
    			}
    			else
    			{
    				cout << "+ ";
    			}
    		}
    		cout << endl;
    	}
    }
    
    
    //获得x2,y2的F 也就是从原点经过x2,y2到终点所走的路程(忽略障碍物)
    int GetF(int x1,int y1,int x2,int y2,int x3,int y3) 
    {
    	int G = abs(x2 - x1)+ abs(y2-y1);
    	int H = abs(x3 - x2) + abs(y3 - y2);
    	return G + H;
    
    
    }
    //寻找最短路径
    void ChoseShortPath(int *arr, int row, int col, int px, int py,int nowx,int nowy, int dx, int dy)
    {
    	
    	if (nowx == dx && nowy == dy) 
    	{
    		return;
    	}
    	if (nowx-1>=0) 
    	{
    		if (*(arr + col * (nowx - 1) + nowy)==0)
    		{
    			Pos p;
    			p.x = nowx - 1;
    			p.y = nowy;
    			p.F = GetF(px, py, p.x, p.y, dx, dy);
    			//添加过的设置为2
    			*(arr + p.x * col + p.y) = 2;
    			open.push_back(p);
    		}
    	}
    	if (nowx + 1 < row)
    	{
    		if(*(arr + col * (nowx + 1) + nowy) == 0)
    		{
    			Pos p;
    			p.x = nowx + 1;
    			p.y = nowy;
    			p.F = GetF(px, py, p.x, p.y, dx, dy);
    			*(arr + p.x * col + p.y) = 2;
    			open.push_back(p);
    		}
    	}
    	if (nowy - 1 >= 0)
    	{
    		if (*(arr + col * nowx + nowy -1) == 0)
    		{
    			Pos p;
    			p.x = nowx;
    			p.y = nowy -1;
    			p.F = GetF(px, py, p.x, p.y, dx, dy);
    			*(arr + p.x * col + p.y) = 2;
    			open.push_back(p);
    		}
    	}
    	if (nowy + 1 < col)
    	{
    		if (*(arr + col * nowx + nowy + 1) == 0)
    		{
    			Pos p;
    			p.x = nowx;
    			p.y = nowy + 1;
    			p.F = GetF(px, py, p.x, p.y, dx, dy);
    			*(arr + p.x * col + p.y) = 2;
    			open.push_back(p);
    		}
    	}
    	int minIndex = 0;
    	for (int index = 1; index < open.size(); index++) 
    	{
    		if (open[index].F <= open[minIndex].F)
    		{
    			minIndex = index;
    		}
    	}
    	nowx = open[minIndex].x;
    	nowy = open[minIndex].y;
    	cout << nowx<<","<<nowy<<endl;
    	//选择过的设置为3
    	*(arr + nowx * col + nowy) = 3;
    	//获取该位置元素的迭代器
    	vector<Pos>::iterator it = open.begin() + minIndex;
    	close.push_back(open[minIndex]);
    	//删除该元素
    	open.erase(it);
    	ChoseShortPath(arr, row, col, px, py, nowx, nowy, dx, dy);
    
    }
    //显示最短路径到二维数组
    void ShowShorPathToArr(int *arr, int row, int col, int px, int py)
    {
    	int EndIndex = close.size() - 1;
    	*(arr + col * close[EndIndex].x + close[EndIndex].y) = 5;
    	int i = 0;
    	//应该从前往后找相邻的位置避免绕路
    	int StartIndex = 0;
    	while (close[EndIndex].x != px || close[EndIndex].y != py)
    	{
    		if (abs(close[StartIndex + i].x - close[EndIndex].x)+abs(close[StartIndex + i].y - close[EndIndex].y)==1)
    		{
    			EndIndex = StartIndex + i;
    			StartIndex = 0;
    			i = 0;
    			//将最短路径上的点赋值为5
    			*(arr + col * close[EndIndex].x + close[EndIndex].y) = 5;
    		}
    		else
    		{
    			i++;
    		}
    	}
    }
    //场景抽象化成的数组  1代表地形限制
    int a[6][7] = { {0,0,0,0,0,0,0},
    				{0,0,0,1,0,0,0},
    				{0,0,0,1,0,0,0},
    				{0,0,0,1,0,0,0},
    				{0,1,0,1,0,0,0},
    				{0,0,0,0,0,0,0}
    				};
    int main()
    {
    	ShowImage( *a,6,7);
    	a[3][1] = 2;
    	Pos startP;
    	startP.x = 3;
    	startP.y = 1;
    	close.push_back(startP);
    	ChoseShortPath(*a, 6, 7, 3, 1, 3, 1, 4, 5);
    	ShowShorPathToArr(*a, 6, 7, 3, 1);
    	ShowImage(*a, 6, 7);
    }
    
    
    
    
    展开全文
  • 利用跳点搜索算法优化A*寻路

    千次阅读 2018-03-10 19:41:39
    在游戏中寻路是无处不在的。最著名的寻找最短路径算法莫过与A*算法,实现方式有很多种...如果你对A星寻路还不是很了解的话,请网上自行另找资料好的,下面进入正题,开始讲解Jump Point Search!(以下简称JPS)下面...

    在游戏中寻路是无处不在的。最著名的寻找最短路径算法莫过与A*算法,实现方式有很多种,重要的是我们要掌握其原理。

    在本教程中,我们将介绍一种相对较新的方法搜索——基于网格的世界的跳点的搜索,可以加速A*寻路算法。效率提升那是大大的。

    我假设读者已经明白A*算法的原理。如果你对A星寻路还不是很了解的话,请网上自行另找资料

    好的,下面进入正题,开始讲解Jump Point Search!(以下简称JPS)

    下面开始讲解原理

    常规A*算法,是向相邻的格子中搜索可能的“最近节点”,然后把所有的“最近节点”连接起来,既为最终解。至于说怎样的节点才是“最近节点”,本篇不做介绍,因为我前面已经设定了读者是已经明白A*算法的原理的了。

    问题的关键,就在于,我们一定要逐格逐格的去搜索吗?随着格子密集度提升,时间复杂度也将大幅提升。

    那么我们如何去优化呢?

    很简单,对于大片的可行走区域,他们之间的任何一点都是可联通的,我们可以省去这部分格子的“最近节点”搜索,这将是很大一部分的搜索的运算了。我们只需要找出一些相关的控制点,然后通过控制点之间的连通,省去大部分无谓的“寻找最近节点”的运算。

    具体思路如下:

    1 生成/摆放好 凸多边形障碍物

    2 “扩展”多边形 扩展的大小取决于 寻路者的大小

    3 将地图中所有联通点(以扩展后的多边形为主)构成一张”图”

    4 将寻路者的起点和目标点作为”临时节点”加入到3)中生成的图里

    5 在图中寻路. 寻路后将之前的起点移除.

    下面我们举个例子:

    1、有如下一张地图,途中黑色填充为不可行走区
    jsp2
    2、 “扩展”多边形 扩展的大小取决于 寻路者的大小,如图中细线部

    jsp2

    3、将地图中所有联通点(以扩展后的多边形为主)构成一张”图”
    jsp2

    4 、将寻路者的起点和目标点作为”临时节点”加入到3)中生成的图里
    jsp2

    5、基于图中的“控制点” ,在图中寻路.

    5.1、寻路第一步,将起始点作为搜索点,在与其相邻的控制点中,找到可能的“最近节点”,如图所示,最粗的两条线的交点,就是我们要找的“最近节点”,因为其深绿色线段+浅绿色线段的长度之和,是最短的。这也是A*寻路的基本思路。
    jsp2

    5.2、寻路第二步,把上一步寻找到的“最近节点”,作为新的搜索点,然后重复同样的判断,找到新的新的“最近节点”,如图所示,红色的点,就是我们要找的新的“最近节点”
    jsp2

    5.3、寻路第N步,重复同样的算法,寻找新的可能的“最近节点”,直到找到“终点”。如下图,深绿色的路线,就是我们寻路结果。
    jsp2

    总结:

    看到这里,我想大家一定都懂了,也肯定明白了,为什么利用JPS算法能够大大提高A*寻路的效率。因为它省去了一些无谓的判断节点。当然它是需要在寻路之前,开销一些空间和时间去进行地图的预处理。不过这点开销,在后面寻路算法中又大大地赚了回来。

    展开全文
  • AStar寻路算法 (C#)

    2020-01-12 14:47:06
    A星算法其实并不是最短路径算法,它找到的路径并不是最短的,它的目标首先是能以最快的速度找到通往目的地的路 B星实际上是A星优化 但是B星的缺点是不能向后查找 所以会有问题 还有一种D星的可以用来找最短路径不...
  • 1.A星寻路算法 2.弗洛伊德路径平滑算法 3.源码下载 1.A星寻路算法 讲A星算法原理的文章实在是太多了,我这里就不重复造轮子了。本文采用的算法是9ria算法大赛挑选出来的几个速度最快的算法之一。该算法是...
  • VB的A星算法模块,有详细的注释,并且附带演示功能。演示操作说明:鼠标左键设置障碍,鼠标右键设置起点和终点。寻路之后,灰色代表关闭表中的节点、紫色是开启表中的...模块详细使用说明请参照“A星寻路算法.bas”。
  • 该图为基础A星算法寻路后的多边形路径,其中A星算法是以三角形边中点作为距离运算的迭代点的。 该图为漏斗算法优化后的路径点,最终为S,D,G,End。可以明显的看出基础A星在非规整导航网格中的路径结果是不平滑...
  • A搜寻算法俗称A星算法。A算法是比较流行的启发式搜索算法之一,被广泛应用于路径优化领域[。它的独特之处是检查最短路径中每个可能的节点时引入了全局信息,对当前节点距终点的距离做出估计,并作为评价该节点处于...
  • AStar算法优化

    2020-01-12 15:06:12
    A星算法也有很多弊端,就比如如果目的地不能到达 他还是会遍历寻路(可以寻路的时候判断 也可以算的上优化) 其次,如果地图过大,计算起来会很消耗时间,所以可以在计算上进行优化 下面说一下优化的一些可行的方法 一....
  • 来源于文档的主要内容: ...和A星寻路算法有什么异同? 相对而言, ORCA是局部导航,导航目标是在个体自己的周围,让个体自身避开与自己接近的其它个体目标和障碍,ORCA只能感知到靠近自身周围的情况...
  • 文章目录疯狂吐槽错误分析效率正确的Java实现代码 - 已优化数据结构坐标类路径结点类地图类算法定义常量 看懂本文的前提是了解清楚A星算法的原理!!这个可以看其他文章,讲的都还可以 推荐这篇A星算法详解(个人...
  • A*搜索算法俗称A星算法,是一个被广泛应用于路径优化领域的算法,它的行为的能力基于启发式代价函数,在游戏的寻路中非常有用。 将地图表格化  A*算法的第一个步是将地图表格化,具体来说是用一个大型的二维列表...
  • 最近搞一款塔防游戏,提到塔防,自然就想到了A星寻路。的确,它是一种高效的寻路算法。但当很多怪物同时在调用A星算法来寻找一条最近的路径来到达目的地时,我发现会很卡。我都不能接受这个卡屏,更何况是玩家呢。...

空空如也

空空如也

1 2
收藏数 29
精华内容 11
关键字:

a星寻路算法路径优化