@@ -57,6 +57,7 @@ and exposed in this file:
5757#include < algorithm>
5858#include < functional>
5959#include < memory>
60+ #include < optional>
6061#include < string>
6162#include < tuple>
6263#include < utility>
@@ -71,11 +72,9 @@ and exposed in this file:
7172#include " absl/time/time.h"
7273#include " absl/types/span.h"
7374#include " ortools/base/base_export.h"
74- #include " ortools/base/logging.h"
7575#include " ortools/base/strong_int.h"
7676#include " ortools/base/strong_vector.h"
7777#include " ortools/base/timer.h"
78- #include " ortools/base/types.h"
7978#include " ortools/constraint_solver/constraint_solver.h"
8079#include " ortools/util/bitset.h"
8180#include " ortools/util/tuple_set.h"
@@ -1800,6 +1799,20 @@ class PathOperator : public IntVarLocalSearchOperator {
18001799 return false ;
18011800 }
18021801
1802+ // / Returns the last node of the chain of length 'chain_length' starting after
1803+ // / 'before_chain'. Returns nullopt if the chain contains 'exclude' or
1804+ // / reaches the end of the path. Returns 'before_chain' if 'chain_length' is
1805+ // / 0.
1806+ std::optional<int64_t > GetChainEnd (int64_t before_chain, int64_t exclude,
1807+ int64_t chain_length) const {
1808+ for (int64_t chain_end = before_chain;
1809+ !IsPathEnd (chain_end) && chain_end != exclude;
1810+ chain_end = Next (chain_end)) {
1811+ if (chain_length-- == 0 ) return chain_end;
1812+ }
1813+ return std::nullopt ;
1814+ }
1815+
18031816 // / Swaps the nodes node1 and node2.
18041817 bool SwapNodes (int64_t node1, int64_t node2) {
18051818 if (IsPathEnd (node1) || IsPathEnd (node2) || IsPathStart (node1) ||
@@ -2446,10 +2459,6 @@ LocalSearchOperator* MakeTwoOpt(
24462459// / therefore not be moved):
24472460// / 1 -> 4 -> 2 -> 3 -> 5
24482461// / 1 -> 3 -> 4 -> 2 -> 5
2449- // /
2450- // / Using Relocate with chain lengths of 1, 2 and 3 together is equivalent to
2451- // / the OrOpt operator on a path. The OrOpt operator is a limited version of
2452- // / 3Opt (breaks 3 arcs on a path).
24532462
24542463LocalSearchOperator* MakeRelocate (
24552464 Solver* solver, const std::vector<IntVar*>& vars,
@@ -2458,9 +2467,17 @@ LocalSearchOperator* MakeRelocate(
24582467 std::function<const std::vector<int>&(int , int )> get_incoming_neighbors =
24592468 nullptr,
24602469 std::function<const std::vector<int>&(int , int )> get_outgoing_neighbors =
2461- nullptr,
2462- int64_t chain_length = 1LL, bool single_path = false,
2463- const std::string& name = "Relocate");
2470+ nullptr);
2471+
2472+ // / ----- OrOpt -----
2473+
2474+ // / Variant of Relocate which relocates chains of nodes of length 1, 2 and 3
2475+ // / within the same path. The OrOpt operator is a limited version of 3Opt
2476+ // / (breaking 3 arcs on a path).
2477+ LocalSearchOperator* MakeOrOpt (
2478+ Solver* solver, const std::vector<IntVar*>& vars,
2479+ const std::vector<IntVar*>& secondary_vars,
2480+ std::function<int (int64_t )> start_empty_path_class);
24642481
24652482// / ----- Exchange -----
24662483
0 commit comments