在while循环内的变量中分配新内存

时间:2013-12-16 20:03:37

标签: c++ pointers memory-management queue artificial-intelligence

我有一个Town类,它代表我的图中的节点,如下所示:

class Town
{
public:
    Town();
public:
    Town* _parent;

    int _name;
    int _row;
    int _column;
    State _state;

    vector<Town*> _neighbors;
};

我有一个Map类,其中包含一个城镇的2D矢量,几乎可以制作我的随机图。

class Map
{
public:
    Map(const int elements, const int size, const int seed);
public: 
    vector <vector<Town> > _map;
    vector <Town*> _towns;
    vector <vector<int> > _adjacency;
    vector <vector<double> > _mDistance;
    vector <Line> _edges;

    const int _elements;
    const int _size;

    Town* _start;
    Town* _exit;
};

然后我的AI类会收到一个Map对象,并根据算法解决它,现在我正在实施Astar。

class AI
{
private:
    struct TownWithCost
    {
        Town town;
        double cost;
    };

    struct OrderByTotalCost
    {
        bool operator()(TownWithCost lfs, TownWithCost rhs)
        {
            return lfs.cost > rhs.cost;
        }
    };
public:
    AI(Map map);
private:
    bool AStar(Town* town);

    double GetTotalCost(Town town);

public:
    bool _success;
private:
    Map _map;
};

这是我的Astar实施:

bool AI::AStar(Town* town)
{
    AI::OrderByTotalCost comparator;
    vector<TownWithCost> priorityQueue;

    TownWithCost currentTown = { *town, 0 };
    Town temp = currentTown.town;

    priorityQueue.push_back(currentTown);

    SetEnvironment(temp, State::visited);

    while (!priorityQueue.empty())
    {
        currentTown = priorityQueue.front();
        Town temp = currentTown.town;

        priorityQueue.erase(priorityQueue.begin());

        SetEnvironment(temp, State::visited);
        PrintEnvironment();

        if (temp._name == _map._exit->_name)
        {
            return true;
        }

        vector <Town*> neighbors = town->_neighbors;

        for each (Town* neighbor in neighbors)
        {
            Town tempNeighbor = *neighbor;

            if (tempNeighbor._state == State::town)
            {
                tempNeighbor._parent = &temp;
                TownWithCost neighborWithCost = { tempNeighbor, GetTotalCost(tempNeighbor) };

                priorityQueue.push_back(neighborWithCost);
            }
        }
        make_heap(priorityQueue.begin(), priorityQueue.end(), comparator);
    }
    return false;
}

你可能已经注意到我还没有实现在priorityQueue内查看我是否已经拥有Town并比较成本以查看我想保留哪一个但是我计划在解决当前问题后实施这个问题。

我的问题是,我不希望在priorityQueue内有指针。我正在尝试制作临时变量,这些变量将复制一个城镇,而且它的成本来自某条路径。

假设我从城镇9开始。

9有邻居0783特别是第一个循环的priorityQueue如下所示:

Parent 9

然后我得到3作为我的currentTown,我正在检查它的邻居。

当我第二次到达Town temp = currentTown.town;行时,priorityQueue中每个元素的父母都被设置为3。现在我明白为什么会发生这种情况,我不明白的是如何防止这种情况。

Parent  changed to 3

我基本上需要priorityQueue来存储具有不同父级和不同成本的相同城镇(不同的内存地址)(我已经用结构TownWithCost处理了单独的成本)。所以总是每次都复制。

例如,我可以直接从90获得总费用81,但我也可以通过03)到达9 -> 3 -> 0总费用50.我希望能够区分这两者。

如何在我的priorityQueue中区分它们以及如何避免重置父项,或者换句话说,每次循环运行时如何为Town temp分配另一部分内存,以便我每次可以有不同的温度?

如果您有其他方式(尽可能新手友好)这样做,请随意说出来。

2 个答案:

答案 0 :(得分:1)

您正在通过Map的值实例传递,并且此类没有复制构造函数或赋值运算符。当这个类被浅层复制时(ala memcpy)vector实例会在它们被销毁(多次)时导致崩溃。

尝试使用指针或引用。也会更快。

答案 1 :(得分:1)

您还可以使用索引向量指向城镇的数组或向量。不需要指针。但就个人而言,我更喜欢使用std:shared_ptr。