OR-Tools  9.3
routing_neighborhoods.h
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
14#ifndef OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_NEIGHBORHOODS_H_
15#define OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_NEIGHBORHOODS_H_
16
17#include <cstdint>
18#include <functional>
19#include <memory>
20#include <string>
21#include <utility>
22#include <vector>
23
24#include "absl/strings/str_cat.h"
31#include "ortools/util/bitset.h"
32
33namespace operations_research {
34
55// TODO(user): Consider merging with standard Relocate in local_search.cc.
57 public:
59 const std::vector<IntVar*>& vars,
60 const std::vector<IntVar*>& secondary_vars,
61 std::function<int(int64_t)> start_empty_path_class,
62 RoutingTransitCallback2 arc_evaluator);
64
65 bool MakeNeighbor() override;
66 std::string DebugString() const override { return "RelocateNeighbors"; }
67
68 private:
75 bool MoveChainAndRepair(int64_t before_chain, int64_t chain_end,
76 int64_t destination);
77
85 int64_t Reposition(int64_t before_to_move, int64_t up_to);
86
87 RoutingTransitCallback2 arc_evaluator_;
88};
89
94// TODO(user): Add option to prune neighbords where the order of node pairs
95// is violated (ie precedence between pickup and delivery nodes).
96// TODO(user): Move this to local_search.cc if it's generic enough.
97// TODO(user): Detect pairs automatically by parsing the constraint model;
98// we could then get rid of the pair API in the RoutingModel
99// class.
100
114 public:
115 MakePairActiveOperator(const std::vector<IntVar*>& vars,
116 const std::vector<IntVar*>& secondary_vars,
117 std::function<int(int64_t)> start_empty_path_class,
118 const RoutingIndexPairs& pairs);
120 bool MakeNeighbor() override;
121 std::string DebugString() const override { return "MakePairActive"; }
122
123 protected:
124 bool MakeOneNeighbor() override;
125 bool OnSamePathAsPreviousBase(int64_t base_index) override {
128 return true;
129 }
130
131 int64_t GetBaseNodeRestartPosition(int base_index) override;
132
135 bool RestartAtPathStartOnSynchronize() override { return true; }
136
137 private:
138 void OnNodeInitialization() override;
139 int FindNextInactivePair(int pair_index) const;
140 bool ContainsActiveNodes(const std::vector<int64_t>& nodes) const;
141
142 int inactive_pair_;
143 int inactive_pair_first_index_;
144 int inactive_pair_second_index_;
145 const RoutingIndexPairs pairs_;
146};
147
150 public:
151 MakePairInactiveOperator(const std::vector<IntVar*>& vars,
152 const std::vector<IntVar*>& secondary_vars,
153 std::function<int(int64_t)> start_empty_path_class,
154 const RoutingIndexPairs& index_pairs);
155
156 bool MakeNeighbor() override;
157 std::string DebugString() const override { return "MakePairInActive"; }
158};
159
169 public:
170 PairRelocateOperator(const std::vector<IntVar*>& vars,
171 const std::vector<IntVar*>& secondary_vars,
172 std::function<int(int64_t)> start_empty_path_class,
173 const RoutingIndexPairs& index_pairs);
175
176 bool MakeNeighbor() override;
177 std::string DebugString() const override { return "PairRelocateOperator"; }
178
179 protected:
180 bool OnSamePathAsPreviousBase(int64_t base_index) override {
182 return base_index == kPairSecondNodeDestination;
183 }
184 int64_t GetBaseNodeRestartPosition(int base_index) override;
185
186 bool ConsiderAlternatives(int64_t base_index) const override {
187 return base_index == kPairFirstNode;
188 }
189
190 private:
191 bool RestartAtPathStartOnSynchronize() override { return true; }
192
193 static constexpr int kPairFirstNode = 0;
194 static constexpr int kPairFirstNodeDestination = 1;
195 static constexpr int kPairSecondNodeDestination = 2;
196};
197
199 public:
200 LightPairRelocateOperator(const std::vector<IntVar*>& vars,
201 const std::vector<IntVar*>& secondary_vars,
202 std::function<int(int64_t)> start_empty_path_class,
203 const RoutingIndexPairs& index_pairs);
205
206 bool MakeNeighbor() override;
207 std::string DebugString() const override {
208 return "LightPairRelocateOperator";
209 }
210};
211
219 public:
220 PairExchangeOperator(const std::vector<IntVar*>& vars,
221 const std::vector<IntVar*>& secondary_vars,
222 std::function<int(int64_t)> start_empty_path_class,
223 const RoutingIndexPairs& index_pairs);
225
226 bool MakeNeighbor() override;
227 std::string DebugString() const override { return "PairExchangeOperator"; }
228
229 private:
230 bool RestartAtPathStartOnSynchronize() override { return true; }
231 bool ConsiderAlternatives(int64_t base_index) const override { return true; }
232 bool GetPreviousAndSibling(int64_t node, int64_t* previous, int64_t* sibling,
233 int64_t* sibling_previous) const;
234};
235
250 public:
252 const std::vector<IntVar*>& vars,
253 const std::vector<IntVar*>& secondary_vars,
254 std::function<int(int64_t)> start_empty_path_class,
255 const RoutingIndexPairs& index_pairs);
257
258 bool MakeNeighbor() override;
259 std::string DebugString() const override {
260 return "PairExchangeRelocateOperator";
261 }
262
263 protected:
264 bool OnSamePathAsPreviousBase(int64_t base_index) override;
265 int64_t GetBaseNodeRestartPosition(int base_index) override;
266
267 private:
268 bool RestartAtPathStartOnSynchronize() override { return true; }
269 bool GetPreviousAndSibling(int64_t node, int64_t* previous, int64_t* sibling,
270 int64_t* sibling_previous) const;
271 bool MoveNode(int pair, int node, int64_t nodes[2][2], int64_t dest[2][2],
272 int64_t prev[2][2]);
273 bool LoadAndCheckDest(int pair, int node, int64_t base_node,
274 int64_t nodes[2][2], int64_t dest[2][2]) const;
275
276 static constexpr int kFirstPairFirstNode = 0;
277 static constexpr int kSecondPairFirstNode = 1;
278 static constexpr int kFirstPairFirstNodeDestination = 2;
279 static constexpr int kFirstPairSecondNodeDestination = 3;
280 static constexpr int kSecondPairFirstNodeDestination = 4;
281 static constexpr int kSecondPairSecondNodeDestination = 5;
282};
283
295 public:
296 SwapIndexPairOperator(const std::vector<IntVar*>& vars,
297 const std::vector<IntVar*>& path_vars,
298 std::function<int(int64_t)> start_empty_path_class,
299 const RoutingIndexPairs& index_pairs);
301
302 bool MakeNextNeighbor(Assignment* delta, Assignment* deltadelta) override;
303 void OnStart() override;
304 std::string DebugString() const override { return "SwapIndexPairOperator"; }
305
306 private:
309 bool UpdateActiveNodes();
311 void SetNext(int64_t from, int64_t to, int64_t path) {
312 DCHECK_LT(from, number_of_nexts_);
313 SetValue(from, to);
314 if (!ignore_path_vars_) {
315 DCHECK_LT(from + number_of_nexts_, Size());
316 SetValue(from + number_of_nexts_, path);
317 }
318 }
319
320 const RoutingIndexPairs index_pairs_;
321 int pair_index_;
322 int first_index_;
323 int second_index_;
324 int64_t first_active_;
325 int64_t second_active_;
326 std::vector<int64_t> prevs_;
327 const int number_of_nexts_;
328 const bool ignore_path_vars_;
329};
330
334 public:
336 const std::vector<IntVar*>& vars,
337 const std::vector<IntVar*>& secondary_vars,
338 std::function<int(int64_t)> start_empty_path_class,
339 const RoutingIndexPairs& index_pairs);
341
342 bool MakeNextNeighbor(Assignment* delta, Assignment* deltadelta) override;
343 bool MakeNeighbor() override;
344 std::string DebugString() const override {
345 return "IndexPairSwapActiveOperator";
346 }
347
348 private:
349 void OnNodeInitialization() override;
350
351 int inactive_node_;
352};
353
356// TODO(user): Put these methods in an object with helper methods instead
357// of adding a layer to the class hierarchy.
359 public:
361 std::unique_ptr<RoutingFilteredHeuristic> heuristic,
362 bool keep_inverse_values = false);
364
365 protected:
366 virtual bool IncrementPosition() = 0;
370 virtual std::function<int64_t(int64_t)> SetupNextAccessorForNeighbor() = 0;
371
372 std::string HeuristicName() const {
373 std::string heuristic_name = heuristic_->DebugString();
374 const int erase_pos = heuristic_name.find("FilteredHeuristic");
375 if (erase_pos != std::string::npos) {
376 const int expected_name_size = heuristic_name.size() - 17;
377 heuristic_name.erase(erase_pos);
378 // NOTE: Verify that the "FilteredHeuristic" string was at the end of the
379 // heuristic name.
380 DCHECK_EQ(heuristic_name.size(), expected_name_size);
381 }
382 return heuristic_name;
383 }
384
385 // TODO(user): Remove the dependency from RoutingModel by storing an
386 // IntVarFilteredHeuristic here instead and storing information on path
387 // start/ends like PathOperator does (instead of relying on the model).
391
392 private:
393 bool MakeOneNeighbor() override;
394 bool MakeChangesAndInsertNodes();
395
396 int64_t VehicleVarIndex(int64_t node) const { return model_->Size() + node; }
397
398 const std::unique_ptr<RoutingFilteredHeuristic> heuristic_;
399 const bool consider_vehicle_vars_;
400};
401
406 public:
408 std::unique_ptr<RoutingFilteredHeuristic> heuristic);
410
411 std::string DebugString() const override {
412 return absl::StrCat("HeuristicPathLNS(", HeuristicName(), ")");
413 }
414
415 private:
416 void OnStart() override;
417
418 bool IncrementPosition() override;
419 bool CurrentRouteIsEmpty() const;
420 void IncrementCurrentRouteToNextNonEmpty();
421
422 std::function<int64_t(int64_t)> SetupNextAccessorForNeighbor() override;
423
424 int current_route_;
425 int last_route_;
426 bool just_started_;
427};
428
434 public:
436 std::unique_ptr<RoutingFilteredHeuristic> heuristic);
438
439 std::string DebugString() const override {
440 return absl::StrCat("RelocatePathAndHeuristicInsertUnperformed(",
441 HeuristicName(), ")");
442 }
443
444 private:
445 void OnStart() override;
446
447 bool IncrementPosition() override;
448 bool IncrementRoutes();
449
450 std::function<int64_t(int64_t)> SetupNextAccessorForNeighbor() override;
451
452 int route_to_relocate_index_;
453 int last_route_to_relocate_index_;
454 int empty_route_index_;
455 int last_empty_route_index_;
456 std::vector<int> routes_to_relocate_;
457 std::vector<int> empty_routes_;
458 std::vector<int64_t> last_node_on_route_;
459 bool has_unperformed_nodes_;
460 bool just_started_;
461};
462
468 public:
470 std::unique_ptr<RoutingFilteredHeuristic> heuristic,
471 int num_arcs_to_consider,
472 std::function<int64_t(int64_t, int64_t, int64_t)>
473 arc_cost_for_route_start);
475
476 std::string DebugString() const override {
477 return absl::StrCat("HeuristicExpensiveChainLNS(", HeuristicName(), ")");
478 }
479
480 private:
481 void OnStart() override;
482
483 bool IncrementPosition() override;
484 bool IncrementRoute();
485 bool IncrementCurrentArcIndices();
486 bool FindMostExpensiveChainsOnRemainingRoutes();
487
488 std::function<int64_t(int64_t)> SetupNextAccessorForNeighbor() override;
489
490 int current_route_;
491 int last_route_;
492
493 const int num_arcs_to_consider_;
494 std::vector<std::pair<int64_t, int>> most_expensive_arc_starts_and_ranks_;
497 std::pair</*first_arc_index*/ int, /*second_arc_index*/ int>
498 current_expensive_arc_indices_;
499 std::function<int64_t(/*before_node*/ int64_t, /*after_node*/ int64_t,
500 /*path_start*/ int64_t)>
501 arc_cost_for_route_start_;
502
503 bool just_started_;
504};
505
511 public:
513 std::unique_ptr<RoutingFilteredHeuristic> heuristic, int num_close_nodes);
515
516 std::string DebugString() const override {
517 return absl::StrCat("HeuristicCloseNodesLNS(", HeuristicName(), ")");
518 }
519
520 private:
521 void OnStart() override;
522
523 bool IncrementPosition() override;
524
525 std::function<int64_t(int64_t)> SetupNextAccessorForNeighbor() override;
526
527 void RemoveNode(int64_t node);
528 void RemoveNodeAndActiveSibling(int64_t node);
529
530 bool IsActive(int64_t node) const {
531 DCHECK_LT(node, model_->Size());
532 return Value(node) != node && !removed_nodes_[node];
533 }
534
535 int64_t Prev(int64_t node) const {
536 DCHECK_EQ(Value(InverseValue(node)), node);
537 DCHECK_LT(node, new_prevs_.size());
538 return changed_prevs_[node] ? new_prevs_[node] : InverseValue(node);
539 }
540 int64_t Next(int64_t node) const {
541 DCHECK(!model_->IsEnd(node));
542 return changed_nexts_[node] ? new_nexts_[node] : Value(node);
543 }
544
545 std::vector<int64_t> GetActiveSiblings(int64_t node) const;
546
547 const std::vector<std::pair<std::vector<int64_t>, std::vector<int64_t>>>&
548 pickup_delivery_pairs_;
549
550 int current_node_;
551 int last_node_;
552 bool just_started_;
553
554 std::vector<std::vector<int64_t>> close_nodes_;
556 std::vector<int64_t> new_nexts_;
557 SparseBitset<> changed_nexts_;
558 std::vector<int64_t> new_prevs_;
559 SparseBitset<> changed_prevs_;
560};
561
570 public:
571 RelocateExpensiveChain(const std::vector<IntVar*>& vars,
572 const std::vector<IntVar*>& secondary_vars,
573 std::function<int(int64_t)> start_empty_path_class,
574 int num_arcs_to_consider,
575 std::function<int64_t(int64_t, int64_t, int64_t)>
576 arc_cost_for_path_start);
578 bool MakeNeighbor() override;
579 bool MakeOneNeighbor() override;
580
581 std::string DebugString() const override { return "RelocateExpensiveChain"; }
582
583 private:
584 void OnNodeInitialization() override;
585 void IncrementCurrentPath();
586 bool IncrementCurrentArcIndices();
590 bool FindMostExpensiveChainsOnRemainingPaths();
591
592 int num_arcs_to_consider_;
593 int current_path_;
594 std::vector<std::pair<int64_t, int>> most_expensive_arc_starts_and_ranks_;
597 std::pair</*first_arc_index*/ int, /*second_arc_index*/ int>
598 current_expensive_arc_indices_;
599 std::function<int64_t(/*before_node*/ int64_t, /*after_node*/ int64_t,
600 /*path_start*/ int64_t)>
601 arc_cost_for_path_start_;
602 int end_path_;
605 bool has_non_empty_paths_to_explore_;
606};
607
615template <bool swap_first>
617 public:
618 PairNodeSwapActiveOperator(const std::vector<IntVar*>& vars,
619 const std::vector<IntVar*>& secondary_vars,
620 std::function<int(int64_t)> start_empty_path_class,
621 const RoutingIndexPairs& index_pairs);
623
624 bool MakeNextNeighbor(Assignment* delta, Assignment* deltadelta) override;
625 bool MakeNeighbor() override;
626 std::string DebugString() const override {
627 return "PairNodeSwapActiveOperator";
628 }
629
630 protected:
631 bool OnSamePathAsPreviousBase(int64_t base_index) override {
634 return true;
635 }
636
637 int64_t GetBaseNodeRestartPosition(int base_index) override;
638
641 bool RestartAtPathStartOnSynchronize() override { return true; }
642
643 private:
644 void OnNodeInitialization() override;
645
646 int inactive_pair_;
647 RoutingIndexPairs pairs_;
648};
649
650// ==========================================================================
651// Section: Implementations of the template classes declared above.
652
653template <bool swap_first>
655 const std::vector<IntVar*>& vars,
656 const std::vector<IntVar*>& secondary_vars,
657 std::function<int(int64_t)> start_empty_path_class,
658 const RoutingIndexPairs& index_pairs)
659 : PathOperator(vars, secondary_vars, 2, false, false,
660 std::move(start_empty_path_class)),
661 inactive_pair_(0),
662 pairs_(index_pairs) {}
663
664template <bool swap_first>
666 int base_index) {
667 // Base node 1 must be after base node 0 if they are both on the same path.
668 if (base_index == 0 || StartNode(base_index) != StartNode(base_index - 1)) {
669 return StartNode(base_index);
670 } else {
671 return BaseNode(base_index - 1);
672 }
673}
674
675template <bool swap_first>
677 for (int i = 0; i < pairs_.size(); ++i) {
678 if (IsInactive(pairs_[i].first[0]) && IsInactive(pairs_[i].second[0])) {
679 inactive_pair_ = i;
680 return;
681 }
682 }
683 inactive_pair_ = pairs_.size();
684}
685
686template <bool swap_first>
688 Assignment* delta, Assignment* deltadelta) {
689 while (inactive_pair_ < pairs_.size()) {
690 if (!IsInactive(pairs_[inactive_pair_].first[0]) ||
691 !IsInactive(pairs_[inactive_pair_].second[0]) ||
693 ResetPosition();
694 ++inactive_pair_;
695 } else {
696 return true;
697 }
698 }
699 return false;
700}
701
702template <bool swap_first>
704 const int64_t base = BaseNode(0);
705 if (IsPathEnd(base)) {
706 return false;
707 }
708 const int64_t pair_first = pairs_[inactive_pair_].first[0];
709 const int64_t pair_second = pairs_[inactive_pair_].second[0];
710 if (swap_first) {
711 return MakeActive(pair_second, BaseNode(1)) &&
712 MakeActive(pair_first, base) &&
713 MakeChainInactive(pair_first, Next(pair_first));
714 } else {
715 return MakeActive(pair_second, BaseNode(1)) &&
716 MakeActive(pair_first, base) &&
717 MakeChainInactive(pair_second, Next(pair_second));
718 }
719}
720
733 public:
734 RelocateSubtrip(const std::vector<IntVar*>& vars,
735 const std::vector<IntVar*>& secondary_vars,
736 std::function<int(int64_t)> start_empty_path_class,
737 const RoutingIndexPairs& pairs);
738
739 std::string DebugString() const override { return "RelocateSubtrip"; }
740 bool MakeNeighbor() override;
741
742 private:
743 // Relocates the subtrip starting at chain_first_node. It must be a pickup.
744 bool RelocateSubTripFromPickup(int64_t chain_first_node,
745 int64_t insertion_node);
747 bool RelocateSubTripFromDelivery(int64_t chain_last_node,
748 int64_t insertion_node);
749 std::vector<bool> is_pickup_node_;
750 std::vector<bool> is_delivery_node_;
751 std::vector<int> pair_of_node_;
752 // Represents the set of pairs that have been opened during a call to
753 // MakeNeighbor(). This vector must be all false before and after calling
754 // RelocateSubTripFromPickup() and RelocateSubTripFromDelivery().
755 std::vector<bool> opened_pairs_bitset_;
756
757 std::vector<int64_t> rejected_nodes_;
758 std::vector<int64_t> subtrip_nodes_;
759};
760
762 public:
763 ExchangeSubtrip(const std::vector<IntVar*>& vars,
764 const std::vector<IntVar*>& secondary_vars,
765 std::function<int(int64_t)> start_empty_path_class,
766 const RoutingIndexPairs& pairs);
767
768 std::string DebugString() const override { return "ExchangeSubtrip"; }
769 bool MakeNeighbor() override;
770
771 private:
772 // Try to extract a subtrip from base_node (see below) and check that the move
773 // will be canonical.
774 // Given a pickup/delivery pair, this operator could generate the same move
775 // twice, the first time with base_node == pickup, the second time with
776 // base_node == delivery. This happens only when no nodes in the subtrip
777 // remain in the original path, i.e. when rejects is empty after
778 // chain extraction. In that case, we keep only a canonical move out of the
779 // two possibilities, the move where base_node is a pickup.
780 bool ExtractChainsAndCheckCanonical(int64_t base_node,
781 std::vector<int64_t>* rejects,
782 std::vector<int64_t>* subtrip);
783 // Reads the path from base_node forward, collecting subtrip nodes in
784 // subtrip and non-subtrip nodes in rejects.
785 // Non-subtrip nodes will be unmatched delivery nodes.
786 // base_node must be a pickup, and remaining/extracted_nodes must be empty.
787 // Returns true if such chains could be extracted.
788 bool ExtractChainsFromPickup(int64_t base_node, std::vector<int64_t>* rejects,
789 std::vector<int64_t>* subtrip);
790 // Reads the path from base_node backward, collecting subtrip nodes in
791 // subtrip and non-subtrip nodes in rejects.
792 // Non-subtrip nodes will be unmatched pickup nodes.
793 // base_node must be a delivery, and remaining/extracted_nodes must be empty.
794 // Returns true if such chains could be extracted.
795 bool ExtractChainsFromDelivery(int64_t base_node,
796 std::vector<int64_t>* rejects,
797 std::vector<int64_t>* subtrip);
798 void SetPath(const std::vector<int64_t>& path, int path_id);
799
800 // Precompute some information about nodes.
801 std::vector<bool> is_pickup_node_;
802 std::vector<bool> is_delivery_node_;
803 std::vector<int> pair_of_node_;
804 // Represents the set of opened pairs during ExtractChainsFromXXX().
805 std::vector<bool> opened_pairs_set_;
806 // Keep internal structures under hand to avoid reallocation.
807 std::vector<int64_t> rejects0_;
808 std::vector<int64_t> subtrip0_;
809 std::vector<int64_t> rejects1_;
810 std::vector<int64_t> subtrip1_;
811 std::vector<int64_t> path0_;
812 std::vector<int64_t> path1_;
813};
814
815} // namespace operations_research
816
817#endif // OR_TOOLS_CONSTRAINT_SOLVER_ROUTING_NEIGHBORHOODS_H_
#define DCHECK_LT(val1, val2)
Definition: base/logging.h:894
#define DCHECK(condition)
Definition: base/logging.h:890
#define DCHECK_EQ(val1, val2)
Definition: base/logging.h:891
An Assignment is a variable -> domains mapping, used to report solutions to the user.
ExchangeSubtrip(const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, std::function< int(int64_t)> start_empty_path_class, const RoutingIndexPairs &pairs)
std::string DebugString() const override
Filtered heuristic LNS operator, where the destruction phase consists of removing a node and the 'num...
FilteredHeuristicCloseNodesLNSOperator(std::unique_ptr< RoutingFilteredHeuristic > heuristic, int num_close_nodes)
Similar to the heuristic path LNS above, but instead of removing one route entirely,...
FilteredHeuristicExpensiveChainLNSOperator(std::unique_ptr< RoutingFilteredHeuristic > heuristic, int num_arcs_to_consider, std::function< int64_t(int64_t, int64_t, int64_t)> arc_cost_for_route_start)
Class of operators using a RoutingFilteredHeuristic to insert unperformed nodes after changes have be...
FilteredHeuristicLocalSearchOperator(std::unique_ptr< RoutingFilteredHeuristic > heuristic, bool keep_inverse_values=false)
virtual std::function< int64_t(int64_t)> SetupNextAccessorForNeighbor()=0
Virtual method to return the next_accessor to be passed to the heuristic to build a new solution.
SparseBitset removed_nodes_
Keeps track of removed nodes when making a neighbor.
LNS-like operator based on a filtered first solution heuristic to rebuild the solution,...
FilteredHeuristicPathLNSOperator(std::unique_ptr< RoutingFilteredHeuristic > heuristic)
Operator which inserts inactive nodes into a path and makes a pair of active nodes inactive.
IndexPairSwapActiveOperator(const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, std::function< int(int64_t)> start_empty_path_class, const RoutingIndexPairs &index_pairs)
bool MakeNextNeighbor(Assignment *delta, Assignment *deltadelta) override
Redefines MakeNextNeighbor to export a simpler interface.
Specialization of LocalSearchOperator built from an array of IntVars which specifies the scope of the...
bool MakeNextNeighbor(Assignment *delta, Assignment *deltadelta) override
Redefines MakeNextNeighbor to export a simpler interface.
Definition: local_search.cc:76
LightPairRelocateOperator(const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, std::function< int(int64_t)> start_empty_path_class, const RoutingIndexPairs &index_pairs)
Pair-based neighborhood operators, designed to move nodes by pairs (pairs are static and given).
int64_t GetBaseNodeRestartPosition(int base_index) override
Returns the index of the node to which the base node of index base_index must be set to when it reach...
MakePairActiveOperator(const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, std::function< int(int64_t)> start_empty_path_class, const RoutingIndexPairs &pairs)
bool RestartAtPathStartOnSynchronize() override
Required to ensure that after synchronization the operator is in a state compatible with GetBaseNodeR...
bool MakeOneNeighbor() override
This method should not be overridden. Override MakeNeighbor() instead.
bool OnSamePathAsPreviousBase(int64_t base_index) override
Returns true if a base node has to be on the same path as the "previous" base node (base node of inde...
Operator which makes pairs of active nodes inactive.
MakePairInactiveOperator(const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, std::function< int(int64_t)> start_empty_path_class, const RoutingIndexPairs &index_pairs)
Relocate neighborhood which moves chains of neighbors.
MakeRelocateNeighborsOperator(const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, std::function< int(int64_t)> start_empty_path_class, RoutingTransitCallback2 arc_evaluator)
Operator which exchanges the position of two pairs; for both pairs the first node of the pair must be...
PairExchangeOperator(const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, std::function< int(int64_t)> start_empty_path_class, const RoutingIndexPairs &index_pairs)
Operator which exchanges the paths of two pairs (path have to be different).
int64_t GetBaseNodeRestartPosition(int base_index) override
Returns the index of the node to which the base node of index base_index must be set to when it reach...
PairExchangeRelocateOperator(const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, std::function< int(int64_t)> start_empty_path_class, const RoutingIndexPairs &index_pairs)
bool OnSamePathAsPreviousBase(int64_t base_index) override
Returns true if a base node has to be on the same path as the "previous" base node (base node of inde...
Operator which inserts pairs of inactive nodes into a path and makes an active node inactive.
int64_t GetBaseNodeRestartPosition(int base_index) override
Returns the index of the node to which the base node of index base_index must be set to when it reach...
bool MakeNextNeighbor(Assignment *delta, Assignment *deltadelta) override
Redefines MakeNextNeighbor to export a simpler interface.
bool RestartAtPathStartOnSynchronize() override
Required to ensure that after synchronization the operator is in a state compatible with GetBaseNodeR...
PairNodeSwapActiveOperator(const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, std::function< int(int64_t)> start_empty_path_class, const RoutingIndexPairs &index_pairs)
bool OnSamePathAsPreviousBase(int64_t base_index) override
Returns true if a base node has to be on the same path as the "previous" base node (base node of inde...
Operator which moves a pair of nodes to another position where the first node of the pair must be bef...
int64_t GetBaseNodeRestartPosition(int base_index) override
Returns the index of the node to which the base node of index base_index must be set to when it reach...
bool ConsiderAlternatives(int64_t base_index) const override
Indicates if alternatives should be considered when iterating over base nodes.
PairRelocateOperator(const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, std::function< int(int64_t)> start_empty_path_class, const RoutingIndexPairs &index_pairs)
bool OnSamePathAsPreviousBase(int64_t base_index) override
Returns true if a base node has to be on the same path as the "previous" base node (base node of inde...
Base class of the local search operators dedicated to path modifications (a path is a set of nodes li...
RelocateExpensiveChain(const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, std::function< int(int64_t)> start_empty_path_class, int num_arcs_to_consider, std::function< int64_t(int64_t, int64_t, int64_t)> arc_cost_for_path_start)
bool MakeOneNeighbor() override
This method should not be overridden. Override MakeNeighbor() instead.
Heuristic-based local search operator which relocates an entire route to an empty vehicle of differen...
RelocatePathAndHeuristicInsertUnperformedOperator(std::unique_ptr< RoutingFilteredHeuristic > heuristic)
Tries to move subtrips after an insertion node.
RelocateSubtrip(const std::vector< IntVar * > &vars, const std::vector< IntVar * > &secondary_vars, std::function< int(int64_t)> start_empty_path_class, const RoutingIndexPairs &pairs)
std::string DebugString() const override
int64_t Size() const
Returns the number of next variables in the model.
Definition: routing.h:1531
bool IsEnd(int64_t index) const
Returns true if 'index' represents the last node of a route.
Definition: routing.h:1339
Operator which iterates through each alternative of a set of pairs.
void OnStart() override
Called by Start() after synchronizing the operator with the current assignment.
bool MakeNextNeighbor(Assignment *delta, Assignment *deltadelta) override
Redefines MakeNextNeighbor to export a simpler interface.
SwapIndexPairOperator(const std::vector< IntVar * > &vars, const std::vector< IntVar * > &path_vars, std::function< int(int64_t)> start_empty_path_class, const RoutingIndexPairs &index_pairs)
const int64_t & Value(int64_t index) const
Returns the value in the current assignment of the variable of given index.
Collection of objects used to extend the Constraint Solver library.
std::function< int64_t(int64_t, int64_t)> RoutingTransitCallback2
Definition: routing_types.h:43
std::vector< RoutingIndexPair > RoutingIndexPairs
Definition: routing_types.h:46
STL namespace.
int64_t delta
Definition: resource.cc:1694
int nodes