| 282 | } |
| 283 | |
| 284 | ProblemData::VehicleType::VehicleType(size_t numAvailable, |
| 285 | std::vector<Load> capacity, |
| 286 | size_t startDepot, |
| 287 | size_t endDepot, |
| 288 | Cost fixedCost, |
| 289 | Duration twEarly, |
| 290 | Duration twLate, |
| 291 | Duration shiftDuration, |
| 292 | Distance maxDistance, |
| 293 | Cost unitDistanceCost, |
| 294 | Cost unitDurationCost, |
| 295 | size_t profile, |
| 296 | std::optional<Duration> startLate, |
| 297 | std::vector<Load> initialLoad, |
| 298 | std::vector<size_t> reloadDepots, |
| 299 | size_t maxReloads, |
| 300 | Duration maxOvertime, |
| 301 | Cost unitOvertimeCost, |
| 302 | std::string name) |
| 303 | : numAvailable(numAvailable), |
| 304 | startDepot(startDepot), |
| 305 | endDepot(endDepot), |
| 306 | capacity(pad(capacity, initialLoad)), |
| 307 | twEarly(twEarly), |
| 308 | twLate(twLate), |
| 309 | shiftDuration(shiftDuration), |
| 310 | maxDistance(maxDistance), |
| 311 | fixedCost(fixedCost), |
| 312 | unitDistanceCost(unitDistanceCost), |
| 313 | unitDurationCost(unitDurationCost), |
| 314 | profile(profile), |
| 315 | startLate(startLate.value_or(twLate)), |
| 316 | initialLoad(pad(initialLoad, capacity)), |
| 317 | reloadDepots(reloadDepots), |
| 318 | maxReloads(maxReloads), |
| 319 | maxOvertime(maxOvertime), |
| 320 | unitOvertimeCost(unitOvertimeCost), |
| 321 | // We need to check >= 0 here to avoid overflow. If the arguments are |
| 322 | // negative the validation checks further below will raise, so it doesn't |
| 323 | // matter what we set as long as we get to those checks. |
| 324 | maxDuration(shiftDuration >= 0 && maxOvertime >= 0 |
| 325 | && maxOvertime < std::numeric_limits<Duration>::max() |
| 326 | - shiftDuration |
| 327 | ? shiftDuration + maxOvertime |
| 328 | : std::numeric_limits<Duration>::max()), |
| 329 | name(duplicate(name.data())) |
| 330 | { |
| 331 | if (numAvailable == 0) |
| 332 | throw std::invalid_argument("num_available must be > 0."); |
| 333 | |
| 334 | if (std::any_of(capacity.begin(), capacity.end(), isNegative<Load>)) |
| 335 | throw std::invalid_argument("capacity amounts must be >= 0."); |
| 336 | |
| 337 | if (twEarly > this->startLate) |
| 338 | throw std::invalid_argument("tw_early must be <= start_late."); |
| 339 | |
| 340 | if (this->startLate > twLate) |
| 341 | throw std::invalid_argument("start_late must be <= tw_late."); |