OR-Tools  9.3
routing_index_manager.cc
Go to the documentation of this file.
1// Copyright 2010-2021 Google LLC
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
15
16#include <cstdint>
17#include <memory>
18
19#include "absl/container/flat_hash_set.h"
22
23namespace operations_research {
24
25const int64_t RoutingIndexManager::kUnassigned = -1;
26
27RoutingIndexManager::RoutingIndexManager(int num_nodes, int num_vehicles,
28 NodeIndex depot)
29 : RoutingIndexManager(num_nodes, num_vehicles,
30 std::vector<std::pair<NodeIndex, NodeIndex>>(
31 num_vehicles, {depot, depot})) {}
32
33RoutingIndexManager::RoutingIndexManager(int num_nodes, int num_vehicles,
34 const std::vector<NodeIndex>& starts,
35 const std::vector<NodeIndex>& ends) {
36 CHECK_EQ(starts.size(), num_vehicles);
37 CHECK_EQ(ends.size(), num_vehicles);
38 std::vector<std::pair<NodeIndex, NodeIndex>> starts_ends(num_vehicles);
39 for (int v = 0; v < num_vehicles; ++v) {
40 starts_ends[v] = {starts[v], ends[v]};
41 }
42 Initialize(num_nodes, num_vehicles, starts_ends);
43}
44
46 int num_nodes, int num_vehicles,
47 const std::vector<std::pair<NodeIndex, NodeIndex>>& starts_ends) {
48 Initialize(num_nodes, num_vehicles, starts_ends);
49}
50
51void RoutingIndexManager::Initialize(
52 int num_nodes, int num_vehicles,
53 const std::vector<std::pair<NodeIndex, NodeIndex>>& starts_ends) {
54 static const NodeIndex kZeroNode(0);
55
56 num_nodes_ = num_nodes;
57 num_vehicles_ = num_vehicles;
58 CHECK_EQ(num_vehicles_, starts_ends.size());
59 absl::flat_hash_set<NodeIndex> starts;
60 absl::flat_hash_set<NodeIndex> ends;
61 absl::flat_hash_set<NodeIndex> unique_depots;
62 for (const std::pair<NodeIndex, NodeIndex>& start_end : starts_ends) {
63 const NodeIndex start = start_end.first;
64 const NodeIndex end = start_end.second;
65 CHECK_GE(start, 0);
66 CHECK_GE(end, 0);
67 CHECK_LE(start, num_nodes_);
68 CHECK_LE(end, num_nodes_);
69 starts.insert(start);
70 ends.insert(end);
71 unique_depots.insert(start);
72 unique_depots.insert(end);
73 }
74 num_unique_depots_ = unique_depots.size();
75 const int size = num_nodes_ + num_vehicles_ - num_unique_depots_;
76
77 index_to_node_.resize(size + num_vehicles_);
78 node_to_index_.resize(num_nodes_, kUnassigned);
79 vehicle_to_start_.resize(num_vehicles_);
80 vehicle_to_end_.resize(num_vehicles_);
81 int64_t index = 0;
82 for (NodeIndex i = kZeroNode; i < num_nodes_; ++i) {
83 if (starts.contains(i) || !ends.contains(i)) {
84 index_to_node_[index] = i;
85 node_to_index_[i] = index;
86 ++index;
87 }
88 }
89 absl::flat_hash_set<NodeIndex> seen_starts;
90 for (int i = 0; i < num_vehicles_; ++i) {
91 const NodeIndex start = starts_ends[i].first;
92 if (!seen_starts.contains(start)) {
93 seen_starts.insert(start);
94 const int64_t start_index = node_to_index_[start];
95 vehicle_to_start_[i] = start_index;
96 CHECK_NE(kUnassigned, start_index);
97 } else {
98 vehicle_to_start_[i] = index;
99 index_to_node_[index] = start;
100 ++index;
101 }
102 }
103 for (int i = 0; i < num_vehicles_; ++i) {
104 NodeIndex end = starts_ends[i].second;
105 index_to_node_[index] = end;
106 vehicle_to_end_[i] = index;
107 CHECK_LE(size, index);
108 ++index;
109 }
110
111 // Logging model information.
112 VLOG(1) << "Number of nodes: " << num_nodes_;
113 VLOG(1) << "Number of vehicles: " << num_vehicles_;
114 for (int64_t index = 0; index < index_to_node_.size(); ++index) {
115 VLOG(2) << "Variable index " << index << " -> Node index "
116 << index_to_node_[index];
117 }
118 for (NodeIndex node = kZeroNode; node < node_to_index_.size(); ++node) {
119 VLOG(2) << "Node index " << node << " -> Variable index "
120 << node_to_index_[node];
121 }
122}
123
125 const std::vector<NodeIndex>& nodes) const {
126 std::vector<int64_t> indices;
127 indices.reserve(nodes.size());
128 for (const NodeIndex node : nodes) {
129 const int64_t index = NodeToIndex(node);
131 indices.push_back(index);
132 }
133 return indices;
134}
135
136std::vector<RoutingIndexManager::NodeIndex> RoutingIndexManager::IndicesToNodes(
137 const std::vector<int64_t>& indices) const {
138 std::vector<NodeIndex> nodes;
139 nodes.reserve(indices.size());
140 for (const int64_t index : indices) {
141 nodes.push_back(IndexToNode(index));
142 }
143 return nodes;
144}
145
146} // namespace operations_research
#define CHECK_EQ(val1, val2)
Definition: base/logging.h:703
#define CHECK_GE(val1, val2)
Definition: base/logging.h:707
#define CHECK_NE(val1, val2)
Definition: base/logging.h:704
#define CHECK_LE(val1, val2)
Definition: base/logging.h:705
#define VLOG(verboselevel)
Definition: base/logging.h:984
void resize(size_type new_size)
size_type size() const
Manager for any NodeIndex <-> variable index conversion.
std::vector< NodeIndex > IndicesToNodes(const std::vector< int64_t > &indices) const
std::vector< int64_t > NodesToIndices(const std::vector< NodeIndex > &nodes) const
RoutingIndexManager(int num_nodes, int num_vehicles, NodeIndex depot)
Creates a NodeIndex to variable index mapping for a problem containing 'num_nodes',...
NodeIndex IndexToNode(int64_t index) const
int64_t NodeToIndex(NodeIndex node) const
int index
Collection of objects used to extend the Constraint Solver library.
STL namespace.
int nodes
std::optional< int64_t > end
int64_t start