A星寻路
2016-06-23 22:36
609 查看
#ifndef KASTAR_H #define KASTAR_H #include <iostream> #include <map> #include <vector> using namespace std; enum eAStarBarrier { eASB_None, eASB_Yes, eASB_Start,//起始点 eASB_End,//结束点 }; enum enum_FindRes { enum_FindPathFailed, enum_FindPathSuccess, enum_FindPathContinue, }; struct PosInfo { int x; int y; int g;//g值 int f;//f值 int h;//h值 PosInfo *parent;//父结点 PosInfo(){ x = 0; y = 0; g = 0; f = 0; h = 0; parent = NULL; } }; struct PosValue { PosInfo *pos; bool operator <(const PosValue &o)const { if (pos->f == o.pos->f) { return (long)pos < (long)o.pos; } return pos->f < o.pos->f; } PosValue(PosInfo *pos) { this->pos = pos; } }; typedef pair<int,int> PosPair; typedef map<PosPair,PosInfo *> Map_PosInfo; typedef vector<PosInfo*> Vec_PosInfo; typedef map<PosValue,PosInfo*> Map_PosValue; typedef pair<Map_PosValue::iterator,bool > Map_PosValue_Ret; class AStar { public: PosInfo *m_startPos; PosInfo *m_endPos; int m_srcX; int m_srcY; int m_destX; int m_destY; int m_minX; int m_maxX; int m_minY; int m_maxY; int m_yLimit; int m_xLimit; int **m_pointInfo; PosInfo *m_optimumPos;//最优点 Map_PosValue m_mvOpenList;//为了找到最优点的开放列表 Map_PosInfo m_openList;//开放列表 Map_PosInfo m_closeList;//关闭列表 vector<PosInfo *> m_trackALiveList;//寻路跟踪列表,不包括死路 vector<PosInfo *> m_trackAllList;//寻路跟踪列表,包括死路点 public: int AddOpenPos(PosInfo *pos) { m_openList.insert(Map_PosInfo::value_type(PosPair(pos->x,pos->y),pos)); m_mvOpenList.insert(Map_PosValue::value_type(PosValue(pos),pos)); FindOptimumpos(); return 0; } PosInfo *FindOptimumpos() { m_optimumPos = NULL; if (m_mvOpenList.size() > 0) { Map_PosValue::iterator iterV = m_mvOpenList.begin(); m_optimumPos = iterV->second; } return m_optimumPos; } int ChangeFValue(PosInfo *pos) { Map_PosValue::iterator iterv = m_mvOpenList.find(PosValue(pos)); if (iterv != m_mvOpenList.end()) { m_mvOpenList.erase(iterv); fFunction(pos); m_mvOpenList.insert(Map_PosValue::value_type(PosValue(pos),pos)); FindOptimumpos(); return 0; } return 1; } int DelOpenPos(PosInfo *pos) { m_openList.erase(PosPair(pos->x,pos->y)); m_closeList.insert(Map_PosInfo::value_type(PosPair(pos->x,pos->y),pos)); Map_PosValue::iterator iterV = m_mvOpenList.find(PosValue(pos)); if (iterV != m_mvOpenList.end()) { m_mvOpenList.erase(iterV); } if (pos == m_optimumPos) { FindOptimumpos(); } return 0; } AStar(); ~AStar(); int printInit(PosInfo *pos); int printTrack(PosInfo *pos); int hFuncion(PosInfo *pos) { return pos->h = 10*(abs(pos->x-m_destX) + abs(pos->y-m_destY)); } int hasFindFunc(PosInfo *pos) { return pos->x == m_destX && pos->y == m_destY; } int fFunction(PosInfo *pos) { return pos->f = pos->h + pos->g; } void hfFunction(PosInfo *pos) { hFuncion(pos); fFunction(pos); } int gfunction(int i,int j) { i = abs(i); j = abs(j); if(i>1 || j>1 ) return 10000; switch(i+j) { case 0: return 0; case 1: return 10; case 2: return 14; } return 10000; } int init(); int InitByTable(); int FindPath();//A星寻路 inline bool IsValid(int x,int nMin,int nMax) { return x >= nMin && x < nMax; } inline bool IsValidX(int x) { return IsValid(x,m_minX,m_maxX); } inline bool IsValidY(int y) { return IsValid(y,m_minY,m_maxY); } inline bool IsValidPos(int x,int y) { return IsValidX(x) && IsValidY(y) && m_pointInfo[x][y] != eASB_Yes; } int clear(); }; #endif
#include "AStar.h" #include <stdio.h> #include <algorithm> AStar::AStar() { m_srcX = 0; m_srcY = 0; m_destX = 0; m_destY = 0; m_minX = 0; m_minY = 0; m_maxX = 0; m_maxY = 0; m_pointInfo = NULL; m_optimumPos = NULL; } AStar::~AStar() { clear(); } const int MaxValue = 40; int AStar::init() { m_yLimit = MaxValue; m_xLimit = MaxValue; m_pointInfo = new int *[m_xLimit]; for (int i = 0;i<m_xLimit;i++) { m_pointInfo[i] = new int[m_yLimit]; } for (int i = 0;i<m_xLimit;i++) { for (int j = 0;j<m_yLimit;j++) { m_pointInfo[i][j] = 0; } } int d = MaxValue/10; int middle = MaxValue/2; for(int i = middle-d; i<= middle+d; i++) m_pointInfo[i][middle+2*d] = 1; for(int i = middle; i< middle+2*d; i++) m_pointInfo[middle-d][i] = 1; for(int i = middle; i< middle+2*d; i++) m_pointInfo[middle+d][i] = 1; m_srcX = middle; m_srcY = middle+d; m_destX = middle; m_destY = middle+3*d; m_minX = 0; m_minY = 0; m_maxX = m_xLimit; m_maxY = m_yLimit; return 0; } int AStar::clear() { Map_PosInfo::iterator it; for(it=m_closeList.begin();it!=m_closeList.end();++it) delete it->second; m_closeList.clear(); for(it=m_openList.begin();it!=m_openList.end();++it) delete it->second; m_openList.clear(); m_trackAllList.clear(); m_trackALiveList.clear(); return 0; } int AStar::printInit(PosInfo *endPos) { PosInfo *pos = endPos->parent; map<PosPair,int> path; while(pos && pos->parent) { path[PosPair(pos->x,pos->y)] = 1; pos = pos->parent; } for (int j = 0;j<m_yLimit;j++) { for (int i = 0;i<m_xLimit;i++) { if (i==m_srcX && j == m_srcY) { printf("S"); } else if(i==endPos->x && j == endPos->y) { printf("E"); } else if(path[PosPair(i,j)] == 1) { printf("+"); } else if(m_pointInfo[i][j] == 1) { printf("*"); } else { printf(" "); } printf(" "); } printf("\n"); } return 0; } int AStar::printTrack(PosInfo *endPos) { map<PosPair,int> path; int j = 0; for (vector<PosInfo *>::iterator it = m_trackAllList.begin();it!=m_trackAllList.end();it++) { PosInfo *pos = *it; path[PosPair(pos->x,pos->y)] = j%26+1; j++; } for (int j = 0;j<m_yLimit;j++) { for (int i = 0;i<m_xLimit;i++) { if (i==m_srcX && j == m_srcY) { printf("S"); } else if(i==endPos->x && j == endPos->y) { printf("E"); } else if(path[PosPair(i,j)]) { printf("%c",path[PosPair(i,j)]+'a'-1); } else if(m_pointInfo[i][j] == 1) { printf("*"); } else { printf(" "); } printf(" "); } printf("\n"); } return 0; } int AStar::FindPath()//循环实现 { m_startPos = new PosInfo(); m_startPos->x = m_srcX; m_startPos->y = m_srcY; hfFunction(m_startPos); PosInfo *currentPos = m_startPos; DelOpenPos(currentPos); m_trackALiveList.push_back(currentPos); m_trackAllList.push_back(currentPos); do { for (int i = -1;i<2;i++) { for (int j = -1;j<2;j++) { if(i==0 && j==0) { continue; } if(!IsValidPos(currentPos->x+i,currentPos->y+j)) continue; int g = gfunction(i,j); PosInfo * openPos = NULL; PosInfo * closePos = NULL; Map_PosInfo::iterator openPosIter = m_openList.find(PosPair(currentPos->x+i,currentPos->y+j)); Map_PosInfo::iterator closePosIter = m_closeList.find(PosPair(currentPos->x+i,currentPos->y+j)); if(openPosIter != m_openList.end()) { openPos = openPosIter->second; } if(closePosIter != m_closeList.end()) { closePos = closePosIter->second; continue; } else if (openPosIter == m_openList.end()) { openPos = new PosInfo(); openPos->g = g; openPos->g += currentPos->g; openPos->x = currentPos->x + i; openPos->y = currentPos->y + j; openPos->parent = currentPos; hfFunction(openPos); AddOpenPos(openPos); } else if(currentPos->g + g < openPos->g) { openPos->g = currentPos->g + g; openPos->parent = currentPos; ChangeFValue(openPos); } } } int size = m_trackAllList.size(); if(m_optimumPos) { currentPos = m_optimumPos; DelOpenPos(currentPos); int m_openListSize = m_openList.size(); int m_closeListSize = m_closeList.size(); m_trackALiveList.push_back(currentPos); m_trackAllList.push_back(currentPos); if(hasFindFunc(currentPos)) { m_endPos = currentPos; printInit(currentPos); printf("\n--------------------------------------------------------------\n"); printTrack(currentPos); return currentPos->f; } if(m_openList.size() == 0) { break; } } else { break; } } while(true); printInit(currentPos); printTrack(currentPos); return -1; } bool sortPosInfo(PosInfo *&pos1,PosInfo *&pos2) { return pos1->f < pos2->f; } #endif
#include <iostream> using namespace std; #include "AStar.h" int main() { { AStar p; p.init(); p.FindPath(); cout << "over" << endl; } while(1); }
参考:http://blog.csdn.net/shanshanpt/article/details/8977512
相关文章推荐
- 算法基础:排序与查找
- 数据库的各种语句
- SEO工程实施流程、计划、规范
- HTTP网页错误代码---网络、端口
- FPGA视觉从入门到放弃——稀疏编码的原理与简单应用
- Github Pages
- 正则表达式 学习笔记(二)
- 04.Java 集合 - Stack
- border-bottom-style(下边框的样式)
- unity通过android adb查看真机日志
- cocos2dx-精灵如何被渲染and纹理如何被管理、产生与销毁
- 形态学操作实现
- scala学习手记19 - Option类型
- PDB文件:每个开发人员都必须知道的
- mean开发之五:探讨node配置之3种路径和2种模块类型
- js 面试大全
- 大一下学习总结
- 查看linux库文件32位还是64位
- 序列化与反序列化(一)
- ubuntu下C++两种方法解析json