7 #include <ortools/constraint_solver/routing.h>
8 #include <ortools/constraint_solver/routing_enums.pb.h>
9 #include <ortools/constraint_solver/routing_index_manager.h>
10 #include <ortools/constraint_solver/routing_parameters.h>
19 namespace ortools = operations_research;
23 bool show_log,
double d_tol,
bool redirect_swaths,
24 long int time_limit_seconds,
bool search_for_optimum) {
28 cells,
swaths, shortest_graph, d_tol, redirect_swaths);
31 cov_graph, show_log, time_limit_seconds, search_for_optimum);
33 v_route,
swaths, cov_graph, shortest_graph);
45 for (
auto&&
swaths : swaths_by_cells) {
47 g.
addEdge(s.startPoint(),
cells.closestPointOnBorderTo(s.startPoint()));
48 g.
addEdge(s.endPoint(),
cells.closestPointOnBorderTo(s.endPoint()));
55 for (
size_t i = 0; i <
ring.size()-1; ++i) {
66 std::vector<F2CPoint> nodes = g.
getNodes();
69 for (
int i = 0; i < 2; ++i) {
71 for (
auto&& edge : edges) {
72 size_t from = edge.first;
73 for (
auto&& e : edge.second) {
77 for (
auto&& n : nodes) {
78 if (n != border[0] && n != border[1] && n.distance(border) < d_tol) {
94 double d_tol,
bool redirect_swaths)
const {
96 for (
auto&&
swaths : swaths_by_cells) {
98 F2CPoint mid_p {(s.startPoint() + s.endPoint()) * 0.5};
99 if (redirect_swaths) {
100 g.
addEdge(s.startPoint(), mid_p, 0);
101 g.
addEdge(s.endPoint(), mid_p, 0);
109 for (
const auto&
swaths1 : swaths_by_cells) {
110 for (
const auto& s1 :
swaths1) {
111 auto s1_s = s1.startPoint();
112 auto s1_e = s1.endPoint();
113 for (
const auto& swaths2 : swaths_by_cells) {
114 for (
const auto& s2 : swaths2) {
115 auto s2_s = s2.startPoint();
116 auto s2_e = s2.endPoint();
117 if (redirect_swaths) {
118 g.
addEdge(s1_s, s2_s, shortest_graph);
119 g.
addEdge(s1_e, s2_e, shortest_graph);
120 g.
addEdge(s1_s, s2_e, shortest_graph);
121 g.
addEdge(s1_e, s2_s, shortest_graph);
135 for (
auto&&
swaths : swaths_by_cells) {
138 g.
addEdge(s.startPoint(), deposit, shortest_graph);
139 g.
addEdge(s.endPoint(), deposit, shortest_graph);
141 g.
addEdge(s.startPoint(), deposit, 0);
142 g.
addEdge(s.endPoint(), deposit, 0);
150 const F2CGraph2D& cov_graph,
bool show_log,
long int time_limit_seconds,
151 bool use_guided_local_search)
const {
152 int depot_id =
static_cast<int>(cov_graph.
numNodes()-1);
153 const ortools::RoutingIndexManager::NodeIndex depot{depot_id};
154 ortools::RoutingIndexManager manager(cov_graph.
numNodes(), 1, depot);
155 ortools::RoutingModel routing(manager);
157 const int transit_callback_index = routing.RegisterTransitCallback(
158 [&cov_graph, &manager] (
long long int from,
long long int to) ->
long long int {
159 auto from_node = manager.IndexToNode(from).value();
160 auto to_node = manager.IndexToNode(to).value();
163 routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index);
164 ortools::RoutingSearchParameters searchParameters =
165 ortools::DefaultRoutingSearchParameters();
166 searchParameters.set_use_full_propagation(
false);
167 searchParameters.set_first_solution_strategy(
168 ortools::FirstSolutionStrategy::AUTOMATIC);
169 if (use_guided_local_search) {
170 searchParameters.set_local_search_metaheuristic(
171 ortools::LocalSearchMetaheuristic::GUIDED_LOCAL_SEARCH);
173 searchParameters.set_local_search_metaheuristic(
174 ortools::LocalSearchMetaheuristic::AUTOMATIC);
176 searchParameters.mutable_time_limit()->set_seconds(time_limit_seconds);
177 searchParameters.set_log_search(show_log);
178 const ortools::Assignment* solution =
179 routing.SolveWithParameters(searchParameters);
181 long long int index = routing.Start(0);
182 std::vector<long long int> v_id;
184 index = solution->Value(routing.NextVar(index));
186 while (!routing.IsEnd(index)) {
187 v_id.emplace_back(manager.IndexToNode(index).value());
188 index = solution->Value(routing.NextVar(index));
194 const std::vector<long long int>& route_ids,
200 const size_t NS = swaths_by_cells.
sizeTotal();
201 for (
int i = 0; i < route_ids.size()-2; ++i) {
204 for (
int j = 0; j < NS; ++j) {
211 route.addSwath(swath, shortest_graph);
219 route.addSwath(swath, shortest_graph);