У меня есть структура данных, следующая
struct routing
{
int color; //white = -1, gray = 0, black = 1
unsigned int d; //distance
unsigned int pi; //previous node id
routing() : color (-1), d (UINT_MAX), pi (UINT_MAX ) {}
};
struct attraction //each node in graph is called an attraction
{
unsigned int id; //id of node
std::string name; //name
unsigned int priority; //priority
std::unordered_map<int, int> nodeMap; //destination node id, distance
routing r; //routing information
attraction() : id (0) , name(""), priority(0) {}
};
Теперь я должен запустить алгоритм Дейкстры, чтобы найти кратчайшее расстояние между различными узлами (называемыми аттракционами). Я реализовал его, и он работает отлично. За исключением того, что он медленный (чем мне нужно).
У меня есть контейнер STL, который хранит информацию об узлах. Я использую это для выполнения маршрутизации. Он приводится ниже:
//I use unordered_map for fast access of elements.
typedef std::unordered_map<unsigned int, attraction*> attractionList;
attractionList attrList;
То, что я пытаюсь сделать, это один раз рассчитать все пути/расходы всех вершин из определенного узла и сохранить его в контейнере attractionList, я хочу, чтобы повторно использовать эту информацию, так что последующие вызовы маршрутизации от этого определенного исходного узла будет Быстрее. Для этого я хочу сохранить состояние контейнера attrList, чтобы я мог быстро использовать сохраненную информацию. Я пытаюсь что-то вроде этого:
//make another container whose first element is a unique source id, second element is the attractionList
std::unordered_map<unsigned int, attractionList> stateMap; (containig routing information)
attractionList* newList = new attractionList(); //make a new object to store old state
newList = &attrList; //copy values from old state
//insert in another container so that each unique source id has all routing information stored
stateMap.insert(std::pair<unsigned int, attractionList> (from, *newList));
Ну, проблема с этим очевидна. Когда указатели, сохраненные в attrList, изменяют все сделанные из него копии, являются недопустимыми. Как хранить их на постоянной основе? Как выполняется копирование в этом контейнере? При необходимости, как перегрузить оператор присваивания? Возможно ли это? Я могу внести небольшие изменения в структуру данных и контейнеры, но не так много.
Извините, за длинную статью. Заранее спасибо.
attractionList* newList = new attractionList(); //make a new object to store old state
newList = &attrList; //copy values from old state
Ну, проблема с этим очевидна. Когда указатели, сохраненные в attrList, изменяют все сделанные из него копии, являются недопустимыми.
Вы не сделали копию. Вы выделили новый пустой список в куче, затем вы отбросили указатель на него и сохранили указатель на существующий список.
Я думаю, вы имеете в виду:
attractionList newList = attrList;
но я не просмотрел остальную часть вашего кода, так что это может быть не полное исправление.
Что касается вашего комментария:
Если вам нужно также скопировать достопримечательности, вам нужно где-то их хранить. Поскольку вы не говорите, как вы храните оригиналы, я не могу сказать вам, где хранить копии, но остальная часть кода будет примерно такой:
attractionList newList;
for (attractionList::iterator it = attrList.begin(); it != attrList.end(); ++it) {
attraction *newNode = /* copy of *(it->second) */;
newList.insert(make_pair(it->first, newNode));
}
auto it = stateMap.find(source);
if (it == stateMap.end())
{
resetNodes();
bool d=dijkstra(attrList.at(from),attrList.at(to));
attractionList newList = attrList;
stateMap.insert(std::pair<unsigned int, attractionList(from, newList));
return d;
}
new
без всякой рифмы или причины.newList = &attrList;
мгновенная утечка памятиnewList = &attrList; //copy values from old state
- я не думаю, что это означает, что вы думаете, что это значит.