osrm-backend/include/util/permutation.hpp
Michael Bell 5266ac1635
Add support for multiple via-way restrictions (#5907)
Currently OSRM only supports turn restrictions with a single via-node or one
via-way. OSM allows for multiple via-ways to represent longer and more
complex restrictions.

This PR extends the use of duplicate nodes for representng via-way turn
restrictions to also support multi via-way restrictions. Effectively, this
increases the edge-based graph size by the number of edges in multi via-way
restrictions. However, given the low number of these restrictions it
has little effect on total graph size.

In addition, we add a new step in the extraction phase that constructs
a restriction graph to support more complex relationships between restrictions,
such as nested restrictions and overlapping restrictions.
2020-12-20 13:59:57 -08:00

74 lines
2.0 KiB
C++

#ifndef OSRM_UTIL_PERMUTATION_HPP
#define OSRM_UTIL_PERMUTATION_HPP
#include "util/integer_range.hpp"
#include <vector>
namespace osrm
{
namespace util
{
namespace permutation_detail
{
template <typename T> static inline void swap(T &a, T &b) { std::swap(a, b); }
static inline void swap(std::vector<bool>::reference a, std::vector<bool>::reference b)
{
std::vector<bool>::swap(a, b);
}
} // namespace permutation_detail
template <typename RandomAccessIterator, typename IndexT>
void inplacePermutation(RandomAccessIterator begin,
RandomAccessIterator end,
const std::vector<IndexT> &old_to_new)
{
std::size_t size = std::distance(begin, end);
BOOST_ASSERT(old_to_new.size() == size);
// we need a little bit auxililary space since we need to mark
// replaced elements in a non-destructive way
std::vector<bool> was_replaced(size, false);
for (auto index : util::irange<IndexT>(0, size))
{
if (was_replaced[index])
{
continue;
}
if (old_to_new[index] == index)
{
was_replaced[index] = true;
continue;
}
// iterate over a cycle in the permutation
auto buffer = begin[index];
auto old_index = index;
auto new_index = old_to_new[old_index];
for (; new_index != index; old_index = new_index, new_index = old_to_new[new_index])
{
was_replaced[old_index] = true;
permutation_detail::swap(buffer, begin[new_index]);
}
was_replaced[old_index] = true;
permutation_detail::swap(buffer, begin[index]);
}
}
template <typename IndexT>
std::vector<IndexT> orderingToPermutation(const std::vector<IndexT> &ordering)
{
std::vector<IndexT> permutation(ordering.size());
for (auto index : util::irange<IndexT>(0, ordering.size()))
permutation[ordering[index]] = index;
return permutation;
}
} // namespace util
} // namespace osrm
#endif