2017-08-20 19:24:05 -04:00
|
|
|
#ifndef OSRM_CONTRACTOR_CONTRACT_EXCLUDABLE_GRAPH_HPP
|
|
|
|
#define OSRM_CONTRACTOR_CONTRACT_EXCLUDABLE_GRAPH_HPP
|
|
|
|
|
|
|
|
#include "contractor/contracted_edge_container.hpp"
|
|
|
|
#include "contractor/contractor_graph.hpp"
|
|
|
|
#include "contractor/graph_contractor.hpp"
|
|
|
|
#include "contractor/graph_contractor_adaptors.hpp"
|
|
|
|
#include "contractor/query_graph.hpp"
|
|
|
|
|
|
|
|
namespace osrm
|
|
|
|
{
|
|
|
|
namespace contractor
|
|
|
|
{
|
|
|
|
|
2017-10-11 20:15:27 -04:00
|
|
|
using GraphAndFilter = std::tuple<QueryGraph, std::vector<std::vector<bool>>>;
|
|
|
|
|
|
|
|
inline auto contractFullGraph(ContractorGraph contractor_graph,
|
|
|
|
std::vector<EdgeWeight> node_weights)
|
|
|
|
{
|
|
|
|
auto num_nodes = contractor_graph.GetNumberOfNodes();
|
2022-06-30 09:32:12 -04:00
|
|
|
contractGraph(contractor_graph, std::move(node_weights));
|
2017-10-11 20:15:27 -04:00
|
|
|
|
|
|
|
auto edges = toEdges<QueryEdge>(std::move(contractor_graph));
|
|
|
|
std::vector<bool> edge_filter(edges.size(), true);
|
|
|
|
|
2022-08-23 13:03:41 -04:00
|
|
|
return GraphAndFilter{QueryGraph{num_nodes, edges}, {std::move(edge_filter)}};
|
2017-10-11 20:15:27 -04:00
|
|
|
}
|
2017-08-20 19:24:05 -04:00
|
|
|
|
|
|
|
inline auto contractExcludableGraph(ContractorGraph contractor_graph_,
|
|
|
|
std::vector<EdgeWeight> node_weights,
|
2017-10-12 13:12:54 -04:00
|
|
|
const std::vector<std::vector<bool>> &filters)
|
2017-08-20 19:24:05 -04:00
|
|
|
{
|
2017-10-11 20:15:27 -04:00
|
|
|
if (filters.size() == 1)
|
|
|
|
{
|
|
|
|
if (std::all_of(filters.front().begin(), filters.front().end(), [](auto v) { return v; }))
|
|
|
|
{
|
|
|
|
return contractFullGraph(std::move(contractor_graph_), std::move(node_weights));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-20 19:24:05 -04:00
|
|
|
auto num_nodes = contractor_graph_.GetNumberOfNodes();
|
|
|
|
ContractedEdgeContainer edge_container;
|
|
|
|
ContractorGraph shared_core_graph;
|
|
|
|
std::vector<bool> is_shared_core;
|
|
|
|
{
|
|
|
|
ContractorGraph contractor_graph = std::move(contractor_graph_);
|
|
|
|
std::vector<bool> always_allowed(num_nodes, true);
|
|
|
|
for (const auto &filter : filters)
|
|
|
|
{
|
|
|
|
for (const auto node : util::irange<NodeID>(0, num_nodes))
|
|
|
|
{
|
|
|
|
always_allowed[node] = always_allowed[node] && filter[node];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// By not contracting all contractable nodes we avoid creating
|
|
|
|
// a very dense core. This increases the overall graph sizes a little bit
|
|
|
|
// but increases the final CH quality and contraction speed.
|
|
|
|
constexpr float BASE_CORE = 0.9;
|
2017-10-13 06:14:45 -04:00
|
|
|
is_shared_core =
|
|
|
|
contractGraph(contractor_graph, std::move(always_allowed), node_weights, BASE_CORE);
|
2017-08-20 19:24:05 -04:00
|
|
|
|
|
|
|
// Add all non-core edges to container
|
|
|
|
{
|
|
|
|
auto non_core_edges = toEdges<QueryEdge>(contractor_graph);
|
|
|
|
auto new_end =
|
|
|
|
std::remove_if(non_core_edges.begin(), non_core_edges.end(), [&](const auto &edge) {
|
|
|
|
return is_shared_core[edge.source] && is_shared_core[edge.target];
|
|
|
|
});
|
|
|
|
non_core_edges.resize(new_end - non_core_edges.begin());
|
|
|
|
edge_container.Insert(std::move(non_core_edges));
|
2018-01-08 10:56:32 -05:00
|
|
|
|
|
|
|
for (const auto filter_index : util::irange<std::size_t>(0, filters.size()))
|
|
|
|
{
|
|
|
|
edge_container.Filter(filters[filter_index], filter_index);
|
|
|
|
}
|
2017-08-20 19:24:05 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Extract core graph for further contraction
|
|
|
|
shared_core_graph = contractor_graph.Filter(
|
|
|
|
[&is_shared_core](const NodeID node) { return is_shared_core[node]; });
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const auto &filter : filters)
|
|
|
|
{
|
|
|
|
auto filtered_core_graph =
|
|
|
|
shared_core_graph.Filter([&filter](const NodeID node) { return filter[node]; });
|
|
|
|
|
2017-10-23 19:09:25 -04:00
|
|
|
contractGraph(filtered_core_graph, is_shared_core, is_shared_core, node_weights);
|
|
|
|
|
2017-08-20 19:24:05 -04:00
|
|
|
edge_container.Merge(toEdges<QueryEdge>(std::move(filtered_core_graph)));
|
|
|
|
}
|
|
|
|
|
2022-08-23 13:03:41 -04:00
|
|
|
return GraphAndFilter{QueryGraph{num_nodes, edge_container.edges},
|
2017-10-11 20:15:27 -04:00
|
|
|
edge_container.MakeEdgeFilters()};
|
2017-08-20 19:24:05 -04:00
|
|
|
}
|
2020-11-26 10:21:39 -05:00
|
|
|
} // namespace contractor
|
|
|
|
} // namespace osrm
|
2017-08-20 19:24:05 -04:00
|
|
|
|
|
|
|
#endif
|