KShortestPaths4.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556
  1. //
  2. // Created by wrede on 24.06.16.
  3. //
  4. #include <boost/graph/named_function_params.hpp>
  5. #include <boost/graph/bellman_ford_shortest_paths.hpp>
  6. #include <boost/graph/copy.hpp>
  7. #include "KShortestPaths4.h"
  8. #include <iomanip>
  9. #define DEBUG
  10. namespace algo
  11. {
  12. KShortestPaths4::KShortestPaths4(DirectedGraph graph, Vertex source, Vertex sink,
  13. size_t max_paths_count)
  14. {
  15. graph_ = graph;
  16. source_ = source;
  17. sink_ = sink;
  18. // vertex_labels_ = VertexDistanceMap();
  19. // vertex_distances_ = VertexDistanceMap();
  20. // vertex_weights_ = VertexDistanceMap();
  21. // vertex_predecessors_ = VertexVertexMap();
  22. // vertex_candidates_ = std::vector<Vertex>();
  23. //
  24. // i_shortest_paths_ = std::vector<VertexVertexMap>();
  25. max_paths_count_ = max_paths_count;
  26. total_paths_count_ = 0;
  27. total_paths_distance_ = 0.0;
  28. }
  29. void KShortestPaths4::Run()
  30. {
  31. Initialization();
  32. }
  33. void KShortestPaths4::Initialization()
  34. {
  35. boost::graph_traits<DirectedGraph>::vertex_iterator vi, vi_end;
  36. boost::graph_traits<DirectedGraph>::edge_iterator ei, ei_end;
  37. // Clear previous data
  38. vertex_labels_.clear();
  39. vertex_distances_.clear();
  40. vertex_candidates_.clear();
  41. interlacing_predecessors_.clear();
  42. interlacing_predecessors_positive_.clear();
  43. source_neighbors_.clear();
  44. sink_neighbors_.clear();
  45. path_predecessors_.clear();
  46. // Find the first path with predecessors and distances
  47. size_t graph_size = boost::num_vertices(graph_);
  48. std::vector<Vertex> pred_list(graph_size);
  49. std::vector<double> dist_list(graph_size);
  50. VertexIndexMap graph_indices = boost::get(boost::vertex_index, graph_);
  51. EdgeWeightMap weight_map = boost::get(boost::edge_weight, graph_);
  52. PredecessorMap path_pred_map(&pred_list[0], graph_indices);
  53. DistanceMap path_dist_map(&dist_list[0], graph_indices);
  54. boost::bellman_ford_shortest_paths(graph_, graph_size,
  55. boost::root_vertex(source_)
  56. .weight_map(weight_map)
  57. .predecessor_map(path_pred_map)
  58. .distance_map(path_dist_map));
  59. double path_total_distance = path_dist_map[sink_];
  60. //TODO check if the path is node simple
  61. // Store the vertex of the path that is the predecessor of the sink
  62. sink_neighbors_.push_back(path_pred_map[sink_]);
  63. // Add the path
  64. for (Vertex u = sink_neighbors_[0], v = path_pred_map[u]; u != source_; u = v, v = path_pred_map[v])
  65. {
  66. path_predecessors_[u] = v;
  67. }
  68. // Store the vertex of the path that is the successor of the source
  69. source_neighbors_.push_back(FindPathSuccessor(path_predecessors_, source_, sink_neighbors_[0], source_));
  70. total_paths_count_ = 1;
  71. total_paths_distance_ = path_total_distance;
  72. // If only one path is needed the algorithm can terminate successfully
  73. if (max_paths_count_ <= 1)
  74. {
  75. FeasibleTermination();
  76. return;
  77. }
  78. // Set the distance labels for all vertices
  79. for (boost::tie(vi, vi_end) = boost::vertices(graph_); vi != vi_end; ++vi)
  80. {
  81. double distance = path_dist_map[*vi];
  82. // If the vertex is not part of the spanning tree, or the distance is greater then the total distance,
  83. if (distance > path_total_distance || (path_pred_map[*vi] == *vi && *vi != source_))
  84. {
  85. distance = path_total_distance;
  86. }
  87. vertex_labels_[*vi] = distance;
  88. }
  89. // Define the candidate list
  90. SetCandidates();
  91. InterlacingConstruction();
  92. }
  93. void KShortestPaths4::InterlacingConstruction()
  94. {
  95. while (true)
  96. {
  97. #ifdef DEBUG
  98. for (auto const &v : vertex_candidates_)
  99. {
  100. double distance = vertex_distances_[v];
  101. if (distance != std::numeric_limits<double>::max())
  102. {
  103. std::cout << "(" << v << "," << vertex_distances_[v] << ","
  104. << (interlacing_predecessors_positive_[v] ? "" : "-")
  105. << interlacing_predecessors_[v] << ")";
  106. }
  107. }
  108. std::cout << std::endl;
  109. #endif
  110. // Find the vertex in the candidate list with the minimum distance
  111. Vertex min_distance_vertex = 0;
  112. double min_distance = std::numeric_limits<double>::max();
  113. for (size_t i = 0; i < vertex_candidates_.size(); ++i)
  114. {
  115. Vertex v = vertex_candidates_[i];
  116. double distance = vertex_distances_[v];
  117. if (distance < min_distance)
  118. {
  119. min_distance_vertex = v;
  120. min_distance = distance;
  121. }
  122. }
  123. if (min_distance == std::numeric_limits<double>::max())
  124. {
  125. NonFeasibleTermination();
  126. return;
  127. }
  128. // Add the distance to the vertex label and remove the vertex from the candidates
  129. vertex_labels_[min_distance_vertex] += min_distance;
  130. Remove(vertex_candidates_, min_distance_vertex);
  131. #ifdef DEBUG
  132. std::cout << min_distance_vertex << " " << vertex_labels_[min_distance_vertex]
  133. << (interlacing_predecessors_positive_[min_distance_vertex] ? " " : " -")
  134. << interlacing_predecessors_[min_distance_vertex] << std::endl;
  135. #endif
  136. if (min_distance_vertex == sink_)
  137. {
  138. NextPathDefinition();
  139. return;
  140. }
  141. else
  142. {
  143. if (path_predecessors_.count(min_distance_vertex) > 0 || Contains(sink_neighbors_, min_distance_vertex))
  144. {
  145. NegativeInterlacing(min_distance_vertex);
  146. return;
  147. }
  148. else
  149. {
  150. NeighborDistanceTest(min_distance_vertex);
  151. }
  152. }
  153. }
  154. }
  155. void KShortestPaths4::NeighborDistanceTest(Vertex vertex_r)
  156. {
  157. // Compute the distance to all neighbors and find the best fitting neighbor,
  158. // than save that neighbor and the new calculated distance
  159. EdgeWeightMap edge_weights = boost::get(boost::edge_weight, graph_);
  160. boost::graph_traits<DirectedGraph>::out_edge_iterator oei, oei_end;
  161. for (boost::tie(oei, oei_end) = boost::out_edges(vertex_r, graph_); oei != oei_end; ++oei)
  162. {
  163. Vertex vertex_j = boost::target(*oei, graph_);
  164. // Check if the vertex is a candidate
  165. if (Contains(vertex_candidates_, vertex_j))
  166. {
  167. // Calculate possible new edge weight for the candidate
  168. double delta = vertex_labels_[vertex_r] + edge_weights[*oei] - vertex_labels_[vertex_j];
  169. if (vertex_distances_[vertex_j] > delta)
  170. {
  171. vertex_distances_[vertex_j] = delta;
  172. interlacing_predecessors_[vertex_j] = vertex_r;
  173. }
  174. }
  175. }
  176. }
  177. void KShortestPaths4::NegativeInterlacing(Vertex vertex_i)
  178. {
  179. boost::graph_traits<DirectedGraph>::edge_descriptor ed;
  180. bool e_found;
  181. // Find the path containing the specified vertex
  182. Vertex path_destination = FindPathDestination(path_predecessors_, source_, sink_neighbors_, vertex_i);
  183. // Find the first vertex going from I in reverse vertex order, which is either weighted or not a candidate
  184. Vertex vertex_j = source_;
  185. for (auto u = vertex_i, v = path_predecessors_[u]; v != source_; u = v, v = path_predecessors_[v])
  186. {
  187. boost::tie(ed, e_found) = boost::edge(v, u, graph_);
  188. double weight = vertex_labels_[v] + boost::get(boost::edge_weight, graph_, ed) - vertex_labels_[u];;
  189. if (weight < 0 || !Contains(vertex_candidates_, v))
  190. {
  191. vertex_j = v;
  192. break;
  193. }
  194. }
  195. // Set Q to the next vertex after J in vertex order
  196. Vertex vertex_q = FindPathSuccessor(path_predecessors_, source_, path_destination, vertex_j);
  197. // Set T to the node in P were the interlacing from origin to I last enters P
  198. Vertex vertex_t = vertex_i;
  199. for (auto u = vertex_i, v = path_predecessors_[u]; u != source_; u = v, v = path_predecessors_[v])
  200. {
  201. if (interlacing_predecessors_.count(u) > 0 && interlacing_predecessors_[u] != v)
  202. {
  203. vertex_t = u;
  204. break;
  205. }
  206. }
  207. // For each node on path between (and different from) J and I
  208. for (auto v = path_predecessors_[vertex_i]; v != vertex_j; v = path_predecessors_[v])
  209. {
  210. // Remove the node from candidates
  211. Remove(vertex_candidates_, v);
  212. }
  213. // For each node on path between (and different from) J and I
  214. for (auto v = path_predecessors_[vertex_i]; v != vertex_j; v = path_predecessors_[v])
  215. {
  216. // Increase the label by the distance to I
  217. vertex_labels_[v] += vertex_distances_[vertex_i];
  218. // Set the predecessor to -T
  219. interlacing_predecessors_[v] = vertex_t;
  220. interlacing_predecessors_positive_[v] = false;
  221. NeighborDistanceTest(v);
  222. }
  223. // Save L_J and compute L_J' to perform a neighbor distance test with L_J' and then restore L_J
  224. double label_j = vertex_labels_[vertex_j];
  225. boost::tie(ed, e_found) = boost::edge(vertex_j, vertex_q, graph_);
  226. double label_j_mark = vertex_labels_[vertex_q] - boost::get(boost::edge_weight, graph_, ed);
  227. vertex_labels_[vertex_j] = label_j_mark;
  228. NeighborDistanceTest(vertex_j);
  229. vertex_labels_[vertex_j] = label_j;
  230. // If and only if J is a candidate
  231. if (Contains(vertex_candidates_, vertex_j))
  232. {
  233. double delta = label_j_mark - label_j;
  234. if (vertex_distances_[vertex_j] > delta)
  235. {
  236. vertex_distances_[vertex_j] = delta;
  237. // Set the predecessor to -T
  238. interlacing_predecessors_[vertex_j] = vertex_t;
  239. interlacing_predecessors_positive_[vertex_j] = false;
  240. }
  241. }
  242. InterlacingConstruction();
  243. }
  244. void KShortestPaths4::NextPathDefinition()
  245. {
  246. // Create a copy of the paths to work with
  247. VertexPredecessorMap path_predecessors_old = path_predecessors_;
  248. // Start with the sink vertex
  249. Vertex vertex_i = sink_;
  250. // Follow the interlacing predecessors backwards and revise the path to define P_{M+1}
  251. while (true)
  252. {
  253. // Set J to the vertex in the shortest path where the interlacing last leaves the path prior to I
  254. Vertex vertex_j = source_;
  255. for (auto u = vertex_i, v = interlacing_predecessors_[u]; v != source_;
  256. u = v, v = interlacing_predecessors_[v])
  257. {
  258. if ((path_predecessors_old.count(u) == 0 && path_predecessors_old.count(v) > 0) ||
  259. path_predecessors_old.count(u) != 0 && path_predecessors_old[u] != v) {
  260. vertex_j = v;
  261. break;
  262. }
  263. }
  264. // Set Q to the first vertex in the interlacing following J
  265. Vertex vertex_q = FindPathSuccessor(interlacing_predecessors_, source_, vertex_i, vertex_j);
  266. // For each node j from Q to I (inclusive) on S, set t_j = p_j
  267. for (auto u = vertex_i, v = interlacing_predecessors_[u]; ;
  268. u = v, v = interlacing_predecessors_[v])
  269. {
  270. if (u != sink_)
  271. path_predecessors_[u] = v;
  272. if (u == vertex_q) break;
  273. }
  274. // Check if the interlacing reached the source vertex, if so, the interlacing is completed
  275. if (vertex_j != source_)
  276. {
  277. // Find T = node following J on P_M
  278. Vertex vertex_t = 0;
  279. if (Contains(sink_neighbors_, vertex_j))
  280. {
  281. vertex_t = sink_;
  282. }
  283. else
  284. {
  285. for (auto &v : sink_neighbors_)
  286. {
  287. Vertex successor = FindPathSuccessor(path_predecessors_, source_, v, vertex_j);
  288. if (successor != vertex_j)
  289. {
  290. vertex_t = successor;
  291. break;
  292. }
  293. }
  294. }
  295. //TODO verify the meaning of (I = node in P_M where S last enters P_M prior to J)
  296. if (interlacing_predecessors_positive_[vertex_t])
  297. {
  298. vertex_i = vertex_t;
  299. }
  300. else
  301. {
  302. vertex_i = interlacing_predecessors_[vertex_t];
  303. }
  304. }
  305. else
  306. {
  307. // Add Q to the source neighbors
  308. source_neighbors_.push_back(vertex_q);
  309. // Add interlacing predecessor of the sink to the sink neighbors
  310. sink_neighbors_.push_back(interlacing_predecessors_[sink_]);
  311. // Add the paths distance to the total distance of all paths
  312. total_paths_distance_ += vertex_labels_[sink_];
  313. // A new path was found
  314. ++total_paths_count_;
  315. // Check if the necessary number of paths was found
  316. if (total_paths_count_ < max_paths_count_)
  317. NewInitialConditions();
  318. else
  319. FeasibleTermination();
  320. return;
  321. }
  322. }
  323. }
  324. void KShortestPaths4::NewInitialConditions()
  325. {
  326. // Add the total path to each vertex label
  327. for (auto const& v : vertex_candidates_)
  328. {
  329. vertex_labels_[v] += vertex_distances_[sink_];
  330. }
  331. // Redefine candidate list
  332. SetCandidates();
  333. InterlacingConstruction();
  334. }
  335. void KShortestPaths4::SetCandidates()
  336. {
  337. // Clear all corresponding values
  338. vertex_candidates_.clear();
  339. vertex_distances_.clear();
  340. interlacing_predecessors_.clear();
  341. interlacing_predecessors_positive_.clear();
  342. // Add all vertices in the graph except the source neighbors and the source itself
  343. boost::graph_traits<DirectedGraph>::vertex_iterator vi, vi_end;
  344. for (boost::tie(vi, vi_end) = boost::vertices(graph_); vi != vi_end; ++vi)
  345. {
  346. if (*vi == source_) continue;
  347. if (Contains(source_neighbors_, *vi)) continue;
  348. vertex_candidates_.push_back(*vi);
  349. }
  350. // For each candidate define the distance and predecessors
  351. boost::graph_traits<DirectedGraph>::edge_descriptor ed;
  352. bool e_found;
  353. for (auto const& v : vertex_candidates_)
  354. {
  355. boost::tie(ed, e_found) = boost::edge(source_, v, graph_);
  356. if (e_found)
  357. {
  358. vertex_distances_[v] = boost::get(boost::edge_weight, graph_, ed) - vertex_labels_[v];
  359. interlacing_predecessors_[v] = source_;
  360. interlacing_predecessors_positive_[v] = true;
  361. }
  362. else
  363. {
  364. vertex_distances_[v] = std::numeric_limits<double>::max();
  365. //TODO check if necessary (if not, remove the lines completely)
  366. interlacing_predecessors_[v] = std::numeric_limits<Vertex>::max();
  367. interlacing_predecessors_positive_[v] = true;
  368. }
  369. }
  370. }
  371. void KShortestPaths4::FeasibleTermination()
  372. {
  373. //TODO implement
  374. #ifdef DEBUG
  375. std::cout << "Feasible termination!\n";
  376. #endif
  377. }
  378. void KShortestPaths4::NonFeasibleTermination()
  379. {
  380. //TODO implement
  381. #ifdef DEBUG
  382. std::cout << "Non feasible termination!\n";
  383. #endif
  384. }
  385. Vertex KShortestPaths4::FindPathDestination(VertexPredecessorMap& map, Vertex origin,
  386. std::vector<Vertex>& possible_destination, Vertex element)
  387. {
  388. if (element == origin) return element;
  389. for (auto d : possible_destination)
  390. {
  391. for (auto v = d; v != origin; v = map[v])
  392. {
  393. if (v == element)
  394. {
  395. return d;
  396. }
  397. }
  398. }
  399. return element;
  400. }
  401. Vertex KShortestPaths4::FindPathSuccessor(VertexPredecessorMap& map, Vertex origin, Vertex destination,
  402. Vertex element)
  403. {
  404. for (auto u = destination, v = map[u]; u != origin; u = v, v = map[v])
  405. {
  406. if (v == element)
  407. {
  408. return u;
  409. }
  410. }
  411. return element;
  412. }
  413. bool KShortestPaths4::Remove(std::vector<Vertex>& vector, Vertex element)
  414. {
  415. for (size_t i = 0; i < vector.size(); ++i)
  416. {
  417. if (vector[i] == element)
  418. {
  419. vector.erase(vector.begin() + i);
  420. return true;
  421. }
  422. }
  423. return false;
  424. }
  425. bool KShortestPaths4::Contains(VertexPredecessorMap& map, Vertex origin, Vertex destination, Vertex element)
  426. {
  427. if (element == origin || element == destination) return true;
  428. for (auto& v = map[destination]; v != origin; v = map[v])
  429. {
  430. if (v == element)
  431. {
  432. return true;
  433. }
  434. }
  435. return false;
  436. }
  437. bool KShortestPaths4::Contains(std::vector<Vertex>& vector, Vertex element)
  438. {
  439. for (auto const& v : vector)
  440. {
  441. if (v == element)
  442. {
  443. return true;
  444. }
  445. }
  446. return false;
  447. }
  448. std::vector<std::vector<Vertex>> KShortestPaths4::GetPaths()
  449. {
  450. std::vector<std::vector<Vertex>> paths;
  451. for (auto u : sink_neighbors_)
  452. {
  453. std::vector<Vertex> path;
  454. path.push_back(sink_);
  455. for (auto v = u; v != source_; v = path_predecessors_[v])
  456. {
  457. path.insert(path.begin(), v);
  458. }
  459. path.insert(path.begin(), source_);
  460. paths.push_back(path);
  461. }
  462. return paths;
  463. }
  464. double KShortestPaths4::GetTotalPathsLength() {
  465. return total_paths_distance_;
  466. }
  467. }