KShortestPaths4.cpp 20 KB

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