diff --git a/CHANGELOG.md b/CHANGELOG.md index 63abdd543..2e514ebe5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ ### Changed +- A mix of empty and non-empty `skills` arrays is allowed in input (#460) - Formatting script updated to use version 10 of clang-format (#452) - vroom will now read json input from stdin if no other input is specified (#457) diff --git a/docs/API.md b/docs/API.md index a5f644754..f4e6879c8 100644 --- a/docs/API.md +++ b/docs/API.md @@ -186,9 +186,14 @@ served by a vehicle that has **all** its required skills. In other words: job `j` is eligible to vehicle `v` iff `j.skills` is included in `v.skills`. -In order to ease modeling problems with no skills required, it is -assumed that there is no restriction at all if no `skills` keys are -provided. +This definition implies in particular that: + +- a task without skills can be served by any vehicle; +- a vehicle without skills can only serve tasks with no particular + need (i.e. without skills as well). + +In order to ease modeling problems with no skills required, not +providing a `skills` key default to providing an empty array. ### Task priorities diff --git a/src/structures/vroom/input/input.cpp b/src/structures/vroom/input/input.cpp index 692231342..8ed9b9ea5 100644 --- a/src/structures/vroom/input/input.cpp +++ b/src/structures/vroom/input/input.cpp @@ -17,7 +17,6 @@ namespace vroom { Input::Input(unsigned amount_size) : _start_loading(std::chrono::high_resolution_clock::now()), - _no_addition_yet(true), _has_TW(false), _homogeneous_locations(true), _geometry(false), @@ -56,18 +55,9 @@ void Input::check_job(Job& job) { std::to_string(_amount_size) + '.'); } - // Ensure that skills are either always or never provided. - if (_no_addition_yet) { - _has_skills = !job.skills.empty(); - _no_addition_yet = false; - } else { - if (_has_skills != !job.skills.empty()) { - throw Exception(ERROR::INPUT, "Missing skills."); - } - } - - // Check for time-windows. - _has_TW |= (!(job.tws.size() == 1) or !job.tws[0].is_default()); + // Check for time-windows and skills. + _has_TW = _has_TW || (!(job.tws.size() == 1) or !job.tws[0].is_default()); + _has_skills = _has_skills || !job.skills.empty(); if (!job.location.user_index()) { // Index of this job in the matrix was not specified upon job @@ -159,18 +149,9 @@ void Input::add_vehicle(const Vehicle& vehicle) { std::to_string(_amount_size) + '.'); } - // Ensure that skills are either always or never provided. - if (_no_addition_yet) { - _has_skills = !current_v.skills.empty(); - _no_addition_yet = false; - } else { - if (_has_skills != !current_v.skills.empty()) { - throw Exception(ERROR::INPUT, "Missing skills."); - } - } - - // Check for time-windows. + // Check for time-windows and skills. _has_TW = _has_TW || !vehicle.tw.is_default(); + _has_skills = _has_skills || !current_v.skills.empty(); bool has_start = current_v.has_start(); bool has_end = current_v.has_end(); @@ -316,11 +297,9 @@ void Input::set_skills_compatibility() { if (_has_skills) { for (std::size_t v = 0; v < vehicles.size(); ++v) { const auto& v_skills = vehicles[v].skills; - assert(!v_skills.empty()); for (std::size_t j = 0; j < jobs.size(); ++j) { bool is_compatible = true; - assert(!jobs[j].skills.empty()); for (const auto& s : jobs[j].skills) { if (v_skills.find(s) == v_skills.end()) { is_compatible = false; diff --git a/src/structures/vroom/input/input.h b/src/structures/vroom/input/input.h index bca4d7e52..3f995aba7 100644 --- a/src/structures/vroom/input/input.h +++ b/src/structures/vroom/input/input.h @@ -31,7 +31,6 @@ class Input { std::chrono::high_resolution_clock::time_point _end_solving; std::chrono::high_resolution_clock::time_point _end_routing; std::unique_ptr _routing_wrapper; - bool _no_addition_yet; bool _has_skills; bool _has_TW; bool _homogeneous_locations;