C++ 如何在结构元素的链接向量中添加元素

C++ 如何在结构元素的链接向量中添加元素,c++,algorithm,a-star,C++,Algorithm,A Star,我有一个叫做网格的结构: struct grid { grid *parent; int x, y; float f, g, h; }; 我还创建了一个结构网格向量:vector open 下面是路径查找代码的一部分。我试图创建一个名为neighbor的新网格,在每次迭代中,我都将其添加到开放向量中,但由于每次迭代都会更改neighbor,因此无法将其正确添加到开放向量中。哪种方法更有效?如何添加到开放向量?基本上,如何实现结构成员的链接向量而不是链表 whil

我有一个叫做网格的结构:

struct grid {
    grid *parent;
    int x, y;
    float f, g, h;
    };
我还创建了一个结构网格向量:vector open 下面是路径查找代码的一部分。我试图创建一个名为neighbor的新网格,在每次迭代中,我都将其添加到开放向量中,但由于每次迭代都会更改neighbor,因此无法将其正确添加到开放向量中。哪种方法更有效?如何添加到开放向量?基本上,如何实现结构成员的链接向量而不是链表

while( !open.empty() )
    {
        grid current, neighbor;
        current=//... minimum-value node in the open vector
        for(vector<grid>::iterator it = open.begin(); it != open.end();++it )
            if((it->x == current.x) &&(it->y == current.y))
               it=open.erase(it);

        for(i=0;i<4;i++)
        {
            neighbor.x=current.x+neighbor_primitves[i][0];
            neighbor.y=current.y+neighbor_primitves[i][1];
            if( (neighbor.x>=0) && (neighbor.x<=100) && (neighbor.y>=0) && (neighbor.y<=100))
            {
                neighbor.parent=new grid;
                neighbor.parent->x=current.x;
                neighbor.parent->y=current.y;
                neighbor.g=current.g+1;
                neighbor.h=heuristic(neighbor,goal);
                neighbor.f=neighbor.g+neighbor.h;
                if(isitinNless(neighbor,open))
                   for(vector<grid>::iterator it = open.begin(); it != open.end(); ++it)
                    {
                          if((it->x == neighbor.x) &&(it->y == neighbor.y))
                          it=open.erase(it);
                     }            
                if(!(isitin(neighbor,open)) )
                    open.push_back(neighbor);
            }
        }
        closed.push_back(current);
    }
编辑:

当我在while循环的末尾添加以下代码行时,我发现父级未在while循环之外更新,即在while循环内部,我更新每个网格成员的父级,但在while循环的范围之外,这些更新不会发生,就好像无法将父级分配给任何网格成员一样。 完整代码:

// A star
#include<iostream>
#include <vector>
#include <cmath>

using namespace std;

struct grid {
    grid *parent;
    int x, y;
    float f, g, h;
    };

float heuristic(grid one, grid two)
{
    float norm= (one.x-two.x)*(one.x-two.x)+(one.y-two.y)*(one.y-two.y);
    return (sqrt(norm));
}

bool isitin(grid &ref, vector<grid> &whole)
{
    bool key=false;
    if(whole.empty())
        return key;
    std::vector<grid>::iterator it;
    for(it = whole.begin(); it != whole.end(); ++it)
    {
        if((it->x==ref.x) && (it->y==ref.y))
            key=true;
    }
    return key;
}

bool isitinNless(grid &ref, vector<grid> &whole)
{
    bool key=false;
    if(whole.empty())
        return key;
    /*
    node iter;
    while(!whole.empty())
    {
        iter=whole.back();
        if((iter.x==ref.x) && (iter.y==ref.y))
            key=true;
        whole.pop_back();
    }*/
    std::vector<grid>::iterator it;
    for(it = whole.begin(); it != whole.end(); ++it)
        if((it->x==ref.x) && (it->y==ref.y) && (ref.g < it->g))
            key=true;
    return key;
}

grid& findmin(vector<grid> &open)
{
    int mini=2000000;
    grid mininode;
    /*
    while(!open.empty())
    {
        iter=open.back();
        if(iter.f<mini)
        {
            mini=iter.f;
        }
        open.pop_back();
    }
    */
    std::vector<grid>::iterator it;
    for(it = open.begin(); it != open.end(); ++it) {
        if(it->f<mini)
            {
                mini=it->f;
                mininode=*it;
            }
    }
    return mininode;
}
int main() {

/*
    vector<node*> open;
    vector<node*> closed;

    node *start=new node;
    start->x=50;
    start->y=50;
    start->f=0;
    start->g=0;
    start->h=0;// you can take it as zero. works instea of the actual distnace between goal and start.

    node *goal=new node;
    goal->x=53;
    goal->y=50;
    goal->f=-1;
    goal->g=-1;
    goal->h=0;

    // put the starting node on the open list
    open.push_back(start);
    node *current=new node;
    current=open.back();
    cout<<current->x;
*/
    vector<grid> open;
    vector<grid> closed;
    // neighbor generation scheme
    int neighbor_primitves[4][2],i;
    neighbor_primitves[0][0]=1; neighbor_primitves[0][1]=0;
    neighbor_primitves[1][0]=0; neighbor_primitves[1][1]=1;
    neighbor_primitves[2][0]=-1; neighbor_primitves[2][1]=0;
    neighbor_primitves[3][0]=0; neighbor_primitves[3][1]=-1;

    grid start;
    start.parent=NULL;
    start.x=50;
    start.y=50;
    start.f=0;
    start.g=0;
    start.h=0;// you can take it as zero. works instead of the actual distnace between goal and start.

    grid goal;
    goal.parent=&start; // just a cosmetic assignment.
    goal.x=53;
    goal.y=50;
    goal.f=-1;
    goal.g=-1;
    goal.h=0;


    // put the starting node on the open list
    open.push_back(start);

    /*if(isitin(start,open))
        cout<<"YO!!!";
    if(!open.empty())
        cout<<"NO!!!";*/
    /*
    node current;
    current=open.back();
    cout<<current.x;
    */

    while( !open.empty() )//&& !(findmin(open).x==goal.x) && !(findmin(open).y==goal.y) )
    {
        grid current, neighbor;
        // find the node with the least f on the open list, call it "current"
        current=findmin(open);
        cout<<open.size();
        if(current.x==goal.x && current.y==goal.y)
        {
            cout<<"Goal!!!\n";
            break;
        }
        // pop current off the open list
        for(vector<grid>::iterator it = open.begin(); it != open.end(); )
        {
            if((it->x == current.x) &&(it->y == current.y))
                {
                    it=open.erase(it);
                }
            else
                ++it;
        }
        cout<<open.size();
        // generate q's 8 successors and set their parents to current
        for(i=0;i<4;i++)
        {
            neighbor.x=current.x+neighbor_primitves[i][0];
            neighbor.y=current.y+neighbor_primitves[i][1];
            if( (neighbor.x>=0) && (neighbor.x<=100) && (neighbor.y>=0) && (neighbor.y<=100))
            {
                neighbor.parent=new grid;
                neighbor.parent->x=current.x;
                neighbor.parent->y=current.y;
                neighbor.g=current.g+1;
                neighbor.h=heuristic(neighbor,goal);
                neighbor.f=neighbor.g+neighbor.h;
                //if(!(isitinNless(neighbor,open)) && !(isitinNless(neighbor,closed)))
                 //   open.push_back(neighbor);
                if(isitinNless(neighbor,open))
                {
                    // pop neighbor off the open list
                    for(vector<grid>::iterator it = open.begin(); it != open.end(); )
                    {
                        if((it->x == neighbor.x) &&(it->y == neighbor.y))
                            {
                                it=open.erase(it);
                            }
                        else
                            ++it;
                    }
                }
                if(isitinNless(neighbor,closed))
                {
                    // pop neighbor off the closed list
                    for(vector<grid>::iterator it = closed.begin(); it != closed.end(); )
                    {
                        if((it->x == neighbor.x) &&(it->y == neighbor.y))
                            {
                                it=closed.erase(it);
                            }
                        else
                            ++it;
                    }
                }
                if(!(isitin(neighbor,open)) && !(isitin(neighbor,closed)))
                    open.push_back(neighbor);
            }
        }
        closed.push_back(current);
        // cout<<open.size()<<"\n";
        cout<<"\n";
        for(vector<grid>::iterator it = open.begin(); it != open.end(); ++it)
            cout<<it->x<<" "<<it->y<<" "<<it->parent->x<<" "<<it->parent->y<<"\n";
    }
    grid* test=goal.parent;
    cout<<test->x<<" "<<test->y;
    cin.get();
    return 0;
}
你的问题在findmin。您希望返回对向量元素的引用,但它返回对无效数据位置的引用:

grid& findmin(vector<grid> &open)
{
    int mini=2000000;
    grid mininode; //locally allocated grid

    std::vector<grid>::iterator it;
    for(it = open.begin(); it != open.end(); ++it) {
        if(it->f<mini)
            {
                mini=it->f;
                mininode=*it; //assigns values in the grid pointed to by it to mininode
            }
    }
    return mininode; //returns a reference to the locally scoped grid
} //destroys mininode

你说的链接向量是什么意思?我知道这个词不正确。我指的是一个向量,它包含相互链接的结构元素。至少你的向量应该包含grid*s。你知道为什么吗?@JonathanMee-复制是向量要做的事情。将类型放在具有错误复制语义的向量中会导致问题,这不是一个好主意。@userzizzy-简单地说,您的结构网格不可安全复制。您要查找的引用是第3条规则:请转到管理资源部分,因为它直接应用于您的结构以及您如何使用指针成员设置它。
grid& findmin(vector<grid> &open)
{
    int mini=2000000;
    grid mininode; //locally allocated grid

    std::vector<grid>::iterator it;
    for(it = open.begin(); it != open.end(); ++it) {
        if(it->f<mini)
            {
                mini=it->f;
                mininode=*it; //assigns values in the grid pointed to by it to mininode
            }
    }
    return mininode; //returns a reference to the locally scoped grid
} //destroys mininode
auto& current = *find_min(open.begin(), open.end(), [](const grid& first, const grid& smallest){return first->f < smallest->f;});