Question

I have a data structure as following

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) {}
};

Now, I have to run the Dijkstra algorithm to find the shortest distance between different nodes (called attractions). I have implemented it and it's working just fine. Except that it's slow(er than I need).
I have an STL container which stores information about the nodes. I use this to perform the routing. It is given below:

//I use unordered_map for fast access of elements.
typedef std::unordered_map<unsigned int, attraction*> attractionList;
attractionList attrList;  

What I'm trying to do is once I calculate all the paths/costs of all the vertices from a certain node and store it in the attractionList container, I want to reuse this information, so that subsequent routing calls from that certain source node will be faster. For this I want to save the state of my attrList container, so I can quickly reuse the information stored. What I'm trying is something like this:

//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)); 

Well, the problem with this is obvious. When the pointers stored in the attrList change all the copies made from it are invalid. How do I store them permanently? How is the copying being done in this container? If necessary how do I overload the assignment operator? Is this even possible? I can make slight changes to my data structure and containers but not much.

Sorry for the long post. Thank you in advance.

Was it helpful?

Solution

attractionList* newList = new attractionList(); //make a new object to store old state
newList = &attrList;     //copy values from old state

Well, the problem with this is obvious. When the pointers stored in the attrList change all the copies made from it are invalid.

You didn't make a copy. You allocated a new, empty list on the heap, then you discarded your pointer to it and stored a pointer to the existing list.

I think you mean:

attractionList newList = attrList;

but I haven't reviewed the rest of your code, so that might not be a complete fix.

Regarding your comment:

If you need to copy the attractions as well, then you'll need somewhere to store them. Since you don't say how you're storing the originals I can't tell you where to store the copies, but the rest of the code will be something like this:

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));
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top