All Distance Sketch  0.1
All distance sketch based algorithms
reverse_rank.h
Go to the documentation of this file.
1 #ifndef SRC_ALGORITHMS_REVERSE_RANK_H_
2 #define SRC_ALGORITHMS_REVERSE_RANK_H_
3 
4 #include "../common.h"
5 #include "../sketch/graph_sketch.h"
6 #include "../proto/ranking.pb.h"
7 
13 namespace all_distance_sketch {
14 
15 typedef proto::NodeRanksGpb NodeRanksGpb;
16 typedef proto::NodeRankGpb NodeRankGpb;
17 
34 template <class T>
35 static void CalculateReverseRank(int source,
36  graph::Graph<T> * graph,
37  GraphSketch * graph_sketch,
38  std::vector<int> * ranking);
39 
60 template <class T, class CallBacks>
61 static void CalculateReverseRank(int source,
62  graph::Graph<T> * graph,
63  GraphSketch * graph_sketch,
64  std::vector<int> * ranking,
65  CallBacks* call_backs);
66 
69 static void SaveRankingToGpb(int source_node_id,
70  const std::vector<int>& ranking,
71  NodeRanksGpb* node_ranks) {
72  node_ranks->set_source_node_id(source_node_id);
73  node_ranks->set_max_node_id(ranking.size());
74  for (int node_id=0; node_id < ranking.size(); node_id++) {
75  if (ranking[node_id] == constants::UNREACHABLE) {
76  continue;
77  }
78  NodeRankGpb* node_rank = node_ranks->add_node_ranks();
79  node_rank->set_node_id(node_id);
80  node_rank->set_node_rank(ranking[node_id]);
81  }
82 }
83 
84 static void LoadRankingFromGpb(std::vector<int>* ranking,
85  const NodeRanksGpb& node_ranks) {
86  ranking->clear();
87  ranking->resize(node_ranks.max_node_id());
88  for (int i=0; i < node_ranks.node_ranks_size(); i++) {
89  int node_id = node_ranks.node_ranks(i).node_id();
90  int node_ranking = node_ranks.node_ranks(i).node_rank();
91  (*ranking)[node_id] = node_ranking;
92  }
93  int source_node_id = node_ranks.source_node_id();
94  (*ranking)[source_node_id] = 0;
95 }
96 
99 template <class T>
100 static int EstimateReverseRankUpperBound(graph::Graph<T> * graph,
101  GraphSketch * graph_sketch,
102  int source,
103  int target,
104  graph::EdgeWeight distance_from_source_to_targer);
105 
106 
107 struct RankData {
108  RankData(int _node_id, int _rank, graph::EdgeWeight _distance) :
109  node_id(_node_id), rank(_rank), distance(_distance) {}
110  RankData() : node_id(-1), rank(-1), distance(constants::UNREACHABLE) { }
111  int node_id;
112  int rank;
113  graph::EdgeWeight distance;
114 };
115 
116 struct compareRankNode {
117  bool operator()(const RankData& n1, const RankData& n2) const {
118  // return n1.rank > n2.rank;
119  if (n1.rank < n2.rank) {
120  return true;
121  }
122  if (n1.rank > n2.rank) {
123  return false;
124  }
125  if (n1.distance < n2.distance) {
126  return true;
127  }
128  if (n1.distance > n2.distance) {
129  return false;
130  }
131  if (n1.node_id < n2.node_id) {
132  return true;
133  }
134  return false;
135  }
136 };
137 
138 template <class T>
139 static int EstimateReverseRankUpperBound(graph::Graph<T> * graph,
140  GraphSketch * graph_sketch,
141  int source,
142  int target,
143  graph::EdgeWeight distance_from_source_to_targer) {
144  if (source == target) {
145  LOG_M(DEBUG4, " Source node is equal to target");
146  return 0;
147  }
148  NodeIdRandomIdData source_node_details(source, graph_sketch->GetNodeRandomId(source));
149  NodeSketch * sourceNodeAds = graph_sketch->GetNodeSketch(source_node_details);
150  int reverse_rank = sourceNodeAds->GetSizeNeighborhoodUpToDistance(distance_from_source_to_targer);
151  LOG_M(DEBUG3, " Source=" << source <<
152  " node=" << target <<
153  " distance= " << distance_from_source_to_targer <<
154  " reverse_rank=" << reverse_rank <<
155  " Node degree=" << graph->GetNI(source).GetOutDeg());
156  return reverse_rank;
157 }
158 
159 
160 template <class T>
161 static double EstimateReverseRankAverage(graph::Graph<T> * graph,
162  GraphSketch * graph_sketch,
163  int source,
164  int target,
165  graph::EdgeWeight distance_from_source_to_target) {
166  if (source == target) {
167  LOG_M(DEBUG4, " Source node is equal to target");
168  return 0;
169  }
170  NodeIdRandomIdData source_node_details(source, graph_sketch->GetNodeRandomId(source));
171  NodeSketch * sourceNodeAds = graph_sketch->GetNodeSketch(source_node_details);
172  int distance_index = sourceNodeAds->GetNeighborhoodDistanceIndex(distance_from_source_to_target);
173  if (distance_index == -1) {
174  return 0;
175  }
176  int n_size_up = sourceNodeAds->GetNeighborhoodDistanceByIndex(distance_index);
177  int n_size_down = sourceNodeAds->GetNeighborhoodDistanceByIndex(distance_index - 1);
178  LOG_M(DEBUG3, " Source=" << source <<
179  " node=" << target <<
180  " distance= " << distance_from_source_to_target <<
181  " n_size_up=" << n_size_up <<
182  " n_size_down=" << n_size_down <<
183  " index=" << distance_index);
184 
185  double reverse_rank = static_cast<double>(n_size_up + n_size_down + 1) / static_cast<double>(2);
186  return reverse_rank;
187 }
188 
189 
190 template<class T>
191 class DefaultReverseRankCallBacks {
192  public:
193  inline void Started(int source_node_id, graph::Graph<T>* graph) { return; }
194 
195  inline void NodePopedFromHeap(int poped_node_id, const RankData& heap_value) { return; }
196 
197  inline bool ShouldPrune(int visited_node_id, const RankData& rank_data) { return false; }
198 
199  inline bool ShouldStop() { return false; }
200 
201  inline void RelaxedPath(int node_id) { }
202 };
203 
204 
205 template <class T>
206 static void CalculateReverseRank(int source,
207  graph::Graph<T> * graph,
208  GraphSketch * graph_sketch,
209  std::vector<int> * ranking) {
210  DefaultReverseRankCallBacks<T> default_reverse_rank_call_backs;
211  CalculateReverseRank(source, graph, graph_sketch, ranking, &default_reverse_rank_call_backs);
212 }
213 
214 template <class T, class CallBacks>
215 static void CalculateReverseRank(int source_node_id,
216  graph::Graph<T> * graph,
217  GraphSketch * graph_sketch,
218  std::vector<int> * ranking,
219  CallBacks* call_backs) {
220  int max_node_id = graph->GetMxNId();
221  ranking->clear();
222  ranking->resize(max_node_id, constants::UNREACHABLE);
223  (*ranking)[source_node_id] = 0;
224  TBitSet poped; poped.resize(max_node_id);
225  TBitSet touced; touced.resize(max_node_id);
226  std::vector<graph::EdgeWeight> min_distance;
227  min_distance.resize(max_node_id, constants::UNREACHABLE);
228  min_distance[source_node_id] = 0;
229  std::set< RankData, compareRankNode > heap;
230  touced[source_node_id] = true;
231  heap.insert(RankData(source_node_id, (*ranking)[source_node_id], 0));
232 
233  LOG_M(DEBUG3, "Starting Reverse rank from node=" << source_node_id);
234  call_backs->Started(source_node_id, graph);
235  double rank_last = 0;
236  while (!heap.empty()) {
237  // Get the node with the minimum rank
238  int visited_node_id = heap.begin()->node_id;
239  auto node_data = *heap.begin();
240  graph::EdgeWeight distance_from_source_to_visited_node = node_data.distance;
241  (*ranking)[visited_node_id] = node_data.rank;
242  call_backs->NodePopedFromHeap(visited_node_id, node_data);
243  LOG_M(DEBUG3, "Poped node=" << visited_node_id << " Distance=" << node_data.distance <<
244  " Rank=" << node_data.rank);
245  assert(rank_last <= node_data.rank);
246  rank_last = node_data.rank;
247  _unused(rank_last);
248  heap.erase(heap.begin());
249  poped[visited_node_id] = true;
250  if (call_backs->ShouldPrune(visited_node_id, node_data)) {
251  continue;
252  }
253 
254  if (call_backs->ShouldStop()) {
255  return;
256  }
257 
258  // Visit each edge exiting visited_node_id
259  graph::TEdgesWeights * nodeWeights = graph->GetNodeWeights(visited_node_id);
260  typename T::TNodeI neighbors = graph->GetNI(visited_node_id);
261  for (int i = 0 ; i < neighbors.GetOutDeg(); i++) {
262  int id_of_neighbor_of_visited_node = neighbors.GetOutNId(i);
263  LOG_M(DEBUG3, "neighbors node=" << id_of_neighbor_of_visited_node);
264  if (poped[id_of_neighbor_of_visited_node]) {
265  continue;
266  }
267  std::pair<bool, graph::EdgeWeight> edge_u_v = graph->GetEdgeWeight(visited_node_id, id_of_neighbor_of_visited_node);
268  graph::EdgeWeight distance_through_u = distance_from_source_to_visited_node + edge_u_v.second; // (*nodeWeights)[i].weight;
269  LOG_M(DEBUG3, "edge weight between " <<
270  " visited_node_id = " << visited_node_id <<
271  " id_of_neighbor_of_visited_node = " << id_of_neighbor_of_visited_node <<
272  " edge weight = " << (*nodeWeights)[i].get_edge_weight() <<
273  " Distance before relax=" << distance_from_source_to_visited_node <<
274  " distance through visited_node_id=" << distance_through_u);
275 
276  if (touced[id_of_neighbor_of_visited_node] == false || distance_through_u < min_distance[id_of_neighbor_of_visited_node]) {
277  int rankOfSourceNode = EstimateReverseRankUpperBound<T>(graph,
278  graph_sketch,
279  id_of_neighbor_of_visited_node,
280  source_node_id,
281  distance_through_u);
282 
283  if (touced[id_of_neighbor_of_visited_node] == false) {
284  LOG_M(DEBUG3, "Inserting node " << id_of_neighbor_of_visited_node <<
285  " to heap with distance " << distance_through_u);
286  heap.insert(RankData(id_of_neighbor_of_visited_node, rankOfSourceNode, distance_through_u));
287  } else {
288  LOG_M(DEBUG3, "Decreasing distance of node " << id_of_neighbor_of_visited_node <<
289  " from " << min_distance[id_of_neighbor_of_visited_node] <<
290  " to " << distance_through_u);
291  heap.erase(RankData(id_of_neighbor_of_visited_node, (*ranking)[id_of_neighbor_of_visited_node], min_distance[id_of_neighbor_of_visited_node]));
292  heap.insert(RankData(id_of_neighbor_of_visited_node, rankOfSourceNode, distance_through_u));
293  }
294  LOG_M(DEBUG5, "Updating rank of node " << id_of_neighbor_of_visited_node <<
295  " rank=" << rankOfSourceNode <<
296  " old rank=" << (*ranking)[id_of_neighbor_of_visited_node]);
297  touced[id_of_neighbor_of_visited_node] = true;
298  min_distance[id_of_neighbor_of_visited_node] = distance_through_u;
299  (*ranking)[id_of_neighbor_of_visited_node] = rankOfSourceNode;
300  }
301  }
302  }
303 }
310 }; // namespace all_distance_sketch
311 #endif // SRC_ALGORITHMS_REVERSE_RANK_H_
Single node sketch.
Definition: node_sketch.h:204
Definition: common.h:53
static void SaveRankingToGpb(int source_node_id, const std::vector< int > &ranking, NodeRanksGpb *node_ranks)
saves the ranking to Gpb
Definition: reverse_rank.h:69
Graph data structure Thin wrapper over SNAP graph.
Definition: graph.h:107
RandomId GetNodeRandomId(const int &node_id)
returns specific node random id
Definition: graph_sketch.h:371
static void CalculateReverseRank(int source, graph::Graph< T > *graph, GraphSketch *graph_sketch, std::vector< int > *ranking)
Calculates the reverse ranks of a single node.
const float UNREACHABLE
Definition: common.h:62
Data structure for the graph sketch.
Definition: graph_sketch.h:17