Bridges-C++  3.2.0
Bridges(C++API)
GraphAdjMatrix.h
Go to the documentation of this file.
1 #ifndef GRAPH_ADJ_MATRIX_H
2 #define GRAPH_ADJ_MATRIX_H
3 
4 #include <stdexcept> //out of range
5 #include <sstream> //stringstream
6 
7 #include "Element.h" //DataStructure, unordered_map, string, cerr, using std
8 
9 namespace bridges {
10  namespace datastructure {
36  template <typename K, typename E1 = K, typename E2 = E1>
37  class GraphAdjMatrix : public DataStructure {
38  private:
39  unordered_map<K, Element<E1>* > vertices; // graph vertices
40  unordered_map<K, unordered_map<K, int> > matrix; // adjacency matrix
41  // maintain edge specific data
42  unordered_map<K, unordered_map<K, E2> > edge_data;
43 
44  public:
48  virtual const string getDStype() const override {
49  return "GraphAdjacencyMatrix";
50  }
51 
59  void addVertex(const K& k, const E1& e = E1()) {
60  stringstream conv;
61  conv << k; //Converts key into string
62  vertices[k] = new Element<E1>(e, conv.str());
63  for (const auto& p : vertices) {
64  // edge weights are 0
65  matrix[k][p.first] = matrix[p.first][k] = 0;
66  }
67  }
68 
79  void addEdge(const K& src, const K& dest, const unsigned int& wt) {
80  try { //create default link data
81  vertices.at(src)->links[vertices.at(dest)];
82  // add edge
83  matrix.at(src).at(dest) = wt;
84  }
85  catch (const out_of_range& ) {
86  cerr << "Cannot addEdge between non-existent verticies." << endl;
87  throw;
88  }
89  }
94  const unordered_map<K, unordered_map<K, int>>& getMatrix() const {
95  return matrix;
96  }
97 
107  const unordered_map<K, int>& getMatrix(K key) const {
108  return matrix.at(key);
109  }
110 
115  unordered_map<K, Element<E1> *>* getVertices() {
116  return &vertices;
117  }
122  const Element<E1>* getVertex(const K& key) const {
123  return vertices.at(key);
124  }
125 
131  Element<E1>* getVertex(const K& key) {
132  return vertices.at(key);
133  }
141  E1 getVertexData (const K& src) {
142  try {
143  Element<E1> *el = vertices.at(src);
144  return (vertices.at(src))->getValue();
145  }
146  catch ( const out_of_range& ) {
147  cerr << "getVertexData(): vertex not found" << endl;
148  throw;
149  }
150  // should never reach here
151  throw "getVertexData(): vertex not found";
152  }
159  void setVertexData (const K& vID, const E1& data) {
160  try {
161  Element<E1> *el = vertices.at(vID);
162  el->setValue (data);
163  }
164  catch ( const out_of_range& ) {
165  cerr << "setVertexData(): Nonexistent vertices or " <<
166  " edge not found" << endl;
167  throw;
168  }
169  catch (const char* msg) {
170  cerr << msg << endl;
171  }
172  }
181  E2 const & getEdgeData (const K& src, const K& dest) const {
182  try {
183  vertices.at(src);
184  vertices.at(dest);
185  return edge_data[src][dest];
186  }
187  catch ( const out_of_range& oor) {
188  cerr << "getEdgeData(): Nonexistent vertices or " <<
189  " edge not found" << endl;
190  throw;
191  }
192  catch (const char* msg) {
193  cerr << msg << endl;
194  throw;
195  }
196  // should never reach here
197  throw "getEdgeData(): Edge not found";
198  }
206  void setEdgeData (const K& src, const K& dest, const E2& data) {
207  try {
208  vertices.at(src);
209  vertices.at(dest);
210  edge_data[src][dest] = data;
211  }
212  catch ( const out_of_range& oor) {
213  cerr << "setEdgeData(): Nonexistent vertices or " <<
214  " edge not found" << endl;
215  throw;
216  }
217  catch (const char* msg) {
218  cerr << msg << endl;
219  throw;
220  }
221  }
231  try {
232  Element<E1> *el = vertices.at(k);
233 
234  return el->getVisualizer();
235  }
236  catch (const out_of_range& oor) {
237  cerr << "Graph vertex " << k << " not found in graph!" << endl;
238  throw;
239  }
240  }
250  LinkVisualizer *getLinkVisualizer (const K& k1, const K& k2) {
251  try {
252  Element<E1> *el1 = vertices.at(k1);
253  Element<E1> *el2 = vertices.at(k2);
254 
255  return el1->getLinkVisualizer(el2);
256  }
257  catch (const out_of_range& oor) {
258  cerr << "Either source or destination node not found in graph!"
259  << endl;
260  throw;
261  }
262  }
263 
264  private:
265 
271  virtual const string getDataStructureRepresentation() const override {
273 
274  // map the nodes to a sequence of ids, 0...N-1
275  // then get the JSON string for nodes placeholder
276  // nullptr prevents insertion of other nullptrs
277 
278  unordered_map<K, int> node_map;
279  int i = 0;
280  string nodes_JSON = "", links_JSON = "";
281 
282  for (const auto& v : this->vertices) {
283  if (node_map.emplace(v.first, i).second) {
284  i++;
285  nodes_JSON += v.second->getElementRepresentation() + COMMA;
286  }
287  }
288 
289  //Remove trailing comma and nullptr entry
290 
291  if (nodes_JSON.size()) {
292  nodes_JSON = nodes_JSON.erase(nodes_JSON.size() - 1);
293  }
294 
295  // iterate through the N squared entries vertices and form the links JSON
296 
297  for (const auto& src : vertices) {
298  for (const auto& dest : vertices) {
299  if (matrix.at(src.first).at(dest.first)) { // link exists
300  Element<E1>* src_v = vertices.at(src.first);
301  Element<E1>* dest_v = vertices.at(dest.first);
302  links_JSON += src_v->getLinkRepresentation(
303  *(src_v->getLinkVisualizer(dest_v)),
304  JSONencode(node_map.at(src.first)),
305  JSONencode(node_map.at(dest.first))) + COMMA;
306  }
307  }
308  }
309 
310  //Remove trailing comma
311  if (links_JSON.size()) {
312  links_JSON = links_JSON.erase(links_JSON.size() - 1);
313  }
314 
315  string graph_amatrix_json =
316  QUOTE + "nodes" + QUOTE + COLON +
317  OPEN_BOX + nodes_JSON + CLOSE_BOX + COMMA +
318  QUOTE + "links" + QUOTE + COLON + OPEN_BOX +
319  links_JSON + CLOSE_BOX +
320  CLOSE_CURLY;
321 
322  return graph_amatrix_json;
323  }
324  }; //end of GraphAdjList class
325  }
326 }//end of bridges namespace
327 #endif
const Element< E1 > * getVertex(const K &key) const
Definition: GraphAdjMatrix.h:122
void setValue(const E &val)
Sets generic object to "val".
Definition: Element.h:229
static const string getLinkRepresentation(const LinkVisualizer &lv, const string &src, const string &dest)
Definition: Element.h:273
LinkVisualizer * getLinkVisualizer(const K &k1, const K &k2)
Definition: GraphAdjMatrix.h:250
const string COLON
Definition: DataStructure.h:51
const unordered_map< K, int > & getMatrix(K key) const
Definition: GraphAdjMatrix.h:107
This class maintains the visual properties of the a Bridges element.
Definition: ElementVisualizer.h:31
const string OPEN_BOX
Definition: DataStructure.h:54
const string CLOSE_CURLY
Definition: DataStructure.h:53
ElementVisualizer * getVisualizer(const K &k)
Definition: GraphAdjMatrix.h:230
these methods convert byte arrays in to base64 codes and are used in BRIDGES to represent the color a...
Definition: alltypes.h:4
E2 const & getEdgeData(const K &src, const K &dest) const
Definition: GraphAdjMatrix.h:181
const string CLOSE_BOX
Definition: DataStructure.h:55
unordered_map< K, Element< E1 > * > * getVertices()
Definition: GraphAdjMatrix.h:115
virtual const string getDStype() const override
Definition: GraphAdjMatrix.h:48
void setEdgeData(const K &src, const K &dest, const E2 &data)
Loads edge information.
Definition: GraphAdjMatrix.h:206
E1 getVertexData(const K &src)
Definition: GraphAdjMatrix.h:141
ElementVisualizer * getVisualizer()
Get the element visualizer object.
Definition: Element.h:144
const string COMMA
Definition: DataStructure.h:50
const unordered_map< K, unordered_map< K, int > > & getMatrix() const
Definition: GraphAdjMatrix.h:94
void addEdge(const K &src, const K &dest, const unsigned int &wt)
Definition: GraphAdjMatrix.h:79
void setVertexData(const K &vID, const E1 &data)
Definition: GraphAdjMatrix.h:159
const string QUOTE
Definition: DataStructure.h:49
void addVertex(const K &k, const E1 &e=E1())
Definition: GraphAdjMatrix.h:59
Element< E1 > * getVertex(const K &key)
Definition: GraphAdjMatrix.h:131
std::string JSONencode(const T &d)
Definition: JSONutil.h:37
LinkVisualizer * getLinkVisualizer(const Element *el)
Returns the LinkVisualizer of element.
Definition: Element.h:165