【问题标题】:Allocating new memory in a variable inside a while loop在while循环内的变量中分配新内存
【发布时间】:2013-12-16 20:03:36
【问题描述】:

我有一个 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 中有指针。我正在尝试制作将复制城镇的临时变量,并且它的成本来自某个路径。

假设我从 Town 9 开始。

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

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

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

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

例如,我可以直接从90,总成本为81,但我也可以通过3 (9 -&gt; 3 -&gt; 0) 到达0,总成本为50。我希望能够区分这两者。

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

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

【问题讨论】:

  • 为什么要使用指针向量?为什么不只是一个对象向量?
  • @caps 你的意思是priorityQueue?因为我将它作为TownWithCost 的向量,它使用Townint。除非您在谈论 Town* _parent 变量。我不知道有什么其他方法可以在没有指针的情况下将我从一个城镇带回它来自的城镇。
  • 我的意思是 Map 的这个成员:vector &lt;Town*&gt; _towns;
  • 我这样做是因为每个向量元素都指向一个_map[][] Town 元素。不过不用担心,Astar 根本没有使用该向量。
  • 它做到了,这就是我再次问它的原因。我要问的具体问题是如何在while循环内的变量中分配新内存我还能如何实现Astar的优先级队列

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


【解决方案1】:

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

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

【讨论】:

  • 如果你的意思是通过 Astar 中的指针来做所有事情,那是我做的第一件事,它抛出了错误 invalid heap 因为 GetTotalCost() 正在改变堆中每个元素的成本,这就是为什么我尝试复制我没有成功的所有内容。
  • 没问题。性能保持在最后。但是你需要编写复制构造函数和赋值运算符。
【解决方案2】:

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

【讨论】:

  • 我想改为将Town 存储在TownWithCost 中,我可以每次都存储一个索引向量,这几乎是每次的路径,但我试图找到一种更优雅的方式实现我的目标。但是,如果我不能仅通过副本来做到这一点,那么最后我可能会再次尝试使用矢量方式。此外,我听到很多人在谈论 std::shared_ptr,但我个人没有这方面的经验,因为我是 C++ 新手(以及一般编程),这就是我没有使用它的原因。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-07
  • 2013-02-25
  • 2013-09-13
  • 2015-11-04
  • 1970-01-01
相关资源
最近更新 更多