small improvements in filters
This commit is contained in:
@@ -2810,9 +2810,9 @@ class GlobalCheapestInsertionFilteredDecisionBuilder
|
||||
AdjustablePriorityQueue<NodeEntry>* priority_queue,
|
||||
std::vector<NodeEntries>* node_entries);
|
||||
|
||||
/// Inserts neighbor_index in
|
||||
/// node_index_to_[pickup|delivery|single]_neighbors_per_cost_class_
|
||||
/// [node_index][cost_class] according to whether neighbor is a pickup,
|
||||
/// Marks neighbor_index as visited in
|
||||
/// node_index_to_[pickup|delivery|single]_neighbors_by_cost_class_
|
||||
/// [node_index][cost_class] according to whether the neighbor is a pickup,
|
||||
/// a delivery, or neither.
|
||||
void AddNeighborForCostClass(int cost_class, int64 node_index,
|
||||
int64 neighbor_index, bool neighbor_is_pickup,
|
||||
@@ -2824,23 +2824,24 @@ class GlobalCheapestInsertionFilteredDecisionBuilder
|
||||
int64 neighbor_index) const;
|
||||
|
||||
/// Returns a reference to the set of pickup neighbors of node_index.
|
||||
const absl::flat_hash_set<int64>& GetPickupNeighborsOfNodeForCostClass(
|
||||
const std::vector<int64>& GetPickupNeighborsOfNodeForCostClass(
|
||||
int cost_class, int64 node_index) {
|
||||
if (neighbors_ratio_ == 1) {
|
||||
return pickup_nodes_;
|
||||
}
|
||||
return node_index_to_pickup_neighbors_by_cost_class_[node_index]
|
||||
[cost_class];
|
||||
return node_index_to_pickup_neighbors_by_cost_class_[node_index][cost_class]
|
||||
->PositionsSetAtLeastOnce();
|
||||
}
|
||||
|
||||
/// Same as above for delivery neighbors.
|
||||
const absl::flat_hash_set<int64>& GetDeliveryNeighborsOfNodeForCostClass(
|
||||
const std::vector<int64>& GetDeliveryNeighborsOfNodeForCostClass(
|
||||
int cost_class, int64 node_index) {
|
||||
if (neighbors_ratio_ == 1) {
|
||||
return delivery_nodes_;
|
||||
}
|
||||
return node_index_to_delivery_neighbors_by_cost_class_[node_index]
|
||||
[cost_class];
|
||||
return node_index_to_delivery_neighbors_by_cost_class_
|
||||
[node_index][cost_class]
|
||||
->PositionsSetAtLeastOnce();
|
||||
}
|
||||
|
||||
const bool is_sequential_;
|
||||
@@ -2848,19 +2849,19 @@ class GlobalCheapestInsertionFilteredDecisionBuilder
|
||||
const double neighbors_ratio_;
|
||||
|
||||
// clang-format off
|
||||
std::vector<std::vector<absl::flat_hash_set<int64> > >
|
||||
std::vector<std::vector<std::unique_ptr<SparseBitset<int64> > > >
|
||||
node_index_to_single_neighbors_by_cost_class_;
|
||||
std::vector<std::vector<absl::flat_hash_set<int64> > >
|
||||
std::vector<std::vector<std::unique_ptr<SparseBitset<int64> > > >
|
||||
node_index_to_pickup_neighbors_by_cost_class_;
|
||||
std::vector<std::vector<absl::flat_hash_set<int64> > >
|
||||
std::vector<std::vector<std::unique_ptr<SparseBitset<int64> > > >
|
||||
node_index_to_delivery_neighbors_by_cost_class_;
|
||||
// clang-format on
|
||||
|
||||
/// When neighbors_ratio is 1, we don't compute the neighborhood members
|
||||
/// above, and use the following sets in the code to avoid unnecessary
|
||||
/// computations and decrease the time and space complexities.
|
||||
absl::flat_hash_set<int64> pickup_nodes_;
|
||||
absl::flat_hash_set<int64> delivery_nodes_;
|
||||
std::vector<int64> pickup_nodes_;
|
||||
std::vector<int64> delivery_nodes_;
|
||||
};
|
||||
|
||||
/// Filter-base decision builder which builds a solution by inserting
|
||||
|
||||
@@ -2854,10 +2854,10 @@ GlobalCheapestInsertionFilteredDecisionBuilder::
|
||||
if (neighbors_ratio == 1) {
|
||||
for (int64 node = 0; node < size; node++) {
|
||||
if (!model->GetPickupIndexPairs(node).empty()) {
|
||||
pickup_nodes_.insert(node);
|
||||
pickup_nodes_.push_back(node);
|
||||
}
|
||||
if (!model->GetDeliveryIndexPairs(node).empty()) {
|
||||
delivery_nodes_.insert(node);
|
||||
delivery_nodes_.push_back(node);
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -2875,6 +2875,14 @@ GlobalCheapestInsertionFilteredDecisionBuilder::
|
||||
num_cost_classes);
|
||||
node_index_to_delivery_neighbors_by_cost_class_[node_index].resize(
|
||||
num_cost_classes);
|
||||
for (int cc = 0; cc < num_cost_classes; cc++) {
|
||||
node_index_to_single_neighbors_by_cost_class_[node_index][cc] =
|
||||
absl::make_unique<SparseBitset<int64>>(size);
|
||||
node_index_to_pickup_neighbors_by_cost_class_[node_index][cc] =
|
||||
absl::make_unique<SparseBitset<int64>>(size);
|
||||
node_index_to_delivery_neighbors_by_cost_class_[node_index][cc] =
|
||||
absl::make_unique<SparseBitset<int64>>(size);
|
||||
}
|
||||
}
|
||||
|
||||
const int64 num_neighbors = std::max(1.0, neighbors_ratio * size);
|
||||
@@ -2929,16 +2937,16 @@ void GlobalCheapestInsertionFilteredDecisionBuilder::AddNeighborForCostClass(
|
||||
int cost_class, int64 node_index, int64 neighbor_index,
|
||||
bool neighbor_is_pickup, bool neighbor_is_delivery) {
|
||||
if (neighbor_is_pickup) {
|
||||
node_index_to_pickup_neighbors_by_cost_class_[node_index][cost_class]
|
||||
.insert(neighbor_index);
|
||||
node_index_to_pickup_neighbors_by_cost_class_[node_index][cost_class]->Set(
|
||||
neighbor_index);
|
||||
}
|
||||
if (neighbor_is_delivery) {
|
||||
node_index_to_delivery_neighbors_by_cost_class_[node_index][cost_class]
|
||||
.insert(neighbor_index);
|
||||
->Set(neighbor_index);
|
||||
}
|
||||
if (!neighbor_is_pickup && !neighbor_is_delivery) {
|
||||
node_index_to_single_neighbors_by_cost_class_[node_index][cost_class]
|
||||
.insert(neighbor_index);
|
||||
node_index_to_single_neighbors_by_cost_class_[node_index][cost_class]->Set(
|
||||
neighbor_index);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2947,19 +2955,21 @@ bool GlobalCheapestInsertionFilteredDecisionBuilder::IsNeighborForCostClass(
|
||||
if (neighbors_ratio_ == 1) {
|
||||
return true;
|
||||
}
|
||||
const SparseBitset<int64>* neighbors;
|
||||
if (!model()->GetPickupIndexPairs(neighbor_index).empty()) {
|
||||
return gtl::ContainsKey(
|
||||
node_index_to_pickup_neighbors_by_cost_class_[node_index][cost_class],
|
||||
neighbor_index);
|
||||
neighbors =
|
||||
node_index_to_pickup_neighbors_by_cost_class_[node_index][cost_class]
|
||||
.get();
|
||||
} else if (!model()->GetDeliveryIndexPairs(neighbor_index).empty()) {
|
||||
neighbors =
|
||||
node_index_to_delivery_neighbors_by_cost_class_[node_index][cost_class]
|
||||
.get();
|
||||
} else {
|
||||
neighbors =
|
||||
node_index_to_single_neighbors_by_cost_class_[node_index][cost_class]
|
||||
.get();
|
||||
}
|
||||
if (!model()->GetDeliveryIndexPairs(neighbor_index).empty()) {
|
||||
return gtl::ContainsKey(
|
||||
node_index_to_delivery_neighbors_by_cost_class_[node_index][cost_class],
|
||||
neighbor_index);
|
||||
}
|
||||
return gtl::ContainsKey(
|
||||
node_index_to_single_neighbors_by_cost_class_[node_index][cost_class],
|
||||
neighbor_index);
|
||||
return (*neighbors)[neighbor_index];
|
||||
}
|
||||
|
||||
bool GlobalCheapestInsertionFilteredDecisionBuilder::BuildSolution() {
|
||||
@@ -3390,12 +3400,8 @@ void GlobalCheapestInsertionFilteredDecisionBuilder::UpdatePickupPositions(
|
||||
// pickup_insert_after.
|
||||
const int cost_class = model()->GetCostClassIndexOfVehicle(vehicle).value();
|
||||
const int64 pickup_insert_before = Value(pickup_insert_after);
|
||||
const absl::flat_hash_set<int64>& pickup_neighbors =
|
||||
GetPickupNeighborsOfNodeForCostClass(cost_class, pickup_insert_after);
|
||||
std::vector<int64> sorted_pickup_neighbors(pickup_neighbors.begin(),
|
||||
pickup_neighbors.end());
|
||||
std::sort(sorted_pickup_neighbors.begin(), sorted_pickup_neighbors.end());
|
||||
for (int64 pickup : sorted_pickup_neighbors) {
|
||||
for (int64 pickup :
|
||||
GetPickupNeighborsOfNodeForCostClass(cost_class, pickup_insert_after)) {
|
||||
if (Contains(pickup)) {
|
||||
continue;
|
||||
}
|
||||
@@ -3502,12 +3508,8 @@ void GlobalCheapestInsertionFilteredDecisionBuilder::UpdateDeliveryPositions(
|
||||
// delivery_insert_after.
|
||||
const int cost_class = model()->GetCostClassIndexOfVehicle(vehicle).value();
|
||||
const int64 delivery_insert_before = Value(delivery_insert_after);
|
||||
const absl::flat_hash_set<int64>& delivery_neighbors =
|
||||
GetDeliveryNeighborsOfNodeForCostClass(cost_class, delivery_insert_after);
|
||||
std::vector<int64> sorted_delivery_neighbors(delivery_neighbors.begin(),
|
||||
delivery_neighbors.end());
|
||||
std::sort(sorted_delivery_neighbors.begin(), sorted_delivery_neighbors.end());
|
||||
for (int64 delivery : sorted_delivery_neighbors) {
|
||||
for (int64 delivery : GetDeliveryNeighborsOfNodeForCostClass(
|
||||
cost_class, delivery_insert_after)) {
|
||||
if (Contains(delivery)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user