I am working on implementing a graph to solve shortest path between two vertices using Dijkstra's algorithm. Trying to keep it at least somewhat efficient because I know there are some time constraints on how long I have to find shortest path for 100 pairs of actors/actresses.
I am limited to just using the data structures from the STL. I spent some time in the lab today with my TA designing everything on paper and thought about having both a vertex and edge class. I also thought of making an actual graph class that could speed up searching by using unordered_maps.
What I am a little unsure about is the efficiency of this design. I know unordered_maps are really fast so I was hoping to take advantage of the \$O(1)\$ find time. It's not really \$O(1)\$ I think because, even though the unordered_map will give me a the movie vector or actor vector in \$O(1)\$ time, I potentially have to search that entire vector for the actor or movie I am searching for. (Though those vectors aren't going to be incredibly long. They just contain the cast of a single movie or a single actor's list of movies they have been in.)
I know I want to use the speed of an unordered_map, but the way I am currently designing this feels like I am actually not taking advantage of the unordered_map really. Why? Because I feel like I could do everything I just described without the Graph class by just using ActorNodes along with their vectors of Movie pointers and Movie objects along with their vectors of ActorNode pointers. I could do exactly what I want to do with the unordered_maps already and it sounds like it would be just as efficient as the way I am thinking of with unordered_maps. That makes me feel like I am missing something and am designing this incorrectly.
The problem I am solving is I have 1 minute to find the shortest path between 100 pairs of actors in a pretty large graph (where the edges of my graph represent a movie those two actors were in together) using Dijkstra's algorithm. The graph can be either weighted or unweighted. Weight is determined by: 1+(2015-(the year the movie was made)).
#include<vector>
#include<unordered_map>
#include<iostream>
#include<queue>
#include<string>
/* OBJECT ORIENTED DESIGN
*
* (Graph)1 <----------> n(Actor object)
* 1 n
* \ /\
* \ |
* \ |
* \ |
* \ \/
* \ n
* n(Movie object)
*/
/* THE IDEA:
* Represent a graph with two unordered maps. One to hold all the
* actorNodes of a graph and a vector of pointers to movies that particular actor is in
* as well as an unordered_map of movies with a vector of pointers to actors that are in
* that particular movie. I believe doing this will accurately represent a graph.
*/
class Movie; // forward declaration to shut compiler up.
class ActorNode; // forward declaration to shut compiler up.
/* Graph object that holds all ActorNodes and Movies */
class Graph {
private:
/*Member Variables*/
std::unordered_map<std::string,std::vector<Movie*>> vertices;
std::unordered_map<std::string,std::vector<ActorNode*>> edges;
public:
/*Constructor*/
Graph() {}
/*Destructor*/
~Graph();
/*Member Functions*/
}
};
/* (Vertex) Object Class to represent actors */
class ActorNode {
//can be converted to struct instead of class??
private:
/*Member Variables*/
std::string name;
std::vector<Movie*> movies;
public:
/*Constructor*/
ActorNode() : name("") {}
/*Getters and Setters*/
std::string getName();
void setName(std::string actor);
std::vector<Movie*> getMovies();
/*Member Functions*/
};
/* Object class to hold movies. Edges? */
class Movie {
//can be converted to struct instead of class?
private:
std::string movie;
int year;
int weight;
std::vector<ActorNode*> cast;
public:
/*Constructor*/
Movie() : movie(""), year(1), weight(1) {}
/*Getters and Setters*/
std::string getMovie();
void setMovie(std::string movie);
int getYear();
I void setYear(int yr);
int getWeight();
void setWeight(int wt);
std::vector<ActorNode*> getCast();
/*Member Functions*/
};
std::unordered_set<Actor>. EachActorcontains a vector ofActor*(links). Each link represents a film the actors have in common. The use ofunordered_setrather thansetis good when building the graph (traversal will finding should be trivial). \$\endgroup\$