21#include "absl/container/flat_hash_set.h"
22#include "absl/log/check.h"
23#include "absl/types/span.h"
37 const std::vector<NodeIndex>& starts,
38 const std::vector<NodeIndex>& ends) {
41 std::vector<std::pair<NodeIndex, NodeIndex>> starts_ends(
num_vehicles);
43 starts_ends[v] = {starts[v], ends[v]};
50 const std::vector<std::pair<NodeIndex, NodeIndex>>& starts_ends) {
54void RoutingIndexManager::Initialize(
55 int num_nodes,
int num_vehicles,
56 const std::vector<std::pair<NodeIndex, NodeIndex>>& starts_ends) {
61 CHECK_EQ(num_vehicles_, starts_ends.size());
62 absl::flat_hash_set<NodeIndex> starts;
63 absl::flat_hash_set<NodeIndex> ends;
64 absl::flat_hash_set<NodeIndex> unique_depots;
65 for (
const std::pair<NodeIndex, NodeIndex>& start_end : starts_ends) {
70 CHECK_LE(start, num_nodes_);
71 CHECK_LE(end, num_nodes_);
74 unique_depots.insert(start);
75 unique_depots.insert(end);
77 num_unique_depots_ = unique_depots.size();
78 const int size = num_nodes_ + num_vehicles_ - num_unique_depots_;
80 index_to_node_.resize(size + num_vehicles_);
82 vehicle_to_start_.resize(num_vehicles_);
83 vehicle_to_end_.resize(num_vehicles_);
85 for (
NodeIndex i = kZeroNode; i < num_nodes_; ++i) {
86 if (starts.contains(i) || !ends.contains(i)) {
87 index_to_node_[index] = i;
88 node_to_index_[i] = index;
92 absl::flat_hash_set<NodeIndex> seen_starts;
93 for (
int i = 0;
i < num_vehicles_; ++
i) {
95 if (!seen_starts.contains(start)) {
96 seen_starts.insert(start);
97 const int64_t start_index = node_to_index_[start];
98 vehicle_to_start_[
i] = start_index;
101 vehicle_to_start_[
i] = index;
102 index_to_node_[index] = start;
106 for (
int i = 0;
i < num_vehicles_; ++
i) {
108 index_to_node_[index] = end;
109 vehicle_to_end_[
i] = index;
110 CHECK_LE(size, index);
115 VLOG(1) <<
"Number of nodes: " << num_nodes_;
116 VLOG(1) <<
"Number of vehicles: " << num_vehicles_;
117 for (int64_t index = 0; index < index_to_node_.size(); ++index) {
118 VLOG(2) <<
"Variable index " << index <<
" -> Node index "
119 << index_to_node_[index];
121 for (
NodeIndex node = kZeroNode; node < node_to_index_.size(); ++node) {
122 VLOG(2) <<
"Node index " << node <<
" -> Variable index "
123 << node_to_index_[node];
128 const std::vector<NodeIndex>& nodes)
const {
129 std::vector<int64_t> indices;
130 indices.reserve(nodes.size());
134 indices.push_back(index);
140 absl::Span<const int64_t> indices)
const {
141 std::vector<NodeIndex> nodes;
142 nodes.reserve(indices.size());
143 for (
const int64_t index : indices) {
static const int64_t kUnassigned
std::vector< NodeIndex > IndicesToNodes(absl::Span< const int64_t > indices) const
Same as IndexToNode but for a given vector of indices.
RoutingNodeIndex NodeIndex
int64_t NodeToIndex(NodeIndex node) const
RoutingIndexManager(int num_nodes, int num_vehicles, NodeIndex depot)
int num_nodes() const
Returns the number of nodes in the manager.
int num_vehicles() const
Returns the number of vehicles in the manager.
std::vector< int64_t > NodesToIndices(const std::vector< NodeIndex > &nodes) const
Same as NodeToIndex but for a given vector of nodes.
NodeIndex IndexToNode(int64_t index) const
void resize(size_type new_size)
In SWIG mode, we don't want anything besides these top-level includes.