@@ -292,8 +292,8 @@ LocalSearch<Route,
292292
293293 // Update best_route data required for consistency.
294294 modified_vehicles.insert (best_route);
295- _sol_state.update_route_eval (_sol[best_route]. route , best_route );
296- _sol_state.set_insertion_ranks (_sol[best_route], best_route );
295+ _sol_state.update_route_eval (_sol[best_route]);
296+ _sol_state.set_insertion_ranks (_sol[best_route]);
297297
298298 const auto fixed_cost =
299299 _sol[best_route].empty () ? _input.vehicles [best_route].fixed_cost () : 0 ;
@@ -320,14 +320,14 @@ LocalSearch<Route,
320320 // Update stored data for consistency (except update_route_eval and
321321 // set_insertion_ranks done along the way).
322322 for (const auto v : modified_vehicles) {
323- _sol_state.update_route_bbox (_sol[v]. route , v );
324- _sol_state.update_costs (_sol[v]. route , v );
325- _sol_state.update_skills (_sol[v]. route , v );
326- _sol_state.update_priorities (_sol[v]. route , v );
327- _sol_state.set_node_gains (_sol[v]. route , v );
328- _sol_state.set_edge_gains (_sol[v]. route , v );
329- _sol_state.set_pd_matching_ranks (_sol[v]. route , v );
330- _sol_state.set_pd_gains (_sol[v]. route , v );
323+ _sol_state.update_route_bbox (_sol[v]);
324+ _sol_state.update_costs (_sol[v]);
325+ _sol_state.update_skills (_sol[v]);
326+ _sol_state.update_priorities (_sol[v]);
327+ _sol_state.set_node_gains (_sol[v]);
328+ _sol_state.set_edge_gains (_sol[v]);
329+ _sol_state.set_pd_matching_ranks (_sol[v]);
330+ _sol_state.set_pd_gains (_sol[v]);
331331 }
332332
333333 return modified_vehicles;
@@ -910,13 +910,16 @@ void LocalSearch<Route,
910910 continue ;
911911 }
912912
913+ const unsigned jobs_moved_from_source =
914+ _sol[source].size () - s_rank - 1 ;
915+
913916 const auto & s_fwd_delivery = _sol[source].fwd_deliveries (s_rank);
914917 const auto & s_fwd_pickup = _sol[source].fwd_pickups (s_rank);
915918 const auto & s_bwd_delivery = _sol[source].bwd_deliveries (s_rank);
916919 const auto & s_bwd_pickup = _sol[source].bwd_pickups (s_rank);
917920
918921 Index end_t_rank = _sol[target].size ();
919- if (s_rank + 1 < _sol[source]. size () ) {
922+ if (jobs_moved_from_source > 0 ) {
920923 // There is a route end after s_rank in source route.
921924 const auto s_next_job_rank = _sol[source].route [s_rank + 1 ];
922925 end_t_rank =
@@ -930,6 +933,14 @@ void LocalSearch<Route,
930933 continue ;
931934 }
932935
936+ assert (static_cast <int >(_sol[target].size ()) - t_rank - 1 >= 0 );
937+ if (const unsigned jobs_moved_from_target =
938+ _sol[target].size () - static_cast <unsigned >(t_rank) - 1 ;
939+ jobs_moved_from_source <= 2 && jobs_moved_from_target <= 2 ) {
940+ // One of Relocate, OrOpt, SwapStar, MixedExchange, or no-opt.
941+ continue ;
942+ }
943+
933944 if (t_rank + 1 < static_cast <int >(_sol[target].size ())) {
934945 // There is a route end after t_rank in target route.
935946 const auto t_next_job_rank = _sol[target].route [t_rank + 1 ];
@@ -1824,16 +1835,16 @@ void LocalSearch<Route,
18241835#endif
18251836
18261837 for (auto v_rank : update_candidates) {
1827- _sol_state.update_route_eval (_sol[v_rank]. route , v_rank );
1828- _sol_state.update_route_bbox (_sol[v_rank]. route , v_rank );
1829- _sol_state.update_costs (_sol[v_rank]. route , v_rank );
1830- _sol_state.update_skills (_sol[v_rank]. route , v_rank );
1831- _sol_state.update_priorities (_sol[v_rank]. route , v_rank );
1832- _sol_state.set_insertion_ranks (_sol[v_rank], v_rank );
1833- _sol_state.set_node_gains (_sol[v_rank]. route , v_rank );
1834- _sol_state.set_edge_gains (_sol[v_rank]. route , v_rank );
1835- _sol_state.set_pd_matching_ranks (_sol[v_rank]. route , v_rank );
1836- _sol_state.set_pd_gains (_sol[v_rank]. route , v_rank );
1838+ _sol_state.update_route_eval (_sol[v_rank]);
1839+ _sol_state.update_route_bbox (_sol[v_rank]);
1840+ _sol_state.update_costs (_sol[v_rank]);
1841+ _sol_state.update_skills (_sol[v_rank]);
1842+ _sol_state.update_priorities (_sol[v_rank]);
1843+ _sol_state.set_insertion_ranks (_sol[v_rank]);
1844+ _sol_state.set_node_gains (_sol[v_rank]);
1845+ _sol_state.set_edge_gains (_sol[v_rank]);
1846+ _sol_state.set_pd_matching_ranks (_sol[v_rank]);
1847+ _sol_state.set_pd_gains (_sol[v_rank]);
18371848
18381849 assert (_sol[v_rank].size () <= _input.vehicles [v_rank].max_tasks );
18391850 assert (_input.vehicles [v_rank].ok_for_range_bounds (
@@ -2009,22 +2020,22 @@ void LocalSearch<Route,
20092020 for (std::size_t v = 0 ; v < _sol.size (); ++v) {
20102021 // Update what is required for consistency in
20112022 // remove_from_route.
2012- _sol_state.update_route_eval (_sol[v].route , v);
2013- _sol_state.update_route_bbox (_sol[v].route , v);
2014- _sol_state.set_node_gains (_sol[v].route , v);
2015- _sol_state.set_pd_matching_ranks (_sol[v].route , v);
2016- _sol_state.set_pd_gains (_sol[v].route , v);
2023+ _sol_state.update_costs (_sol[v]);
2024+ _sol_state.update_route_eval (_sol[v]);
2025+ _sol_state.update_route_bbox (_sol[v]);
2026+ _sol_state.set_node_gains (_sol[v]);
2027+ _sol_state.set_pd_matching_ranks (_sol[v]);
2028+ _sol_state.set_pd_gains (_sol[v]);
20172029 }
20182030 }
20192031
20202032 // Update stored data that has not been maintained while
20212033 // removing.
20222034 for (std::size_t v = 0 ; v < _sol.size (); ++v) {
2023- _sol_state.update_costs (_sol[v].route , v);
2024- _sol_state.update_skills (_sol[v].route , v);
2025- _sol_state.update_priorities (_sol[v].route , v);
2026- _sol_state.set_insertion_ranks (_sol[v], v);
2027- _sol_state.set_edge_gains (_sol[v].route , v);
2035+ _sol_state.update_skills (_sol[v]);
2036+ _sol_state.update_priorities (_sol[v]);
2037+ _sol_state.set_insertion_ranks (_sol[v]);
2038+ _sol_state.set_edge_gains (_sol[v]);
20282039 }
20292040
20302041 // Refill jobs.
0 commit comments