Updating dijkstra_shortest_path_to, seems buggy.

for/release
Denes Matetelki 10 years ago
parent 7b3e960f4a
commit 18afa617b3

@ -1,27 +1,22 @@
#include <graph.hpp> #ifndef GRAPH_ALGORITHMS_HPP
#define GRAPH_ALGORITHMS_HPP
#include "graph.hpp"
#include <vector> #include <vector>
#include <unordered_map> #include <unordered_map>
#include <unordered_set> #include <unordered_set>
#include <queue> #include <queue>
#include <utility>
#include <algorithm> #include <algorithm>
#include <functional>
namespace { namespace {
template <typename G>
inline typename G::weight_type min_dist_between(const G& graph,
typename G::const_reference destination,
typename G::const_reference source)
{
const std::vector<typename G::weight_type>& ws = graph.weights(destination, source);
const typename std::vector<typename G::weight_type>::const_iterator it = std::min_element(ws.begin(), ws.end());
return *it;
}
template <typename V, typename W> template <typename V, typename W>
inline V smallest_distance_to_graph(const std::unordered_set<V>& q, const std::unordered_map<V, W>& dist) inline V closestNode(const std::unordered_set<V>& q, const std::unordered_map<V, W>& dist)
{ {
const typename std::unordered_set<V>::const_iterator smallest_it = const typename std::unordered_set<V>::const_iterator smallest_it =
std::min_element(q.begin(), q.end(), std::min_element(q.begin(), q.end(),
@ -31,14 +26,17 @@ inline V smallest_distance_to_graph(const std::unordered_set<V>& q, const std::u
return *smallest_it; return *smallest_it;
} }
template <typename V, typename W> template <typename V>
std::vector<V> pathFromPrevList(const V& dest, std::unordered_map<V, V> prev) std::vector<V> pathFromPrevList(const V& dest, std::unordered_map<V, V> prev)
{ {
std::vector<V> retval; std::vector<V> retval;
retval.push_back(dest); retval.push_back(dest);
for (V it = dest; prev.find(it) != prev.end() ; it = prev.at(it)) for (V it = dest; prev.find(it) != prev.end() ; /*it = prev.at(it)*/) {
retval.push_back(prev[it]); V v = prev.at(it);
retval.push_back(v);
it = v;
}
std::reverse(retval.begin(), retval.end()); std::reverse(retval.begin(), retval.end());
return retval; return retval;
@ -47,93 +45,18 @@ std::vector<V> pathFromPrevList(const V& dest, std::unordered_map<V, V> prev)
} // anonym namespace } // anonym namespace
template <typename V, typename W>
// template <typename G> std::vector<V>
// std::pair <std::unordered_map<typename G::value_type, typename G::weight_type>, dijkstra_shortest_path_to(const Graph<V>& graph,
// std::unordered_map<typename G::value_type, typename G::value_type> > const V& source,
// dijkstra_shortest_path(const G& graph, typename G::const_reference source) const V& dest,
// { std::function<W(V, V)> distanceCompute
// typedef typename G::value_type V; )
// typedef typename G::weight_type W;
//
// std::unordered_map<V, W> dist; /// @todo -> std::map < W, V > ?
// std::unordered_map<V, V> prev;
//
// dist[source] = V();
//
// std::unordered_set<V> q;
// for (const V& v : graph.vertices())
// q.insert(v);
//
// while (!q.empty()) {
// const V& u = smallest_distance_to_graph<V, W>(q, dist);
// q.erase(u);
// if (dist.find(u) == dist.end())
// continue;
//
// for (V v : graph.neighboursOf(u)) {
// const W alt = dist.at(u) + min_dist_between(graph, u, v);
// if (dist.find(v) == dist.end() || alt < dist.at(v)) {
// dist[v] = alt;
// prev[v] = u;
// }
// }
// }
//
// return std::make_pair(dist, prev);
// }
//
// template <typename G>
// std::pair <std::unordered_map<typename G::value_type, typename G::weight_type>,
// std::unordered_map<typename G::value_type, typename G::value_type> >
// dijkstra_shortest_path_v2(const G& graph, typename G::const_reference source)
// {
// typedef typename G::value_type V;
// typedef typename G::weight_type W;
//
// std::unordered_map<V, W> dist;
// std::unordered_map<V, V> prev;
//
// dist[source] = V();
//
// std::unordered_set<V> q;
// q.insert(source);
//
// const std::vector<V>& s_n = graph.neighboursOf(source);
// std::copy(s_n.begin(), s_n.end(), std::inserter(q, q.end()));
//
// while (!q.empty()) {
// const V& u = smallest_distance_to_graph<V, W>(q, dist);
// q.erase(u);
//
// for (V v : graph.neighboursOf(u)) {
// const W alt = dist.at(u) + min_dist_between(graph, u, v);
// if (dist.find(v) == dist.end() || alt < dist.at(v)) {
// dist[v] = alt;
// prev[v] = u;
// }
//
// if (dist.find(v) == dist.end())
// q.insert(v);
// }
// }
//
// return std::make_pair(dist, prev);
// }
template <typename G>
std::vector<typename G::value_type>
dijkstra_shortest_path_to(const G& graph,
typename G::const_reference source,
typename G::const_reference dest)
{ {
typedef typename G::value_type V;
typedef typename G::weight_type W;
std::unordered_map<V, W> dist; /// @todo into std::priority_queue<std::pair<V< W>> std::unordered_map<V, W> dist; /// @todo into std::priority_queue<std::pair<V< W>>
std::unordered_map<V, V> prev; std::unordered_map<V, V> prev;
dist[source] = V(); dist.emplace(source, W());
std::unordered_set<V> q; std::unordered_set<V> q;
q.insert(source); q.insert(source);
@ -142,22 +65,30 @@ dijkstra_shortest_path_to(const G& graph,
std::copy(s_n.begin(), s_n.end(), std::inserter(q, q.end())); std::copy(s_n.begin(), s_n.end(), std::inserter(q, q.end()));
while (!q.empty()) { while (!q.empty()) {
const V& u = smallest_distance_to_graph<V, W>(q, dist); const V& u = closestNode<V, W>(q, dist);
q.erase(u); q.erase(u);
if (u == dest) if (u == dest)
break; break;
for (V v : graph.neighboursOf(u)) { for (V v : graph.neighboursOf(u)) {
const W alt = dist.at(u) + min_dist_between(graph, u, v); const bool newNode = dist.find(v) == dist.end();
if (dist.find(v) == dist.end() || alt < dist.at(v)) { const W d = distanceCompute(u, v);
dist[v] = alt; if (newNode) {
prev[v] = u; dist.emplace(v, d);
} prev.emplace(v, u);
if (dist.find(v) == dist.end())
q.insert(v); q.insert(v);
} else {
const W alt = dist.at(u) + d;
const bool betterRoute = alt < dist.at(v);
if (betterRoute) {
dist[v] = alt;
prev[v] = u;
}
}
} }
} }
return pathFromPrevList(dest, prev); return pathFromPrevList(dest, prev);
} }
#endif // GRAPH_ALGORITHMS_HPP

Loading…
Cancel
Save