通过A*算法实现多节点的寻径

 1 /*
 2 A star 算法的基础处理
 3 */
 4 #ifndef _A_STAR_BASE_H_
 5 #define _A_STAR_BASE_H_
 6 #include "windows.h"
 7
 8 typedef struct _APoint{
 9     int x; // x 坐标
10     int y; // y 坐标
11     int type; // 类型
12     int f; // f = g + h
13     int g;
14     int h;
15 } APoint, *PAPoint;
16
17 enum APointType{
18     APT_UNKNOWN, // 未知状态
19     APT_OPENED, // 开放列表中
20     APT_CLOSED, // 关闭列表中
21     APT_STARTPOINT, // 起始点
22     APT_ENDPOINT // 结束点
23 };
24
25
26 class CAStarBase{
27 public:
28     CAStarBase();
29     ~CAStarBase();
30 private:
31     PAPoint m_pAPointArr;
32     int m_nAPointArrWidth;
33     int m_nAPointArrHeight;
34
35     PAPoint m_pStartPoint, m_pEndPoint, m_pCurPoint;
36     char* m_pOldArr;
37 public:
38     BOOL Create(char* pDateArr, int nWidth, int nHeight);
39     void SetStartPoint(int x, int y);
40     void SetEndPoint(int x, int y);
41     void SetOpened(int x, int y);
42     void SetClosed(int x, int y);
43     void SetCurrent(int x, int y);
44     void PrintCharArr();
45
46     PAPoint CalcNextPoint(PAPoint ptCalc); // 应用迭代的办法进行查询
47 };
48
49 #endif  
  1 #include "A_Star.h"
  2 #include <cstdio>
  3
  4 CAStarBase::CAStarBase()
  5 {
  6     m_pAPointArr = NULL;
  7     m_nAPointArrWidth = 0;
  8     m_nAPointArrHeight = 0;
  9
 10     m_pStartPoint = NULL;
 11     m_pEndPoint = NULL;
 12     m_pCurPoint = NULL;
 13
 14 }
 15
 16 CAStarBase::~CAStarBase()
 17 {
 18
 19 }
 20
 21 BOOL CAStarBase::Create(char* pDateArr, int nWidth, int nHeight)
 22 {
 23     if (!pDateArr) return FALSE;                      //数组地址是否存在
 24     if (nWidth<1 || nHeight<1) return FALSE;          //判断数组的长宽是否大于一
 25     m_pAPointArr = new APoint[nWidth*nHeight];
 26     if (!m_pAPointArr) return FALSE;
 27     m_pOldArr = pDateArr;                             //父节点9指针形式)
 28     m_nAPointArrWidth = nWidth;                       //数组的宽度
 29     m_nAPointArrHeight = nHeight;                     //数组的高度
 30     // 初始化数组内容
 31     for (int y = 0; y<m_nAPointArrHeight; y++)
 32     {
 33         for (int x = 0; x<m_nAPointArrWidth; x++)
 34         {
 35             m_pAPointArr[y*m_nAPointArrWidth + x].x = x;                   //赋值形式?!
 36             m_pAPointArr[y*m_nAPointArrWidth + x].y = y;
 37             m_pAPointArr[y*m_nAPointArrWidth + x].g = 0;
 38             m_pAPointArr[y*m_nAPointArrWidth + x].f = 0;
 39             m_pAPointArr[y*m_nAPointArrWidth + x].h = 0;
 40
 41             if (pDateArr[y*m_nAPointArrWidth + x] == ‘0‘)
 42             {
 43                 m_pAPointArr[y*m_nAPointArrWidth + x].type = APT_OPENED;
 44             }
 45             else if (pDateArr[y*m_nAPointArrWidth + x] == ‘1‘)
 46             {
 47                 m_pAPointArr[y*m_nAPointArrWidth + x].type = APT_CLOSED;
 48             }
 49             else if (pDateArr[y*m_nAPointArrWidth + x] == ‘S‘)
 50             {
 51                 m_pAPointArr[y*m_nAPointArrWidth + x].type = APT_STARTPOINT;
 52                 m_pStartPoint = m_pAPointArr + y*m_nAPointArrWidth + x;            //赋值形式?!
 53                 m_pCurPoint = m_pStartPoint;
 54             }
 55             else if (pDateArr[y*m_nAPointArrWidth + x] == ‘E‘)
 56             {
 57                 m_pAPointArr[y*m_nAPointArrWidth + x].type = APT_ENDPOINT;
 58                 m_pEndPoint = m_pAPointArr + y*m_nAPointArrWidth + x;
 59             }
 60             else{
 61                 m_pAPointArr[y*m_nAPointArrWidth + x].type = APT_UNKNOWN;
 62             }
 63
 64         }
 65     }
 66     return TRUE;                          //初始化返回为真
 67 }
 68
 69 void CAStarBase::SetStartPoint(int x, int y)
 70 {
 71     if (m_pStartPoint && m_pAPointArr[y*m_nAPointArrWidth + x].type != APT_CLOSED)
 72     {
 73         m_pStartPoint->type = APT_OPENED;
 74         // 设置新的值
 75         m_pStartPoint = m_pAPointArr + y*m_nAPointArrWidth + x;
 76         m_pStartPoint->type = APT_STARTPOINT;
 77         m_pCurPoint = m_pStartPoint;
 78     }
 79 }
 80
 81 void CAStarBase::SetEndPoint(int x, int y)
 82 {
 83     if (m_pStartPoint && m_pAPointArr[y*m_nAPointArrWidth + x].type != APT_CLOSED)
 84     {
 85         m_pStartPoint->type = APT_OPENED;
 86         // 设置新的值
 87         m_pStartPoint = m_pAPointArr + y*m_nAPointArrWidth + x;
 88         m_pStartPoint->type = APT_ENDPOINT;
 89     }
 90 }
 91
 92 void CAStarBase::SetCurrent(int x, int y)
 93 {
 94     //  if ( m_pAPointArr[y*m_nAPointArrWidth+x].type==APT_OPENED )
 95     {
 96         m_pCurPoint = m_pAPointArr + y*m_nAPointArrWidth + x;
 97     }
 98 }
 99
100 void CAStarBase::SetOpened(int x, int y)                //建立“开启列表”
101 {
102     if (m_pAPointArr[y*m_nAPointArrWidth + x].type != APT_OPENED)
103     {
104         m_pAPointArr[y*m_nAPointArrWidth + x].type = APT_OPENED;
105     }
106 }
107
108 void CAStarBase::SetClosed(int x, int y)                 //建立“关闭列表”
109 {
110     if (m_pAPointArr[y*m_nAPointArrWidth + x].type != APT_CLOSED)
111     {
112         m_pAPointArr[y*m_nAPointArrWidth + x].type = APT_CLOSED;
113     }
114 }
115
116 void CAStarBase::PrintCharArr()                     //打印终点
117 {
118     if (m_pOldArr)                                 //是否有父节点
119     {
120         for (int y = 0; y<m_nAPointArrHeight; y++)
121         {
122             for (int x = 0; x<m_nAPointArrWidth; x++)
123             {
124                 printf("%c ", m_pOldArr[x + m_nAPointArrWidth*y]);
125             }
126             printf("\r\n");
127         }
128         printf("\r\n");
129     }
130 }
131
132 PAPoint CAStarBase::CalcNextPoint(PAPoint ptCalc)
133 {
134     if (ptCalc == NULL)
135     {
136         ptCalc = m_pStartPoint;
137     }
138     int x = ptCalc->x;
139     int y = ptCalc->y;
140     int dx = m_pEndPoint->x;
141     int dy = m_pEndPoint->y;
142     int xmin = x, ymin = y, vmin = 0; // 最优步骤的坐标和值
143     // 判断是否已经到了最终的位置
144     if ((x == dx && abs(y - dy) == 1) || (y == dy && abs(x - dx) == 1))     //是否在重点的周围
145     {
146         printf("\r\n\n");
147         PrintCharArr();
148         return m_pEndPoint;
149     }
150     // 上
151     if (m_pAPointArr[(x + 0) + m_nAPointArrWidth*(y - 1)].type == APT_OPENED && y>0)
152     {
153         m_pAPointArr[(x + 0) + m_nAPointArrWidth*(y - 1)].g = 10;
154         m_pAPointArr[(x + 0) + m_nAPointArrWidth*(y - 1)].h =
155             10 * (abs(x - dx) + abs(y - 1 - dy));
156         m_pAPointArr[(x + 0) + m_nAPointArrWidth*(y - 1)].f =
157             m_pAPointArr[(x + 0) + m_nAPointArrWidth*(y - 1)].g + m_pAPointArr[(x + 0) + m_nAPointArrWidth*(y - 1)].h;
158         if (vmin == 0)
159         {
160             xmin = x;
161             ymin = y - 1;
162             vmin = m_pAPointArr[(x + 0) + m_nAPointArrWidth*(y - 1)].f;
163         }
164         else{
165             if (vmin > m_pAPointArr[(x + 0) + m_nAPointArrWidth*(y - 1)].f)
166             {
167                 xmin = x;
168                 ymin = y - 1;
169                 vmin = m_pAPointArr[(x + 0) + m_nAPointArrWidth*(y - 1)].f;
170             }
171         }
172     }
173     // 下
174     if (m_pAPointArr[(x + 0) + m_nAPointArrWidth*(y + 1)].type == APT_OPENED && y<m_nAPointArrHeight)
175     {
176         m_pAPointArr[(x + 0) + m_nAPointArrWidth*(y + 1)].g = 10;
177         m_pAPointArr[(x + 0) + m_nAPointArrWidth*(y + 1)].h =
178             10 * (abs(x - dx) + abs(y + 1 - dy));
179         m_pAPointArr[(x + 0) + m_nAPointArrWidth*(y + 1)].f =
180             m_pAPointArr[(x + 0) + m_nAPointArrWidth*(y + 1)].g + m_pAPointArr[(x + 0) + m_nAPointArrWidth*(y + 1)].h;
181         if (vmin == 0)
182         {
183             xmin = x;
184             ymin = y + 1;
185             vmin = m_pAPointArr[(x + 0) + m_nAPointArrWidth*(y + 1)].f;
186         }
187         else{
188             if (vmin > m_pAPointArr[(x + 0) + m_nAPointArrWidth*(y + 1)].f)
189             {
190                 xmin = x;
191                 ymin = y + 1;
192                 vmin = m_pAPointArr[(x + 0) + m_nAPointArrWidth*(y + 1)].f;
193             }
194         }
195     }
196     // 左
197     if (m_pAPointArr[(x - 1) + m_nAPointArrWidth*y].type == APT_OPENED && x>0)
198     {
199         m_pAPointArr[(x - 1) + m_nAPointArrWidth*y].g = 10;
200         m_pAPointArr[(x - 1) + m_nAPointArrWidth*y].h =
201             10 * (abs(x - 1 - dx) + abs(y - dy));
202         m_pAPointArr[(x - 1) + m_nAPointArrWidth*y].f =
203             m_pAPointArr[(x - 1) + m_nAPointArrWidth*y].g + m_pAPointArr[(x - 1) + m_nAPointArrWidth*y].h;
204         if (vmin == 0)
205         {
206             xmin = x - 1;
207             ymin = y;
208             vmin = m_pAPointArr[(x - 1) + m_nAPointArrWidth*y].f;
209         }
210         else{
211             if (vmin > m_pAPointArr[(x - 1) + m_nAPointArrWidth*y].f)
212             {
213                 xmin = x - 1;
214                 ymin = y;
215                 vmin = m_pAPointArr[(x - 1) + m_nAPointArrWidth*y].f;
216             }
217         }
218     }
219     // 右
220     if (m_pAPointArr[(x + 1) + m_nAPointArrWidth*y].type == APT_OPENED && x<m_nAPointArrWidth)
221     {
222         m_pAPointArr[(x + 1) + m_nAPointArrWidth*y].g = 10;
223         m_pAPointArr[(x + 1) + m_nAPointArrWidth*y].h =
224             10 * (abs(x + 1 - dx) + abs(y - dy));
225         m_pAPointArr[(x + 1) + m_nAPointArrWidth*y].f =
226             m_pAPointArr[(x + 1) + m_nAPointArrWidth*y].g + m_pAPointArr[(x + 1) + m_nAPointArrWidth*y].h;
227         if (vmin == 0)
228         {
229             xmin = x + 1;
230             ymin = y;
231             vmin = m_pAPointArr[(x + 1) + m_nAPointArrWidth*y].f;
232         }
233         else{
234             if (vmin > m_pAPointArr[(x + 1) + m_nAPointArrWidth*y].f)
235             {
236                 xmin = x + 1;
237                 ymin = y;
238                 vmin = m_pAPointArr[(x + 1) + m_nAPointArrWidth*y].f;
239             }
240         }
241     }
242
243
244     if (vmin)
245     {
246         SetCurrent(xmin, ymin);
247         SetClosed(xmin, ymin);
248         printf("(%d,%d)->", xmin, ymin);
249         *(m_pOldArr + xmin + m_nAPointArrWidth*ymin) = ‘-‘;         //走过的路径用‘-’表示
250         //PrintCharArr();                                             //每在关闭列表中加入一个值,就输出一遍
251         PAPoint pApoint = CalcNextPoint(m_pCurPoint);               // 如果有最优点则迭代,则否就返回NULL
252         if (pApoint == NULL)
253         {
254             SetCurrent(x, y);
255             SetClosed(xmin, ymin);
256             *(m_pOldArr + xmin + m_nAPointArrWidth*ymin) = ‘0‘;      //不做改变
257             return CalcNextPoint(m_pCurPoint);
258         }
259         return pApoint;
260     }
261     else{
262         return NULL;
263     }
264
265 }
 1 // AStarMath.cpp : 定义控制台应用程序的入口点。
 2 //
 3
 4 //#include <stdafx.h>
 5 #include "A_Star.h"
 6 #include <stdio.h>
 7
 8 CAStarBase Astarbase;
 9
10 int main()
11 {
12     char pBuff[][12] = {
13         ‘S‘, ‘0‘, ‘0‘, ‘1‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘,
14         ‘0‘, ‘1‘, ‘1‘, ‘0‘, ‘0‘, ‘1‘, ‘1‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘,
15         ‘0‘, ‘0‘, ‘1‘, ‘0‘, ‘1‘, ‘1‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘,
16         ‘0‘, ‘1‘, ‘0‘, ‘0‘, ‘0‘, ‘1‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘,
17         ‘0‘, ‘0‘, ‘0‘, ‘1‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘,
18         ‘0‘, ‘0‘, ‘0‘, ‘1‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘,
19         ‘0‘, ‘0‘, ‘0‘, ‘1‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘,
20         ‘0‘, ‘0‘, ‘0‘, ‘1‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘,
21         ‘0‘, ‘0‘, ‘0‘, ‘1‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘,
22         ‘0‘, ‘0‘, ‘0‘, ‘1‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘E‘,
23         ‘0‘, ‘0‘, ‘0‘, ‘1‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘,
24         ‘0‘, ‘0‘, ‘0‘, ‘1‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘, ‘0‘
25     };
26     Astarbase.Create(&pBuff[0][0], 12, 12);
27     Astarbase.PrintCharArr();
28     PAPoint pPoint = Astarbase.CalcNextPoint(NULL);
29     if (pPoint == NULL)
30     {
31         printf("no path can arrive!\r\n");
32     }
33     else{
34         printf("success arrived!\r\n");
35     }
36     getchar();
37     return 0;
38 }
时间: 2024-10-09 20:21:15

通过A*算法实现多节点的寻径的相关文章

链表算法-后面插入节点

链表算法-后面插入节点

一致性算法中的节点下限(转)

在众多的分布式一致性算法中,经常需要通过节点的数量满足某种规则来保证算法的正确性,比如Paxos算法,依赖一个”多数派“ 节点的工作的正确性.这类算法的共同目标是容许尽量多的节点失败但又不影响算法的正确性”. 这类问题本质上都抽象为数学上集合之间的逻辑关系,下面我们便从集合的性质入手讨论,为此先引入两个问题: 假设N为一非空结合,n为集合的元素数,M1,M2,...,Mm为N的m个子集,其元素数分别为n1,n2,...,nm,则: 求得M1∩M2∩...∩Mn≠Φ的条件 求得M1∩M2∩...∩

无限极分类查找所有子孙节点的改进算法

在以前,遇到无限极分类返回一个节点的所有子孙节点时,我都是用递归计算的,后来发现时间复杂度和空间复杂度都太高了,后来自己研究了一下改进了算法. 节点数据如下:键值对分别是自己对应父亲节点 <?php $tree=array( 1=>0, 2=>1, 3=>2, 4=>3, 5=>4, 6=>5, 7=>6, 8=>7, 9=>8, 10=>9, 11=>10, ); ?> 以往算法如下: <?php function ge

Floyd-Warshall 算法-- 最短路径(适合节点密集的图)

由于此算法时间复杂度为O(V3),大多数情况下不如迪杰斯特拉算法的,迪杰斯特拉算法适合于节点疏散的图. 示例图如下: Step 1 创建节点与边的最短路径结果表(直接可达关系),数值表示距离,INF表示不可达 1 2 3 4 1 0 8 INF 1 2 INF 0 1 INF 3 4 INF 0 INF 4 INF 2 9 0 Step2 找出所有经过1的路径,更新两点间的最短路径 经过1的路径即所有入度和出度路径的组合,总数为入度×出度: 经过1路径为: 第一条,3-1-2 目前MIN(3->

【转载】GC基本算法及C++GC机制

原文: GC基本算法及C++GC机制 阅读目录 前言 基本概念 有向可达图与根集 三种基本的垃圾收集算法及其改进算法 1.引用计数算法 2. Mark & Sweep 算法 3. 节点复制算法 分代回收 C++垃圾回收机制 参考书籍 正文 回到顶部 前言 垃圾收集器是一种动态存储分配器,它自动释放程序不再需要的已分配的块,这些块也称为垃圾.在程序员看来,垃圾就是不再被引用的对象.自动回收垃圾的过程则称为垃圾收集(garbage collection).在一个支持垃圾收集的语言中,程序显式地申请内

51nod-迷宫问题(Dijkstra算法)

Dijkstra算法 你来到一个迷宫前.该迷宫由若干个房间组成,每个房间都有一个得分,第一次进入这个房间,你就可以得到这个分数.还有若干双向道路连结这些房间,你沿着这些道路从一个房间走到另外一个房间需要一些时间.游戏规定了你的起点和终点房间,你首要目标是从起点尽快到达终点,在满足首要目标的前提下,使得你的得分总和尽可能大.现在问题来了,给定房间.道路.分数.起点和终点等全部信息,你能计算在尽快离开迷宫的前提下,你的最大得分是多少么? Dijkstra算法是一个经典的算法--他是荷兰计算机科学家D

数据结构与算法系列研究四——数组和广义表

稀疏矩阵的十字链表实现和转置 一.数组和广义表的定义 数组的定义1:一个 N 维数组是受 N 组线性关系约束的线性表.           二维数组的逻辑结构可形式地描述为:           2_ARRAY(D,R)              其中 D={aij} | i=0,1,...,b1-1; j=0,1,...,b2-1;aij∈D0}              R={Row,Col}              Row={<aij,ai,j+1>|0<=i<=b1-1;

一致性哈希算法原理

一致性Hash算法背景 一致性哈希算法在1997年由麻省理工学院的Karger等人在解决分布式Cache中提出的,设计目标是为了解决因特网中的热点(Hot spot)问题,初衷和CARP十分类似.一致性哈希修正了CARP使用的简单哈希算法带来的问题,使得DHT可以在P2P环境中真正得到应用. 但现在一致性hash算法在分布式系统中也得到了广泛应用,研究过memcached缓存数据库的人都知道,memcached服务器端本身不提供分布式cache的一致性,而是由客户端来提供,具体在计算一致性has

Raft算法国际论文全翻译

最近在开发强一致性的分布式算法,因此需要深入理解下Raft算法,这里对Raft论文进行了翻译,留以备用 - Sunface. 英文版论文:https://ramcloud.atlassian.net/wiki/download/attachments/6586375/raft.pdf Raft 是一种通过日志复制来实现的一致性算法,提供了和(多重)Paxos 算法相同的功能和性能,但是它的算法结构和 Paxos 是不同的,因此Raft 算法更容易理解和应用.Raft 有几个关键模块:领导人选举.