21#include "absl/container/flat_hash_set.h"
22#include "absl/log/check.h"
33 num_vehicles, {depot, depot})) {}
36 const std::vector<NodeIndex>& starts,
37 const std::vector<NodeIndex>& ends) {
40 std::vector<std::pair<NodeIndex, NodeIndex>> starts_ends(
num_vehicles);
42 starts_ends[v] = {starts[v], ends[v]};
48 int num_nodes,
int num_vehicles,
49 const std::vector<std::pair<NodeIndex, NodeIndex>>& starts_ends) {
53void RoutingIndexManager::Initialize(
54 int num_nodes,
int num_vehicles,
55 const std::vector<std::pair<NodeIndex, NodeIndex>>& starts_ends) {
60 CHECK_EQ(num_vehicles_, starts_ends.size());
61 absl::flat_hash_set<NodeIndex> starts;
62 absl::flat_hash_set<NodeIndex> ends;
63 absl::flat_hash_set<NodeIndex> unique_depots;
64 for (
const std::pair<NodeIndex, NodeIndex>& start_end : starts_ends) {
69 CHECK_LE(
start, num_nodes_);
70 CHECK_LE(
end, num_nodes_);
73 unique_depots.insert(
start);
74 unique_depots.insert(
end);
76 num_unique_depots_ = unique_depots.size();
77 const int size = num_nodes_ + num_vehicles_ - num_unique_depots_;
79 index_to_node_.resize(
size + num_vehicles_);
81 vehicle_to_start_.resize(num_vehicles_);
82 vehicle_to_end_.resize(num_vehicles_);
84 for (
NodeIndex i = kZeroNode; i < num_nodes_; ++i) {
85 if (starts.contains(i) || !ends.contains(i)) {
86 index_to_node_[
index] = i;
87 node_to_index_[i] =
index;
91 absl::flat_hash_set<NodeIndex> seen_starts;
92 for (
int i = 0;
i < num_vehicles_; ++
i) {
94 if (!seen_starts.contains(
start)) {
95 seen_starts.insert(
start);
96 const int64_t start_index = node_to_index_[
start];
97 vehicle_to_start_[
i] = start_index;
100 vehicle_to_start_[
i] =
index;
105 for (
int i = 0;
i < num_vehicles_; ++
i) {
108 vehicle_to_end_[
i] =
index;
114 VLOG(1) <<
"Number of nodes: " << num_nodes_;
115 VLOG(1) <<
"Number of vehicles: " << num_vehicles_;
117 VLOG(2) <<
"Variable index " <<
index <<
" -> Node index "
118 << index_to_node_[
index];
120 for (
NodeIndex node = kZeroNode; node < node_to_index_.size(); ++node) {
121 VLOG(2) <<
"Node index " << node <<
" -> Variable index "
122 << node_to_index_[node];
127 const std::vector<NodeIndex>&
nodes)
const {
128 std::vector<int64_t> indices;
129 indices.reserve(
nodes.size());
133 indices.push_back(
index);
139 const std::vector<int64_t>& indices)
const {
140 std::vector<NodeIndex>
nodes;
141 nodes.reserve(indices.size());
142 for (
const int64_t
index : indices) {
static const int64_t kUnassigned
int64_t NodeToIndex(NodeIndex node) const
std::vector< NodeIndex > IndicesToNodes(const std::vector< int64_t > &indices) const
Same as IndexToNode but for a given vector of indices.
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.
RoutingNodeIndex NodeIndex
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.
std::optional< int64_t > end