我正在使用stl堆化向量(具有小于谓词)的A *路径查找的简单4邻居c ++实现。当我运行程序时,它会抛出无效的堆调试断言。我可以在调试器中运行代码,并检查存储在向量中的数据,该数据正确地以F cost的升序存储位置。我不太明白我做错了什么:
//simple function for finding the index of a position in a vector that matches a search position
int find(std::vector<AStarPosition*>& p_Vec,AStarPosition* p_SearchParam)
{
for (size_t i = 0; i < p_Vec.size();i++)
{
if(p_Vec[i]->equals(p_SearchParam))
return i;
}
return -1;
}
//min heap predicate function
bool less(AStarPosition* a, AStarPosition* b)
{
return (a->F < b->F);
}
void AIManager::getNextPathCell(glm::vec3 p_startPosition, glm::vec3 p_targetPosition,std::vector<glm::ivec2>& path)
{
glm::ivec2 startPos = m_maze->getGridCell(p_startPosition);
glm::ivec2 goalPos = m_maze->getGridCell(p_targetPosition);
AStarPosition* start = m_Pool->getPosition(nullptr,startPos.x,startPos.y);
AStarPosition* goal = m_Pool->getPosition(nullptr,goalPos.x,goalPos.y);
start->estimateCost(goal);
bool pathFound = false;
//used to hold positions representing visited grid positions
std::vector<AStarPosition*> usedList;
//create a min heap to hold positions
std::vector<AStarPosition*> openList;
//add the start to the min heap
openList.push_back(start);
std::make_heap(openList.begin(),openList.end(),less);
//set all closed list values to zero (false)
for (size_t i = 0; i < m_closedList.size();i++)
{
std::fill(m_closedList[i].begin(),m_closedList[i].end(),0);
}
//main algorithm:
while(openList.size() > 0)
{
//remove root from openList (position with lowest F cost)
AStarPosition* parent = openList.front();
std::pop_heap(openList.begin(),openList.end(),less);
openList.pop_back();
usedList.push_back(parent);
//if current position == goal
if(parent->equals(goal))
{
pathFound = true;
break;
}
//get successor positions (4)
m_closedList[parent->x][parent->y] = 1;
AStarPosition* successors[4];
//NORTH
successors[0] = m_Pool->getPosition(parent,0,1);
//WEST
successors[1] = m_Pool->getPosition(parent,1,0);
//SOUTH
successors[2] = m_Pool->getPosition(parent,0,-1);
//EAST
successors[3] = m_Pool->getPosition(parent,-1,0);
//for each successor loop
for (int i = 0; i < 4;i++)
{
//if position is a wall or outside maze maze
if(!m_maze->isOk(glm::ivec2(successors[i]->x,successors[i]->y)))
{
//continue
successors[i]->inUse = false;
successors[i] = nullptr;
continue;
}
//if position has been visited
if(m_closedList[successors[i]->x][successors[i]->y]==1)
{
//find position within used list, as more checks are needed
int pos = find(usedList,successors[i]);
//if it has
if(pos!=-1)
{
//and the closed list is less or equal to the successor
//ie a better path than successor
if(usedList[pos]->G <= successors[i]->m_Parent->G+10)
{
//return position to pool and skip to next successor
successors[i]->inUse = false;
successors[i] = nullptr;
continue;
}
else
{
//remove position from the closed list, and return position to pool
usedList[pos]->inUse = false;
m_closedList[successors[i]->x][successors[i]->y] = 0;
usedList.erase(usedList.begin()+pos);
}
}
}
//else if current exists within openlist
int pos = find(openList,successors[i]);
if(pos!=-1)
{
//if current G cost is lower (closer to start, so better path), set openlist entry G as current G and copy parent
if(openList[pos]->G > successors[i]->G)
{
//recalculate F score of openlist entry
openList[pos]->G=successors[i]->G;
openList[pos]->m_Parent=successors[i]->m_Parent;
openList[pos]->estimateCost(goal);
//and resort list
std::sort_heap(openList.begin(),openList.end(),less);
}
successors[i]->inUse = false;
successors[i] = nullptr;
continue;
}
//else not in open list
else
{
//insert successor into open list
openList.push_back(successors[i]);
successors[i]->estimateCost(goal);
////////////////////////////////////////////////////
//line below crashes program
std::push_heap(openList.begin(),openList.end(),less);
}
}
}
if(pathFound)
{
//reconstruct path
AStarPosition* current = usedList.back();
while(!start->equals(current))
{
path.push_back(glm::ivec2(current->x,current->y));
current=current->m_Parent;
}
}
//and clean up
for (std::vector<AStarPosition*>::iterator it = openList.begin();it!=openList.end();)
{
(*it)->inUse=false;
it = openList.erase(it);
}
for (std::vector<AStarPosition*>::iterator it = usedList.begin();it!=usedList.end();)
{
(*it)->inUse=false;
it = usedList.erase(it);
}
}
我已经标记了导致崩溃的行。我是否错误地使用堆函数?