@@ -1303,7 +1303,7 @@ std::vector<bool> SlopeAndYInterceptToConvexityRegions(
13031303namespace {
13041304// Find a "good" scaling factor for constraints with non-integers coefficients.
13051305// See sat::FindBestScalingAndComputeErrors() for more infos.
1306- double FindBestScaling (const std::vector< double >& coefficients,
1306+ double FindBestScaling (absl::Span< const double > coefficients,
13071307 absl::Span<const double > lower_bounds,
13081308 absl::Span<const double > upper_bounds,
13091309 int64_t max_absolute_activity,
@@ -1722,6 +1722,7 @@ bool DimensionCumulOptimizerCore::SetRouteCumulConstraints(
17221722 solver->SetVariableDisjointBounds (lp_cumul, starts, ends);
17231723 }
17241724 }
1725+ solver->AddRoute (path, lp_cumuls);
17251726 // Create LP variables for slacks.
17261727 std::vector<int > lp_slacks (path_size - 1 , -1 );
17271728 for (int pos = 0 ; pos < path_size - 1 ; ++pos) {
@@ -1966,13 +1967,14 @@ bool DimensionCumulOptimizerCore::SetRouteCumulConstraints(
19661967 // breaks are scheduled, those variables are used both in the pure breaks
19671968 // part and in the break distance part of the model.
19681969 // Otherwise, it doesn't need the variables and they are not created.
1969- std::vector<int > lp_break_start;
1970- std::vector<int > lp_break_duration;
1971- std::vector<int > lp_break_end;
1970+ struct LpBreak {
1971+ int start;
1972+ int end;
1973+ int duration;
1974+ };
1975+ std::vector<LpBreak> lp_breaks;
19721976 if (solver->IsCPSATSolver ()) {
1973- lp_break_start.resize (num_breaks, -1 );
1974- lp_break_duration.resize (num_breaks, -1 );
1975- lp_break_end.resize (num_breaks, -1 );
1977+ lp_breaks.resize (num_breaks, {.start = -1 , .end = -1 , .duration = -1 });
19761978 }
19771979
19781980 std::vector<int > slack_exact_lower_bound_ct (path_size - 1 , -1 );
@@ -2004,29 +2006,26 @@ bool DimensionCumulOptimizerCore::SetRouteCumulConstraints(
20042006 current_route_break_variables_.push_back (-1 );
20052007 continue ;
20062008 }
2007- lp_break_start[br] =
2008- solver->AddVariable (break_start_min, break_start_max);
2009- SET_DEBUG_VARIABLE_NAME (solver, lp_break_start[br],
2009+ lp_breaks[br] = {
2010+ .start = solver->AddVariable (break_start_min, break_start_max),
2011+ .end = solver->AddVariable (break_end_min, break_end_max),
2012+ .duration =
2013+ solver->AddVariable (break_duration_min, break_duration_max)};
2014+ const auto [break_start, break_end, break_duration] = lp_breaks[br];
2015+ SET_DEBUG_VARIABLE_NAME (solver, break_start,
20102016 absl::StrFormat (" lp_break_start(%ld)" , br));
2011- lp_break_end[br] = solver->AddVariable (break_end_min, break_end_max);
2012- SET_DEBUG_VARIABLE_NAME (solver, lp_break_end[br],
2017+ SET_DEBUG_VARIABLE_NAME (solver, break_end,
20132018 absl::StrFormat (" lp_break_end(%ld)" , br));
2014- lp_break_duration[br] =
2015- solver->AddVariable (break_duration_min, break_duration_max);
2016- SET_DEBUG_VARIABLE_NAME (solver, lp_break_duration[br],
2019+ SET_DEBUG_VARIABLE_NAME (solver, break_duration,
20172020 absl::StrFormat (" lp_break_duration(%ld)" , br));
20182021 // start + duration = end.
2019- solver->AddLinearConstraint (0 , 0 ,
2020- {{lp_break_end[br], 1 },
2021- {lp_break_start[br], -1 },
2022- {lp_break_duration[br], -1 }});
2022+ solver->AddLinearConstraint (
2023+ 0 , 0 , {{break_end, 1 }, {break_start, -1 }, {break_duration, -1 }});
20232024 // Record index of variables
2024- all_break_variables_[all_break_variables_offset + 2 * br] =
2025- lp_break_start[br];
2026- all_break_variables_[all_break_variables_offset + 2 * br + 1 ] =
2027- lp_break_end[br];
2028- current_route_break_variables_.push_back (lp_break_start[br]);
2029- current_route_break_variables_.push_back (lp_break_end[br]);
2025+ all_break_variables_[all_break_variables_offset + 2 * br] = break_start;
2026+ all_break_variables_[all_break_variables_offset + 2 * br + 1 ] = break_end;
2027+ current_route_break_variables_.push_back (break_start);
2028+ current_route_break_variables_.push_back (break_end);
20302029 } else {
20312030 if (break_end_min <= vehicle_start_max ||
20322031 vehicle_end_min <= break_start_max) {
@@ -2048,7 +2047,7 @@ bool DimensionCumulOptimizerCore::SetRouteCumulConstraints(
20482047 if (break_end_min <= vehicle_start_max) {
20492048 const int ct = solver->AddLinearConstraint (
20502049 0 , std::numeric_limits<int64_t >::max (),
2051- {{lp_cumuls.front (), 1 }, {lp_break_end [br], -1 }});
2050+ {{lp_cumuls.front (), 1 }, {lp_breaks [br]. end , -1 }});
20522051 const int break_is_before_route = solver->AddVariable (0 , 1 );
20532052 SET_DEBUG_VARIABLE_NAME (
20542053 solver, break_is_before_route,
@@ -2060,7 +2059,7 @@ bool DimensionCumulOptimizerCore::SetRouteCumulConstraints(
20602059 if (vehicle_end_min <= break_start_max) {
20612060 const int ct = solver->AddLinearConstraint (
20622061 0 , std::numeric_limits<int64_t >::max (),
2063- {{lp_break_start [br], 1 }, {lp_cumuls.back (), -1 }});
2062+ {{lp_breaks [br]. start , 1 }, {lp_cumuls.back (), -1 }});
20642063 const int break_is_after_route = solver->AddVariable (0 , 1 );
20652064 SET_DEBUG_VARIABLE_NAME (
20662065 solver, break_is_after_route,
@@ -2124,7 +2123,7 @@ bool DimensionCumulOptimizerCore::SetRouteCumulConstraints(
21242123 solver, break_duration_in_slack,
21252124 absl::StrFormat (" break_duration_in_slack(%ld, %ld)" , br, pos));
21262125 solver->AddProductConstraint (break_duration_in_slack,
2127- {break_in_slack, lp_break_duration [br]});
2126+ {break_in_slack, lp_breaks [br]. duration });
21282127 if (slack_exact_lower_bound_ct[pos] == -1 ) {
21292128 slack_exact_lower_bound_ct[pos] = solver->AddLinearConstraint (
21302129 std::numeric_limits<int64_t >::min (), 0 , {{lp_slacks[pos], -1 }});
@@ -2135,13 +2134,13 @@ bool DimensionCumulOptimizerCore::SetRouteCumulConstraints(
21352134 // 1) break_start >= cumul[pos] + pre_travel[pos]
21362135 const int break_start_after_current_ct = solver->AddLinearConstraint (
21372136 pre_travel[pos], std::numeric_limits<int64_t >::max (),
2138- {{lp_break_start [br], 1 }, {lp_cumuls[pos], -1 }});
2137+ {{lp_breaks [br]. start , 1 }, {lp_cumuls[pos], -1 }});
21392138 solver->SetEnforcementLiteral (break_start_after_current_ct,
21402139 break_in_slack);
21412140 // 2) break_end <= cumul[pos+1] - post_travel[pos]
21422141 const int break_ends_before_next_ct = solver->AddLinearConstraint (
21432142 post_travel[pos], std::numeric_limits<int64_t >::max (),
2144- {{lp_cumuls[pos + 1 ], 1 }, {lp_break_end [br], -1 }});
2143+ {{lp_cumuls[pos + 1 ], 1 }, {lp_breaks [br]. end , -1 }});
21452144 solver->SetEnforcementLiteral (break_ends_before_next_ct,
21462145 break_in_slack);
21472146 }
@@ -2158,10 +2157,10 @@ bool DimensionCumulOptimizerCore::SetRouteCumulConstraints(
21582157 }
21592158 // When this feature is used, breaks are in sorted order.
21602159 for (int br = 1 ; br < num_breaks; ++br) {
2161- if (lp_break_start [br] == -1 || lp_break_start [br - 1 ] == -1 ) continue ;
2160+ if (lp_breaks [br]. start == -1 || lp_breaks [br - 1 ]. start == -1 ) continue ;
21622161 solver->AddLinearConstraint (
21632162 0 , std::numeric_limits<int64_t >::max (),
2164- {{lp_break_end [br - 1 ], -1 }, {lp_break_start [br], 1 }});
2163+ {{lp_breaks [br - 1 ]. end , -1 }, {lp_breaks [br]. start , 1 }});
21652164 }
21662165 }
21672166 for (const auto & distance_duration :
@@ -2201,7 +2200,8 @@ bool DimensionCumulOptimizerCore::SetRouteCumulConstraints(
22012200 solver->AddLinearConstraint (limit, limit,
22022201 {{previous_cover, 1 }, {lp_cumuls.front (), -1 }});
22032202 for (int br = 0 ; br < num_breaks; ++br) {
2204- if (lp_break_start[br] == -1 ) continue ;
2203+ const LpBreak& lp_break = lp_breaks[br];
2204+ if (lp_break.start == -1 ) continue ;
22052205 const int64_t break_end_min = CapSub (breaks[br]->EndMin (), cumul_offset);
22062206 const int64_t break_end_max = CapSub (breaks[br]->EndMax (), cumul_offset);
22072207 // break_is_eligible <=>
@@ -2218,11 +2218,11 @@ bool DimensionCumulOptimizerCore::SetRouteCumulConstraints(
22182218 1 , 1 , {{break_is_eligible, 1 }, {break_is_not_eligible, 1 }});
22192219 const int positive_ct = solver->AddLinearConstraint (
22202220 min_break_duration, std::numeric_limits<int64_t >::max (),
2221- {{lp_break_end[br] , 1 }, {lp_break_start[br] , -1 }});
2221+ {{lp_break. end , 1 }, {lp_break. start , -1 }});
22222222 solver->SetEnforcementLiteral (positive_ct, break_is_eligible);
22232223 const int negative_ct = solver->AddLinearConstraint (
22242224 std::numeric_limits<int64_t >::min (), min_break_duration - 1 ,
2225- {{lp_break_end[br] , 1 }, {lp_break_start[br] , -1 }});
2225+ {{lp_break. end , 1 }, {lp_break. start , -1 }});
22262226 solver->SetEnforcementLiteral (negative_ct, break_is_not_eligible);
22272227 }
22282228 // break_is_eligible => break_cover == break_end + limit.
@@ -2236,7 +2236,7 @@ bool DimensionCumulOptimizerCore::SetRouteCumulConstraints(
22362236 SET_DEBUG_VARIABLE_NAME (solver, break_cover,
22372237 absl::StrFormat (" break_cover(%ld)" , br));
22382238 const int limit_cover_ct = solver->AddLinearConstraint (
2239- limit, limit, {{break_cover, 1 }, {lp_break_end[br] , -1 }});
2239+ limit, limit, {{break_cover, 1 }, {lp_break. end , -1 }});
22402240 solver->SetEnforcementLiteral (limit_cover_ct, break_is_eligible);
22412241 const int empty_cover_ct = solver->AddLinearConstraint (
22422242 CapAdd (vehicle_start_min, limit), CapAdd (vehicle_start_min, limit),
@@ -2255,7 +2255,7 @@ bool DimensionCumulOptimizerCore::SetRouteCumulConstraints(
22552255 {{lp_cumuls.back (), 1 }, {previous_cover, -1 }});
22562256 const int break_start_cover_ct = solver->AddLinearConstraint (
22572257 0 , std::numeric_limits<int64_t >::max (),
2258- {{previous_cover, 1 }, {lp_break_start[br] , -1 }});
2258+ {{previous_cover, 1 }, {lp_break. start , -1 }});
22592259 solver->SetEnforcementLiteral (break_start_cover_ct,
22602260 route_end_is_not_covered);
22612261
0 commit comments