heapified vector在push_heap调用上抛出无效堆

时间:2014-04-20 23:32:12

标签: c++ vector stl heap a-star

我正在使用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);
    }
}

我已经标记了导致崩溃的行。我是否错误地使用堆函数?

0 个答案:

没有答案