| 54 | } // namespace |
| 55 | |
| 56 | ProblemData::Client::Client(Coordinate x, |
| 57 | Coordinate y, |
| 58 | std::vector<Load> delivery, |
| 59 | std::vector<Load> pickup, |
| 60 | Duration serviceDuration, |
| 61 | Duration twEarly, |
| 62 | Duration twLate, |
| 63 | Duration releaseTime, |
| 64 | Cost prize, |
| 65 | bool required, |
| 66 | std::optional<size_t> group, |
| 67 | std::string name) |
| 68 | : x(x), |
| 69 | y(y), |
| 70 | serviceDuration(serviceDuration), |
| 71 | twEarly(twEarly), |
| 72 | twLate(twLate), |
| 73 | delivery(pad(delivery, pickup)), |
| 74 | pickup(pad(pickup, delivery)), |
| 75 | releaseTime(releaseTime), |
| 76 | prize(prize), |
| 77 | required(required), |
| 78 | group(group), |
| 79 | name(duplicate(name.data())) |
| 80 | { |
| 81 | assert(delivery.size() == pickup.size()); |
| 82 | |
| 83 | if (std::any_of(delivery.begin(), delivery.end(), isNegative<Load>)) |
| 84 | throw std::invalid_argument("delivery amounts must be >= 0."); |
| 85 | |
| 86 | if (std::any_of(pickup.begin(), pickup.end(), isNegative<Load>)) |
| 87 | throw std::invalid_argument("pickup amounts must be >= 0."); |
| 88 | |
| 89 | if (serviceDuration < 0) |
| 90 | throw std::invalid_argument("service_duration must be >= 0."); |
| 91 | |
| 92 | if (twEarly > twLate) |
| 93 | throw std::invalid_argument("tw_early must be <= tw_late."); |
| 94 | |
| 95 | if (twEarly < 0) |
| 96 | throw std::invalid_argument("tw_early must be >= 0."); |
| 97 | |
| 98 | if (releaseTime > twLate) |
| 99 | throw std::invalid_argument("release_time must be <= tw_late"); |
| 100 | |
| 101 | if (releaseTime < 0) |
| 102 | throw std::invalid_argument("release_time must be >= 0."); |
| 103 | |
| 104 | if (prize < 0) |
| 105 | throw std::invalid_argument("prize must be >= 0."); |
| 106 | } |
| 107 | |
| 108 | ProblemData::Client::Client(Client const &client) |
| 109 | : x(client.x), |