关于A*寻路的实现-感谢下我的室友杨XX。。。。。。。。。

关于A*寻路的实现-感谢下我的室友杨XX。。。。。。。。。

好久都没更新博客了。。。。。。。。这段时间主要是忙着百度之星的A*坦克大战。。。。。。。虽然成绩不理想但还是让我感到欣喜的就是学到了A*算法。。。。。。。其实A*的思想很简单。。。。就是从上下左右4个方向寻找离终点步数最少的那个节点取出来。。。。。。这里就涉及了一个排序的问题。。。。。额。。。本人数据结构学的不是很扎实所以初期写了一个A*效率太低几乎没用。。。。。。。这里发一个由我的室友杨XX的改进版。。。利用了堆排序了。。。。效率提高了很多。。。。。。征求他的同意这里将实现代码发出来。。。。大家互相学习学习:
defin.h
////////////////////////////////////
#ifndef DEFINE_H
#define DEFINE_H

#include <iomanip>
#include <iostream>

using namespace std;
#define mapwidth 15
#define mapheight 13
#define mapsize (mapwidth*mapheight)

void showpath(const int *map);
void a_find(const int *map,int size,int beginpos,int endpos);
int get_len(int beginbos,int endpos);

#endif
//////////////////////////////////////////////

heap.h堆类
////////////////////////////////
#ifndef HEAP_H
#define HEAP_H

#include<iostream>
using namespace std;

template<typename T>
class Heap
{
public:
 Heap():m_size(0),max_size(100),h(NULL),m_ismax(true){}
 ~Heap(){if(h)delete[] h;}
 inline int size(){return m_size;}
 inline bool isempty();
 inline void add(T item);
 inline bool pop(T& item);
 inline void resize(int size);
 //////////////////////////////////堆排序
 inline void build(int k);
 inline void change_compare(bool ismax=true); 

private:
 bool m_ismax;
 int m_size;
 int max_size;
 void shift(int m);
 T *h;
};

template<typename T>
void Heap<T>::change_compare(bool ismax)
{
 m_ismax=ismax;
}

template<typename T>
void Heap<T>::add(T item)
{
 if(isempty())
 {
  h=new T[max_size];
 }
 h[m_size]=item;
 m_size++;
 build(m_size); 
 if(m_size>=max_size)
  resize(max_size*2); 
}

template<typename T>
bool Heap<T>::pop(T& item)
{
 if(m_size<1)
  return false;
 item=h[0];
 h[0]=h[m_size-1];
 m_size--;
 build(m_size);
 return true;
}

template<typename T>
void Heap<T>::build(int k)
{
 k/=2;
 for(int i=k-1;i>=0;i=(i+1)/2-1)
 {
  shift(i);
  if(!i)
   break;
 }
  
 
}

template<typename T>
void Heap<T>::resize(int Size)
{
 T* t=h;
 h=new T[Size];
 max_size=Size;
 for(int i=0;i<size();i++)
  h[i]=t[i];
 delete[] t;
}

template<typename T>
bool Heap<T>::isempty()
{
 if(m_size)
  return false;
 else
  return true;
}

template<typename T>
void Heap<T>::shift(int m)
{
 int j,n=size()-1;
 T t;
 t=h[m];
 j=2*m+1;
 if(m_ismax)
 {
  while(j<=n)
  {
   if((j<n) && (h[j]<h[j+1]))
    j++;
   if(t<h[j])
   {
    h[m]=h[j];
    m=j;
    j=2*m+1;
   }
   else
    j=n+1;
  }
 }
 else
 {
  while(j<=n)
  {
   if((j<n) && (h[j]>h[j+1]))
    j++;
   if(t>h[j])
   {
    h[m]=h[j];
    m=j;
    j=2*m+1;
   }
   else
    j=n+1;
  }
 }
 h[m]=t;
}
#endif
////////////////////////////////////////////////////

open_node.h 节点类
///////////////////////////////////////////////////
#ifndef open_node_H
#define open_node_H
class open_node
{
public:
 open_node():nowpos(0),nextpos(0),score(0),from_start(0){}
 inline open_node& operator = (const open_node&);
 inline bool operator > (const open_node&);
 inline bool operator < (const open_node&);

 int nowpos;
 int nextpos;
 int score;
 int from_start;
 
};

open_node& open_node :: operator = (const open_node& node)
{
 nowpos=node.nowpos;
 nextpos=node.nextpos;
 from_start=node.from_start;
 score=node.score;
 return *this;
}

bool open_node ::operator > (const open_node& node)

 return score>node.score ? true:false;
}

bool open_node ::operator < (const open_node& node)
{
 return score<node.score ? true:false;
}
#endif
///////////////////////////////////////////////////////


find.cpp实现A*
//////////////
#include "define.h"
#include "open_node.h"
#include "heap.h"

void a_find(const int *map,int size,int beginpos,int endpos)
{
 int path[mapsize];
    int countofpath=0;
 int val=1;                //地形消耗(array)
 
 int Open_Close[mapsize]; 
 
 open_node node[mapsize];
 int countofnode=0;

 open_node node_pre;
 int iter;
 
 Heap<open_node> open_heap;
 open_heap.change_compare(false);
 
 //memcpy(Open_Close,map,sizeof(int)*mapsize);
 
 node_pre.nowpos=beginpos;
 node_pre.score=node_pre.from_start+get_len(beginpos,endpos);
 open_heap.add(node_pre);
 

 while(open_heap.size())
 { 
  countofnode++; 
  open_heap.pop(node[countofnode]);  
  
  if(node[countofnode].nowpos==endpos)
   break;
  else
  {
   Open_Close[node[countofnode].nowpos]=0;
   int up=node[countofnode].nowpos-mapwidth;
   int down=node[countofnode].nowpos+mapwidth;
   int left=node[countofnode].nowpos-1;
   int right=node[countofnode].nowpos+1;   
   //up
   if(up>=0)
   {
    if(Open_Close[up])
    {     
     node_pre.nextpos=countofnode;
     node_pre.nowpos=up; 
     node_pre.from_start=node[countofnode].from_start+val;
     node_pre.score=node_pre.from_start+get_len(node_pre.nowpos,endpos);     
     open_heap.add(node_pre);     
    }
   }
   
   //down
   if(down<mapsize)
   {
    if(Open_Close[down])
    {
     node_pre.nextpos=countofnode;
     node_pre.nowpos=down; 
     node_pre.from_start=node[countofnode].from_start+val;
     node_pre.score=node_pre.from_start+get_len(node_pre.nowpos,endpos);      
     open_heap.add(node_pre);
    }
   }
   
   //left
   if((node[countofnode].nowpos%mapwidth)!=0)
   {
    if(Open_Close[left])
    {
     node_pre.nextpos=countofnode;
     node_pre.nowpos=left; 
     node_pre.from_start=node[countofnode].from_start+val;
     node_pre.score=node_pre.from_start+get_len(node_pre.nowpos,endpos); 
     open_heap.add(node_pre);
    }
   }
   
   //right
   if((right%mapwidth)!=0)
   {
    if(Open_Close[right])
    {     
     node_pre.nextpos=countofnode;
     node_pre.nowpos=right; 
     node_pre.from_start=node[countofnode].from_start+val;
     node_pre.score=node_pre.from_start+get_len(node_pre.nowpos,endpos);     
     open_heap.add(node_pre);
    }
   }   
  }
 }
 iter=countofnode;
 while(iter)
 {
  path[countofpath++]=node[iter].nowpos;
  iter=node[iter].nextpos;
 }
 showpath(map);
 int mmp[mapsize];
 memset(mmp,0,sizeof(int)*mapsize);
 for(int i=0;i<countofpath;i++)
 {
  mmp[path[i]]=1;  
 }
 cout<<"路线:"<<endl;
 for(int iy=0;iy<mapheight;iy++)
 {
  for(int ix=0;ix<mapwidth;ix++)
   cout<<setw(3)<<mmp[iy*mapwidth+ix];
  cout<<endl;
 }

 
}

int get_len(int beginpos,int endpos)
{
 int x,y;
 x=(endpos-beginpos)%mapwidth;
 x=x>0?x:-x;
 y=(endpos-beginpos)/mapwidth;
 y=y>0?y:-y;
 return x+y; 
}

void showpath(const int *mapdata)

 cout<<"原始地图:"<<endl;
 for(int iy=0;iy<mapheight;iy++)
 {
  for(int ix=0;ix<mapwidth;ix++)
   cout<<setw(3)<<mapdata[iy*mapwidth+ix];
  cout<<endl;
 }
}
//////////////////////////////

main.cpp 调用
///////////////////////////////

#include"define.h"


//////////////////////////////////////////////////////////////

void main()
{
/* const int mapdata[mapsize]={
  1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,
     1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,
  1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,
  1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,
  1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,
  1,1,1,1,0,1,1,1,1,0,0,1,1,1,1,
  0,1,1,1,1,1,1,1,1,1,0,0,0,1,0,
  0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,
  0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,
  0,1,1,1,1,1,1,1,1,1,0,0,1,1,0,
  0,0,1,0,0,0,0,0,1,0,0,0,1,1,1,
  0,0,1,1,1,1,1,1,1,1,0,0,0,0,1,
  0,0,0,0,0,0,0,0,0,1,1,1,1,1,1
 };
*/
 const int mapdata[mapsize]={
  2,2,2,2,0,0,0,0,0,1,1,1,1,1,1,
  1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,
  1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,
  1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,
  1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,
  1,1,1,1,0,1,1,1,1,0,0,1,1,1,1,
  0,1,1,1,1,1,1,1,1,1,0,0,0,1,0,
  0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,
  0,0,0,0,0,0,0,0,2,1,0,0,1,1,0,
  0,1,1,1,1,1,1,1,1,1,0,0,1,1,0,
  0,0,1,0,0,0,0,0,1,0,0,0,1,1,1,
  0,0,1,1,1,1,1,1,1,1,0,0,0,0,1,
  0,0,0,0,0,0,0,0,0,1,1,1,1,1,1
 };


 

 

 int beginpos=0;
    int endpos=mapsize-1;

 

 a_find(mapdata,mapsize,beginpos,endpos);


}
/////////////////////////////////////////////
这就是A*全部实现代码。。。。。。。。。。。。最后再次感谢下我的室友杨XX给我的帮助....................
                                                                                                                                                                 记于2010年6月14日 下午

你可能感兴趣的:(关于A*寻路的实现-感谢下我的室友杨XX。。。。。。。。。)