Commit c7d2dfcc authored by Tiago Peixoto's avatar Tiago Peixoto
Browse files

all_shortest_paths(): Add "epsilon" parameter

parent 9f7ea589
Pipeline #338 passed with stage
in 430 minutes and 17 seconds
......@@ -30,6 +30,7 @@
#include <boost/graph/bellman_ford_shortest_paths.hpp>
#include <boost/python/stl_iterator.hpp>
#include <boost/python.hpp>
#include <boost/math/special_functions/relative_difference.hpp>
using namespace std;
using namespace boost;
......@@ -449,7 +450,8 @@ void get_dists(GraphInterface& gi, size_t source, boost::python::object tgt,
}
template <class Graph, class Dist, class Pred, class Weight, class Preds>
void get_all_preds(Graph g, Dist dist, Pred pred, Weight weight, Preds preds)
void get_all_preds(Graph g, Dist dist, Pred pred, Weight weight, Preds preds,
long double epsilon)
{
parallel_vertex_loop
(g,
......@@ -462,14 +464,23 @@ void get_all_preds(Graph g, Dist dist, Pred pred, Weight weight, Preds preds)
for (auto e : in_or_out_edges_range(v, g))
{
auto u = boost::is_directed(g) ? source(e, g) : target(e, g);
if (dist_t(dist[u] + get(weight, e)) == d)
preds[v].push_back(u);
if (std::is_floating_point<dist_t>::value)
{
if (dist_t(dist[u] + get(weight, e)) == d)
preds[v].push_back(u);
}
else
{
if (boost::math::relative_difference(dist_t(dist[u] + get(weight, e)), d) < epsilon)
preds[v].push_back(u);
}
}
});
};
void do_get_all_preds(GraphInterface& gi, boost::any adist,
boost::any apred, boost::any aweight, boost::any apreds)
void do_get_all_preds(GraphInterface& gi, boost::any adist, boost::any apred,
boost::any aweight, boost::any apreds,
long double epsilon)
{
typedef property_map_type
::apply<int64_t, GraphInterface::vertex_index_map_t>::type pred_map_t;
......@@ -489,7 +500,8 @@ void do_get_all_preds(GraphInterface& gi, boost::any adist,
run_action<>()
(gi, [&](auto& g, auto dist, auto weight)
{get_all_preds(g, dist, pred.get_unchecked(num_vertices(g)),
weight, preds.get_unchecked(num_vertices(g)));},
weight, preds.get_unchecked(num_vertices(g)),
epsilon);},
vertex_scalar_properties(), weight_props_t())(adist, aweight);
}
......
......@@ -1849,7 +1849,7 @@ def shortest_path(g, source, target, weights=None, negative_weights=False,
v = p
return vlist, elist
def all_predecessors(g, dist_map, pred_map, weights=None):
def all_predecessors(g, dist_map, pred_map, weights=None, epsilon=1e-8):
"""Return a property map with all possible predecessors in the search tree
determined by ``dist_map`` and ``pred_map``.
......@@ -1864,6 +1864,9 @@ def all_predecessors(g, dist_map, pred_map, weights=None):
Vertex property map with the predecessors in the search tree.
weights : :class:`~graph_tool.PropertyMap` (optional, default: None)
The edge weights.
epsilon : `float` (optional, default: `1e-8`)
Maximum relative difference between distances to be considered "equal",
in case floating-point weights are used.
Returns
-------
......@@ -1878,11 +1881,13 @@ def all_predecessors(g, dist_map, pred_map, weights=None):
_prop("v", g, dist_map),
_prop("v", g, pred_map),
_prop("e", g, weights),
_prop("v", g, preds))
_prop("v", g, preds),
epsilon)
return preds
def all_shortest_paths(g, source, target, weights=None, negative_weights=False,
dist_map=None, pred_map=None, all_preds_map=None):
dist_map=None, pred_map=None, all_preds_map=None,
epsilon=1e-8):
"""Return an iterator over all shortest paths from `source` to `target`.
Parameters
......@@ -1908,6 +1913,9 @@ def all_shortest_paths(g, source, target, weights=None, negative_weights=False,
Vector-valued vertex property map with all possible predecessors in the
search tree. If this is provided, the shortest paths are obtained
directly from this map.
epsilon : `float` (optional, default: `1e-8`)
Maximum relative difference between distances to be considered "equal",
in case floating-point weights are used.
Returns
-------
......@@ -1955,7 +1963,7 @@ def all_shortest_paths(g, source, target, weights=None, negative_weights=False,
negative_weights=negative_weights,
pred_map=True)
if all_preds_map is None:
all_preds_map = all_predecessors(g, dist_map, pred_map, weights)
all_preds_map = all_predecessors(g, dist_map, pred_map, weights, epsilon)
path_iterator = \
libgraph_tool_topology.get_all_shortest_paths(g._Graph__graph,
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment