All Distance Sketch  0.1
All distance sketch based algorithms
graph.h
Go to the documentation of this file.
1 #ifndef SRC_GRAPH_GRAPH_H_
2 #define SRC_GRAPH_GRAPH_H_
3 
4 #include "../common.h"
5 #include "../utils/utils.h"
6 
11 namespace all_distance_sketch {
12 namespace graph {
13 
14 struct EdgeDetails {
15  EdgeDetails(EdgeWeight edge_weight, int node_id) :
16  edge_weight_(edge_weight), node_id_(node_id) {}
17 
18  inline bool operator<(const EdgeDetails other) const {
19  return other.node_id_ > node_id_;
20  }
21 
22  inline int get_node_id() const { return node_id_; }
23  inline EdgeWeight get_edge_weight() const { return edge_weight_; }
24  inline void set_edge_weight(EdgeWeight weight) { edge_weight_ = weight; }
25  EdgeWeight edge_weight_;
26  int node_id_;
27 };
28 
29 typedef std::vector<EdgeDetails> TEdgesWeights;
30 typedef std::vector<TEdgesWeights> TWeights;
31 
32 struct WeightMap {
33  void SetDirected() { is_directed_ = true;}
34  void SetUnDirected() { is_directed_ = false;}
35 
36  bool AddEdge(int source_node_id, int dest_node_id, EdgeWeight weight) {
37  if (is_directed_) {
38  return _AddEdge(source_node_id, dest_node_id, weight);
39  } else {
40  return (_AddEdge(source_node_id, dest_node_id, weight) || _AddEdge(dest_node_id, source_node_id, weight));
41  }
42  }
43 
44  bool _AddEdge(int source_node_id, int dest_node_id, EdgeWeight weight) {
45  if (weights_.size() <= (unsigned int)source_node_id) {
46  weights_.resize(source_node_id + 1);
47  }
48 
49  EdgeDetails details(weight, dest_node_id);
50  TEdgesWeights::iterator it = \
51  std::lower_bound( weights_[source_node_id].begin(), weights_[source_node_id].end(), details);
52  if (it != weights_[source_node_id].end() && it->get_node_id() == dest_node_id) {
53  it->set_edge_weight(weight);
54  return true;
55  }
56 
57  weights_[source_node_id].insert(it, details);
58  return false;
59  }
60 
61  TEdgesWeights * GetNodeWeights(int aNode) {
62  if (aNode >= weights_.size()) {
63  return NULL;
64  }
65  return &(weights_[aNode]);
66  }
67 
68  bool GetEdgeWeight(int source_node_id, int dest_node_id, EdgeWeight * result_edge_weight) {
69  int temp_node_1 = source_node_id;
70  int temp_node_2 = dest_node_id;
71  if (is_directed_ == false) {
72  temp_node_1 = source_node_id < dest_node_id ? source_node_id : dest_node_id;
73  temp_node_2 = source_node_id > dest_node_id ? source_node_id : dest_node_id;
74  }
75 
76  source_node_id = temp_node_1;
77  dest_node_id = temp_node_2;
78  if (weights_.size() <= (unsigned int)source_node_id) {
79  *result_edge_weight = constants::UNREACHABLE;
80  return false;
81  }
82 
83  EdgeDetails details(0, dest_node_id);
84  TEdgesWeights::iterator it = std::lower_bound( weights_[source_node_id].begin(), weights_[source_node_id].end(), details);
85  if (it != weights_[source_node_id].end() && it->get_node_id() == dest_node_id) {
86  *result_edge_weight = it->get_edge_weight();
87  return true;
88  }
89 
90  *result_edge_weight = constants::UNREACHABLE;
91  return false;
92  }
93  public:
94  TWeights weights_;
95  bool is_directed_;
96 };
97 
98 template <class K>
99 struct GraphTrait {
100  static const bool directed = false;
101 };
102 
106 template <class T>
107 class Graph {
108  public:
109  Graph() {
110  if (GraphTrait<T>::directed){
111  weight_map_.SetDirected();
112  } else {
113  weight_map_.SetUnDirected();
114  }
115  }
116 
117  int AddNode(int node_id) {
118  return graph_.AddNode(node_id);
119  }
120 
121  int AddEdge(const int& aSrcNId, const int& aDstNId, int weight = 1) {
122  int edgeId = graph_.AddEdge(aSrcNId, aDstNId);
123  if (edgeId == -1) {
124  LOG_M(DEBUG5, "Inserting edge, source node=" << aSrcNId
125  << " dest node=" << aDstNId
126  << " weight=" << weight);
127  weight_map_.AddEdge(aSrcNId, aDstNId, weight);
128  }
129  return edgeId;
130  }
131 
132  std::pair<bool, EdgeWeight> GetEdgeWeight(const int& aSrcNId, const int& aDstNId) {
133  bool wasFound = false;
134  EdgeWeight w = constants::UNREACHABLE;
135  wasFound = weight_map_.GetEdgeWeight(aSrcNId, aDstNId, &w);
136  std::pair<bool, EdgeWeight> result(wasFound, w);
137  return result;
138  }
139 
140  TEdgesWeights * GetNodeWeights(int aNode) {
141  return weight_map_.GetNodeWeights(aNode);
142  }
143 
144  typename T::TNodeI BegNI() {
145  return graph_.BegNI();
146  }
147 
148  typename T::TNodeI EndNI() {
149  return graph_.EndNI();
150  }
151 
152  bool IsEdge(const int& aSrcNId, const int& aDstNId) const {
153  return graph_.IsEdge(aSrcNId, aDstNId);
154  }
155 
156  bool IsNode(const int& node_id) const {
157  return graph_.IsNode(node_id);
158  }
159 
160  int GetNumNodes() const {
161  return graph_.GetNodes();
162  }
163 
164  int GetNumEdges() const {
165  return graph_.GetEdges();
166  }
169  WeightMap * utGeWeightMap() {
170  return &weight_map_;
171  }
174  typename T::TNodeI GetNI(const int& node_id) const {
175  return graph_.GetNI(node_id);
176  }
177 
178  int GetMxNId() const {
179  return graph_.GetMxNId();
180  }
184  void Transpose(Graph<T> * transpose) {
185  for (auto node_itr = this->BegNI(); node_itr != this->EndNI() /* node_itr.HasMore()*/ ; node_itr++) {
186  transpose->AddNode(node_itr.GetId());
187  }
188  for (int node_id = 0; node_id < weight_map_.weights_.size(); ++node_id) {
189  for (auto node_it = weight_map_.weights_[node_id].begin(); node_it != weight_map_.weights_[node_id].end(); ++node_it){
190  transpose->AddEdge(node_it->get_node_id() , node_id, node_it->get_edge_weight());
191  }
192  }
193  }
207  void LoadGraphFromDir(std::string aPath, bool aTranspose = false) {
208  utils::FileUtils::NodePairList nodePairList;
209  utils::FileUtils::GetNodePairListFromDir(aPath, &nodePairList);
210  for (utils::FileUtils::NodePairList::iterator itr = nodePairList.begin(); itr != nodePairList.end(); ++itr) {
211  int uNodeId = itr->first;
212  LOG_M(DEBUG5, "Found node " << uNodeId);
213  if (IsNode(uNodeId) == false) {
214  LOG_M(DEBUG5, "inserting node " << uNodeId << " it does not exists");
215  AddNode(uNodeId);
216  }
217  int vNodeId = itr->second;
218  LOG_M(DEBUG5, "Found node " << vNodeId);
219  if (IsNode(vNodeId) == false) {
220  LOG_M(DEBUG5, "Inserting node " << vNodeId << " it does not exists");
221  AddNode(vNodeId);
222  }
223  LOG_M(DEBUG1, "Node src " << uNodeId << " Node dest " << vNodeId);
224  if (aTranspose == false) {
225  AddEdge(uNodeId, vNodeId);
226  } else {
227  AddEdge(vNodeId, uNodeId);
228  }
229  }
230  }
231 
234  WeightMap weight_map_;
235  T graph_;
238 };
239 
240 } // namespace graph
241 
245 } // namespace all_distance_sketch
246 
247 #endif // SRC_GRAPH_GRAPH_H_
Definition: common.h:53
Graph data structure Thin wrapper over SNAP graph.
Definition: graph.h:107
void LoadGraphFromDir(std::string aPath, bool aTranspose=false)
Loads the graph from files located in a dir.
Definition: graph.h:207
const float UNREACHABLE
Definition: common.h:62
void Transpose(Graph< T > *transpose)
Changes the direction of all edges For undirected graph this has no effect.
Definition: graph.h:184