| 699 | } |
| 700 | |
| 701 | GraphAndFilter contractExcludableGraph(ContractorGraph contractor_graph_, |
| 702 | const std::vector<std::vector<bool>> &filters) |
| 703 | { |
| 704 | if (filters.size() == 1) |
| 705 | { |
| 706 | if (std::all_of(filters.front().begin(), filters.front().end(), [](auto v) { return v; })) |
| 707 | { |
| 708 | return contractFullGraph(std::move(contractor_graph_)); |
| 709 | } |
| 710 | } |
| 711 | |
| 712 | auto num_nodes = contractor_graph_.GetNumberOfNodes(); |
| 713 | ContractedEdgeContainer edge_container; |
| 714 | ContractorGraph shared_core_graph; |
| 715 | std::vector<bool> is_shared_core; |
| 716 | { |
| 717 | ContractorGraph contractor_graph = std::move(contractor_graph_); |
| 718 | std::vector<bool> always_allowed(num_nodes, true); |
| 719 | for (const auto &filter : filters) |
| 720 | { |
| 721 | for (const auto node : util::irange<NodeID>(0, num_nodes)) |
| 722 | { |
| 723 | always_allowed[node] = always_allowed[node] && filter[node]; |
| 724 | } |
| 725 | } |
| 726 | |
| 727 | // By not contracting all contractible nodes we avoid creating |
| 728 | // a very dense core. This increases the overall graph sizes a little bit |
| 729 | // but increases the final CH quality and contraction speed. |
| 730 | constexpr float BASE_CORE = 0.9f; |
| 731 | is_shared_core = contractGraph(contractor_graph, std::move(always_allowed), BASE_CORE); |
| 732 | |
| 733 | // Add all non-core edges to container |
| 734 | { |
| 735 | auto non_core_edges = toEdges<QueryEdge>(contractor_graph); |
| 736 | auto new_end = std::remove_if(non_core_edges.begin(), |
| 737 | non_core_edges.end(), |
| 738 | [&](const auto &edge) { |
| 739 | return is_shared_core[edge.source] && |
| 740 | is_shared_core[edge.target]; |
| 741 | }); |
| 742 | non_core_edges.resize(new_end - non_core_edges.begin()); |
| 743 | edge_container.Insert(std::move(non_core_edges)); |
| 744 | |
| 745 | for (const auto filter_index : util::irange<std::size_t>(0, filters.size())) |
| 746 | { |
| 747 | edge_container.Filter(filters[filter_index], filter_index); |
| 748 | } |
| 749 | } |
| 750 | |
| 751 | // Extract core graph for further contraction |
| 752 | shared_core_graph = contractor_graph.Filter([&is_shared_core](const NodeID node) |
| 753 | { return is_shared_core[node]; }); |
| 754 | } |
| 755 | |
| 756 | for (const auto &filter : filters) |
| 757 | { |
| 758 | auto filtered_core_graph = |
no test coverage detected