6 #include <unordered_map> 16 namespace datastructure {
110 template<
typename K,
typename E1 = K,
typename E2 = E1>
111 class GraphAdjList :
public DataStructure {
115 unordered_map<K, Element<E1>* > vertices;
117 unordered_map<K, SLelement<Edge<K, E2> >*> adj_list;
120 static const int LargeGraphVertSize = 2000;
122 bool forceLargeViz =
false;
123 bool forceSmallViz =
false;
126 GraphAdjList(
const GraphAdjList& gr) =
delete;
127 const GraphAdjList& operator= (
const GraphAdjList& gr) =
delete;
130 GraphAdjList() =
default;
131 GraphAdjList(GraphAdjList&& gr) =
default;
134 for (
auto& v : vertices) {
135 if (adj_list[v.first]) {
139 adj_list[v.first]; sle !=
nullptr; ) {
144 adj_list[v.first] =
nullptr;
146 delete vertices[v.first];
147 vertices[v.first] =
nullptr;
157 if (forceLargeViz || (!forceSmallViz &&
158 vertices.size() > LargeGraphVertSize &&
159 areAllVerticesLocated())) {
162 return "GraphAdjacencyList";
180 if (vertices.find(k) == vertices.end()) {
183 adj_list[k] =
nullptr;
200 void addEdge(
const K& src,
const K& dest,
const E2& data = E2()) {
206 vertices[src]->links[vertices.at(dest)];
213 Edge<K, E2> (src, dest, &(vertices[src]->links[vertices.at(dest)]), data), conv.str());
216 catch (
const out_of_range& ) {
217 cerr <<
"addEdge(): Nonexistent vertex?" << endl <<
218 "Create vertices first prior to adding edges that use that vertex" << endl
219 <<
"Cannot add edge between non-existent verticies" 231 bool isEdge(
const K& src,
const K& dest) {
235 for (
auto& e : outgoingEdgeSetOf(src))
236 if (e.to() == dest) {
237 cout <<
"found it!" << src <<
"," << dest << endl;
241 catch (
const out_of_range& ) {
256 return (vertices.at(src))->getValue();
258 catch (
const out_of_range& ) {
259 cerr <<
"getVertexData(): vertex not found" << endl;
263 throw "getVertexData(): vertex not found";
277 catch (
const out_of_range& ) {
278 cerr <<
"setVertexData(): Nonexistent vertex" << endl;
281 catch (
const char* msg) {
300 if (ed.
to() == dest) {
305 throw "Edge not found!";
307 catch (
const out_of_range& ) {
308 cerr <<
"getEdgeData(): Edge not found" << endl;
311 catch (
const char* msg) {
315 throw "getEdgeData(): Edge not found";
332 if (ed.getVertex() == dest) {
337 throw "Edge not found!";
339 catch (
const out_of_range& ) {
340 cerr <<
"getEdgeData(): Edge not found" << endl;
343 catch (
const char* msg) {
347 throw "getEdgeData(): Edge not found";
366 if (ed.getVertex() == dest) {
373 throw "getEdgeData(): Edge not found!";
375 catch (
const out_of_range& ) {
376 cerr <<
"setEdgeData(): Nonexistent vertices or " <<
377 " edge not found" << endl;
380 catch (
const char* msg) {
384 throw "getEdgeData(): Edge not found";
410 return vertices.at(key);
412 catch (
const std::out_of_range& oor) {
427 return vertices.at(key);
429 catch (
const std::out_of_range& oor) {
449 while (sle !=
nullptr) {
451 if (edge_dest == dest)
456 catch (
const std::out_of_range& oor) {
458 std::cout <<
"one or both vertices are likely missing from graph\n";
461 throw "Edge not found";
468 const unordered_map<K, SLelement<Edge<K, E2> >*>&
483 return adj_list.at(k);
485 catch (
const out_of_range& ) {
486 cerr <<
"Cannot get adjacencyList of a non-existent vertex -- " << k <<
"\n";
501 return adj_list.at(k);
503 catch (
const out_of_range& ) {
504 cerr <<
"Cannot getAdjacencyList() of a non-existent vertex!" 525 catch (
const out_of_range& ) {
526 cerr <<
"Graph vertex " << k <<
" not found in graph!" << endl;
542 return getEdge(k1, k2).getLinkVisualizer();
544 catch (
const out_of_range& ) {
545 cerr <<
"Either source or destination node not found in graph!\n";
555 virtual const string getDataStructureRepresentation()
const override {
565 vertices.size() > LargeGraphVertSize &&
566 areAllVerticesLocated())) {
567 return getDataStructureRepresentationLargeGraph();
570 unordered_map<K, int> node_map;
572 string nodes_JSON =
"", links_JSON =
"";
574 for (
const auto& v : vertices) {
575 if (node_map.emplace(v.first, i).second) {
577 nodes_JSON += v.second->getElementRepresentation() +
COMMA;
583 if (nodes_JSON.size()) {
584 nodes_JSON = nodes_JSON.erase(nodes_JSON.size() - 1);
589 for (
const auto& v : vertices) {
591 Element<E1>* src_vert = vertices.at(
v.first);
593 for (SLelement<Edge<K, E2>>* it = adj_list.at(
v.first); it !=
nullptr;
594 it = it->getNext()) {
595 Element<E1>* dest_vert = vertices.at(it->getValue().to() );
596 links_JSON += src_vert->getLinkRepresentation(
597 *(src_vert->getLinkVisualizer(dest_vert)),
604 if (links_JSON.size()) {
605 links_JSON = links_JSON.erase(links_JSON.size() - 1);
608 string graph_alist_json =
616 return graph_alist_json;
628 string getDataStructureRepresentationLargeGraph ()
const {
635 unordered_map<K, int> node_map;
637 string nodes_JSON =
"";
639 for (
const auto& v : vertices) {
640 if (node_map.emplace(
v.first, i).second) {
642 const ElementVisualizer *elvis =
643 vertices.at(
v.first)->getVisualizer();
645 if ( (elvis->getLocationX() != INFINITY) &&
646 (elvis->getLocationY() != INFINITY) ) {
654 elvis->getColor().getCSSRepresentation() +
661 if (nodes_JSON.size()) {
662 nodes_JSON = nodes_JSON.erase(nodes_JSON.size() - 1);
666 string links_JSON =
"";
667 for (
const auto& v : vertices) {
669 Element<E1>* src_vert = vertices.at(
v.first);
671 for (SLelement<Edge<K, E2>>* it = adj_list.at(
v.first); it !=
nullptr;
672 it = it->getNext()) {
673 Element<E1>* dest_vert = vertices.at(it->getValue().to() );
674 LinkVisualizer *lv = src_vert->getLinkVisualizer(dest_vert);
676 string dest =
JSONencode(node_map.at(it->getValue().to()));
680 lv->getColor().getCSSRepresentation() +
686 if (links_JSON.size())
687 links_JSON = links_JSON.erase(links_JSON.size() - 1);
689 string graph_alist_json =
696 return graph_alist_json;
702 bool areAllVerticesLocated()
const {
703 for (
const auto& v : vertices) {
704 ElementVisualizer *elvis =
v.second->getVisualizer();
705 if (elvis->getLocationX() == INFINITY
706 || elvis->getLocationY() == INFINITY)
733 forceLargeViz =
true;
734 forceSmallViz =
false;
737 forceLargeViz =
false;
759 forceSmallViz =
true;
760 forceLargeViz =
false;
763 forceSmallViz =
false;
771 std::unordered_map<K, Element<E1>* >
const & underlying_map;
786 return this->it != it.it;
789 const K& operator*()
const {
846 typename std::unordered_map<K, Element<E1>* > & underlying_map;
859 typename std::unordered_map<K, Element<E1>* >
::iterator it;
866 return this->it != it.it;
892 return this->it != it.it;
907 return iterator(underlying_map.begin());
911 return iterator(underlying_map.end());
939 typename std::unordered_map<K, Element<E1>* >
const & underlying_map;
955 return this->it != it.it;
VertexElementSet_listhelper vertexSet()
Definition: GraphAdjList.h:928
void forceSmallVisualization(bool f)
Force the rendering engine to use small graph visualization.
Definition: GraphAdjList.h:757
This is a helper class to return sets of vertices in a way that are iterable with range for loops....
Definition: GraphAdjList.h:858
const_iterator & operator++()
Definition: GraphAdjList.h:899
void setValue(const E &val)
Sets generic object to "val".
Definition: Element.h:229
const K & to() const
Destination vertex accessor.
Definition: Edge.h:86
This is a helper class to return sets of vertices ina way that are iterable with range for loops....
Definition: GraphAdjList.h:947
void setEdgeData(const E2 &data)
Sets edge data to "data".
Definition: Edge.h:94
ElementVisualizer * getVisualizer(const K &k)
Returns the visualizer corresponding to a graph vertex. convenient method to set attributes of the gr...
Definition: GraphAdjList.h:519
bool operator!=(const const_iterator &it) const
Definition: GraphAdjList.h:891
E2 & getEdgeData(const K &src, const K &dest)
Gets edge data for the edge from "src" to "dest".
Definition: GraphAdjList.h:293
SLelement< Edge< K, E2 > > * getAdjacencyList(const K &k)
Returns adjacency list of a vertex with name k.
Definition: GraphAdjList.h:481
iterator end()
Definition: GraphAdjList.h:910
const string COLON
Definition: DataStructure.h:51
E const & getValue() const
Gets the object held in the generic object E.
Definition: Element.h:210
iterator(typename std::unordered_map< K, Element< E1 > * >::iterator i)
Definition: GraphAdjList.h:861
constVertexElementSet_listhelper(std::unordered_map< K, Element< E1 > * > const &um)
Definition: GraphAdjList.h:942
SLelement< Edge< K, E2 > >::SLelement_listhelper outgoingEdgeSetOf(K const &k)
This method is useful for iterating through a set of outgoing edges from a vertex.
Definition: GraphAdjList.h:826
This class maintains the visual properties of the a Bridges element.
Definition: ElementVisualizer.h:31
const string OPEN_BOX
Definition: DataStructure.h:54
const_iterator end() const
Definition: GraphAdjList.h:972
const_iterator & operator++()
Definition: GraphAdjList.h:962
const_iterator(typename std::unordered_map< K, Element< E1 > * >::const_iterator i)
Definition: GraphAdjList.h:950
const_iterator begin() const
Definition: GraphAdjList.h:799
const_iterator(typename std::unordered_map< K, Element< E1 > * >::const_iterator i)
Definition: GraphAdjList.h:887
const string CLOSE_CURLY
Definition: DataStructure.h:53
Definition: GraphAdjList.h:770
const Element< E1 > * getVertex(const K &key) const
Return the vertex corresponding to a key.
Definition: GraphAdjList.h:408
const E1 & getVertexData(const K &src) &
Gets vertex data for a graph vertex.
Definition: GraphAdjList.h:253
const_iterator end() const
Definition: GraphAdjList.h:803
Element< E1 > * getVertex(const K &key)
Definition: GraphAdjList.h:425
The singly linked list element, derived from Element.
Definition: SLelement.h:27
This is a helper class to return sets of vertices in a way that are iterable with range for loops....
Definition: GraphAdjList.h:884
const_iterator end() const
Definition: GraphAdjList.h:918
void forceLargeVisualization(bool f)
Force the rendering engine to use large graph visualization.
Definition: GraphAdjList.h:731
void addVertex(const K &k, const E1 &e=E1())
Adds a vertex to the graph.
Definition: GraphAdjList.h:177
const_iterator(typename std::unordered_map< K, Element< E1 > * >::const_iterator i)
Definition: GraphAdjList.h:781
bool operator!=(const iterator &it) const
Definition: GraphAdjList.h:865
these methods convert byte arrays in to base64 codes and are used in BRIDGES to represent the color a...
Definition: alltypes.h:4
const_iterator begin() const
Definition: GraphAdjList.h:968
virtual const string getDStype() const override
Get the string representation of this data structure type.
Definition: GraphAdjList.h:156
const string CLOSE_BOX
Definition: DataStructure.h:55
bool operator!=(const const_iterator &it) const
Definition: GraphAdjList.h:954
const E2 & getEdgeData() const
Return the edge data.
Definition: Edge.h:102
bool operator!=(const const_iterator &it) const
Definition: GraphAdjList.h:785
Definition: GraphAdjList.h:778
This is a helper class to return sets of vertices in a way that are iterable with range for loops....
Definition: GraphAdjList.h:938
const_iterator begin() const
Definition: GraphAdjList.h:914
KeySet_helper(std::unordered_map< K, Element< E1 > * > const &um)
Definition: GraphAdjList.h:774
unordered_map< K, Element< E1 > * > * getVertices()
Return the graph nodes.
Definition: GraphAdjList.h:391
constVertexElementSet_listhelper vertexSet() const
Definition: GraphAdjList.h:980
Edge< K, E2 > getEdge(const K &src, const K &dest)
Get the edge between src and dest vertices.
Definition: GraphAdjList.h:443
const_iterator & operator++()
Definition: GraphAdjList.h:793
void setVertexData(const K &vertID, E1 const &data)
Loads vertex specific information for a graph vertex.
Definition: GraphAdjList.h:272
virtual SLelement * getNext()
Returns the next element in the list.
Definition: SLelement.h:75
iterator & operator++()
Definition: GraphAdjList.h:873
const unordered_map< K, Element< E1 > * > * getVertices() const
Return the graph nodes - const version.
Definition: GraphAdjList.h:400
This is a helper class to return sets of vertices in a way that are iterable with range for loops....
Definition: GraphAdjList.h:845
const SLelement< Edge< K, E2 > > * getAdjacencyList(const K &k) const
Definition: GraphAdjList.h:499
This class maintains the visual properties of links within data structures.
Definition: LinkVisualizer.h:26
VertexElementSet_listhelper(std::unordered_map< K, Element< E1 > * > &um)
Definition: GraphAdjList.h:849
KeySet_helper keySet() const
Definition: GraphAdjList.h:817
virtual ~GraphAdjList() override
Definition: GraphAdjList.h:133
ElementVisualizer * getVisualizer()
Get the element visualizer object.
Definition: Element.h:144
const string COMMA
Definition: DataStructure.h:50
iterator begin()
Definition: GraphAdjList.h:906
const string QUOTE
Definition: DataStructure.h:49
bool isEdge(const K &src, const K &dest)
Definition: GraphAdjList.h:231
const unordered_map< K, SLelement< Edge< K, E2 > > * > & getAdjacencyList() const
Return the adjacency list.
Definition: GraphAdjList.h:469
LinkVisualizer * getLinkVisualizer(const K &k1, const K &k2)
Returns the link visualizer corresponding to an edge. Returns the link visualizer corresponding to tw...
Definition: GraphAdjList.h:540
SLelement< Edge< K, E2 > >::SLelement_constlisthelper outgoingEdgeSetOf(K const &k) const
This method is useful for iterating through a set of outgoing edges from a vertex - const version.
Definition: GraphAdjList.h:835
E2 const & getEdgeData(const K &src, const K &dest) const
Gets edge data for the edge from "src" to "dest" - const version.
Definition: GraphAdjList.h:325
void addEdge(const K &src, const K &dest, const E2 &data=E2())
Definition: GraphAdjList.h:200
This helper class is used by the graph classes - GraphAdjList , GraphAdjMatrix - to keep track of edg...
Definition: Edge.h:36
void setEdgeData(const K &src, const K &dest, E2 &data)
Loads edge specific information for the edge from "src" to "dest".
Definition: GraphAdjList.h:359
std::string JSONencode(const T &d)
Definition: JSONutil.h:37