diff --git a/include/cpp_common/base_matrix.hpp b/include/cpp_common/base_matrix.hpp index 3e5b7e0f1..e6629cd9f 100644 --- a/include/cpp_common/base_matrix.hpp +++ b/include/cpp_common/base_matrix.hpp @@ -23,8 +23,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ********************************************************************PGR-GNU*/ -/*! @file */ - #ifndef INCLUDE_CPP_COMMON_BASE_MATRIX_HPP_ #define INCLUDE_CPP_COMMON_BASE_MATRIX_HPP_ #pragma once @@ -32,14 +30,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #include #include #include -#include -#include #include "c_types/typedefs.h" #include "cpp_common/identifiers.hpp" -#include "structures/generic/matrix.h" - typedef struct Matrix_cell_t Matrix_cell_t; namespace vrprouting { @@ -63,9 +57,9 @@ class Base_Matrix { /** @brief Constructs an emtpy matrix */ Base_Matrix() = default; /** @brief Constructs a matrix for only specific identifiers */ - Base_Matrix(Matrix_cell_t *, size_t, const Identifiers&, Multiplier); - Base_Matrix(Vroom_matrix_t *, size_t, const Identifiers &, double); - explicit Base_Matrix(const std::map, Id> &, Multiplier); + Base_Matrix(Matrix_cell_t*, size_t, const Identifiers&, Multiplier); + /** @brief Constructs a matrix for the euclidean */ + Base_Matrix(const std::map, Id>&, Multiplier); /** @name status of the matrix * @{ @@ -73,9 +67,6 @@ class Base_Matrix { /** @brief does the matrix values not given by the user? */ bool has_no_infinity() const; - vroom::Matrix get_vroom_duration_matrix() const; - vroom::Matrix get_vroom_cost_matrix() const; - /** @brief does the matrix obeys the triangle inequality? */ bool obeys_triangle_inequality() const; size_t fix_triangle_inequality(size_t depth = 0); @@ -89,8 +80,6 @@ class Base_Matrix { */ size_t size() const {return m_ids.size();} - /** @brief is the matrix symetric? */ - bool is_symmetric() const; /** @}*/ @@ -108,11 +97,11 @@ class Base_Matrix { /** @brief original id -> idx */ Idx get_index(Id) const; - /** @brief original id -> idx */ + /** @brief idx -> original id */ Id get_original_id(Idx) const; private: - /** @brief Traverses the matrix information to set the ids of the nodes */ + /** @brief set the ids of the nodes */ void set_ids(const std::vector &); /** DATA **/ @@ -124,12 +113,6 @@ class Base_Matrix { * m_time_matrix[i][j] i and j are index from the ids */ std::vector> m_time_matrix; - - /** @brief the cost matrix for vroom - * - * m_cost_matrix[i][j] i and j are index from the ids - */ - std::vector> m_cost_matrix; }; } // namespace base diff --git a/include/cpp_common/vroom_matrix.hpp b/include/cpp_common/vroom_matrix.hpp new file mode 100644 index 000000000..881f362d4 --- /dev/null +++ b/include/cpp_common/vroom_matrix.hpp @@ -0,0 +1,96 @@ +/*PGR-GNU***************************************************************** + +FILE: vroom_matrix.hpp + +Copyright (c) 2024 pgRouting developers +Mail: project@pgrouting.org + +------ + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + ********************************************************************PGR-GNU*/ + +/*! @file */ + +#ifndef INCLUDE_CPP_COMMON_VROOM_MATRIX_HPP_ +#define INCLUDE_CPP_COMMON_VROOM_MATRIX_HPP_ +#pragma once + +#include + +#include +#include +#include +#include +#include + +#include "c_types/typedefs.h" +#include "cpp_common/identifiers.hpp" + + +typedef struct Matrix_cell_t Matrix_cell_t; + +namespace vrprouting { +namespace vroom { + +/** @brief N x N matrix + * + * - The internal data interpretation is done by the user of this class + * - Once created do not modifiy + */ +class Matrix { + public: + /** @brief Constructs an emtpy matrix */ + Matrix() = default; + Matrix(Vroom_matrix_t *, size_t, const Identifiers &, double); + + ::vroom::Matrix<::vroom::Duration> get_vroom_duration_matrix() const; + ::vroom::Matrix<::vroom::Cost> get_vroom_cost_matrix() const; + + /** @brief the size of the matrix */ + size_t size() const {return m_ids.size();} + + /** @brief original id -> idx */ + Idx get_index(Id) const; + + /** @brief original id -> idx */ + Id get_original_id(Idx) const; + + /** @brief has identifier */ + bool has_id(Id) const; + + private: + typedef std::vector>> VMatrix; + + /** @brief does the matrix values not given by the user? */ + bool has_infinity(const VMatrix&) const; + void set_vroom_duration_matrix(const VMatrix&); + void set_vroom_cost_matrix(const VMatrix&); + + /** DATA **/ + /** ordered list of user identifiers */ + std::vector m_ids; + + /** @brief the dureation matrix for vroom */ + ::vroom::Matrix<::vroom::Duration> m_dmatrix; + /** @brief the dureation matrix for vroom */ + ::vroom::Matrix<::vroom::Cost> m_cmatrix; +}; + +} // namespace vroom +} // namespace vrprouting + +#endif // INCLUDE_CPP_COMMON_VROOM_MATRIX_HPP_ diff --git a/include/vroom/vroom.hpp b/include/vroom/vroom.hpp index 704be0955..54d1cf76f 100644 --- a/include/vroom/vroom.hpp +++ b/include/vroom/vroom.hpp @@ -40,7 +40,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #include #include "c_types/typedefs.h" -#include "cpp_common/base_matrix.hpp" +#include "cpp_common/vroom_matrix.hpp" #include "cpp_common/messages.hpp" using Vroom_rt = struct Vroom_rt; @@ -70,40 +70,40 @@ class Vroom : public vrprouting::Messages { void add_vehicles(const Vroom_vehicle_t*, size_t, const Vroom_break_t*, size_t, const Vroom_time_window_t*, size_t); /** @brief sets m_matrix */ - void add_matrix(const vrprouting::base::Base_Matrix&); + void add_matrix(const vrprouting::vroom::Matrix&); /** @brief solves the vroom problem */ std::vector solve(int32_t, int32_t, int32_t); private: - std::vector get_vroom_time_windows(const std::vector&) const; - vroom::Amount get_vroom_amounts(const std::vector&) const; - vroom::Amount get_vroom_amounts(const Amount *amounts, size_t count) const; - vroom::Skills get_vroom_skills(const Skill*, size_t) const; - vroom::Job get_vroom_job( + std::vector<::vroom::TimeWindow> get_vroom_time_windows(const std::vector&) const; + ::vroom::Amount get_vroom_amounts(const std::vector&) const; + ::vroom::Amount get_vroom_amounts(const Amount *amounts, size_t count) const; + ::vroom::Skills get_vroom_skills(const Skill*, size_t) const; + ::vroom::Job get_vroom_job( const Vroom_job_t&, const std::vector&) const; - std::pair get_vroom_shipment( + std::pair<::vroom::Job, ::vroom::Job> get_vroom_shipment( const Vroom_shipment_t&, const std::vector&, const std::vector&) const; - std::vector get_vroom_breaks( + std::vector<::vroom::Break> get_vroom_breaks( const std::vector&, const std::vector&) const; - vroom::Vehicle get_vroom_vehicle( + ::vroom::Vehicle get_vroom_vehicle( const Vroom_vehicle_t&, const std::vector&, const std::vector&) const; - void get_amount(vroom::Amount, Amount**); - StepType get_job_step_type(vroom::JOB_TYPE); - StepType get_step_type(vroom::Step); - std::vector get_results(vroom::Solution); + void get_amount(::vroom::Amount, Amount**); + StepType get_job_step_type(::vroom::JOB_TYPE); + StepType get_step_type(::vroom::Step); + std::vector get_results(::vroom::Solution); private: - std::vector m_jobs; - std::vector> m_shipments; - std::vector m_vehicles; - vrprouting::base::Base_Matrix m_matrix; + std::vector<::vroom::Job> m_jobs; + std::vector> m_shipments; + std::vector<::vroom::Vehicle> m_vehicles; + vrprouting::vroom::Matrix m_matrix; }; } // namespace problem diff --git a/src/cpp_common/CMakeLists.txt b/src/cpp_common/CMakeLists.txt index 658ee6037..cac9cc623 100644 --- a/src/cpp_common/CMakeLists.txt +++ b/src/cpp_common/CMakeLists.txt @@ -5,4 +5,5 @@ ADD_LIBRARY(cpp_common OBJECT assert.cpp alloc.cpp get_check_data.c + vroom_matrix.cpp ) diff --git a/src/cpp_common/base_matrix.cpp b/src/cpp_common/base_matrix.cpp index 61786bab7..a118af62a 100644 --- a/src/cpp_common/base_matrix.cpp +++ b/src/cpp_common/base_matrix.cpp @@ -1,4 +1,5 @@ /*PGR-GNU***************************************************************** + FILE: matrix.cpp Copyright (c) 2015 pgRouting developers @@ -28,20 +29,15 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #include "cpp_common/base_matrix.hpp" -#include -#include -#include #include -#include -#include #include #include +#include +#include +#include -#include "cpp_common/identifiers.hpp" #include "cpp_common/assert.hpp" #include "cpp_common/matrix_cell_t.hpp" -#include "cpp_common/vroom_matrix_t.hpp" - namespace vrprouting { namespace base { @@ -203,7 +199,6 @@ Base_Matrix::get_original_id(Idx index) const { /* * Go to the index in the identifiers vector */ - if (index >= m_ids.size()) { std::ostringstream msg; msg << *this << "\nOut of range" << index; @@ -287,85 +282,6 @@ Base_Matrix::Base_Matrix( } } -/** - * @brief Constructor for VROOM matrix input - * - * @param [in] matrix_rows The set of costs - * @param [in] total_matrix_rows The size of the set of costs - * @param [in] location_ids The location identifiers - * @param [in] scaling_factor Multiplier - * - * @pre data_costs is not empty - * @post ids has all the ids of node_ids - * @post data_costs[from_vid, to_vid] is ignored when from_vid is not in node_ids or to_vid is not in node_ids - * @post costs[from_vid, to_vid] is not has the cell cost when from_vid, to_vid are in node_ids - * @post costs[from_vid, to_vid] = inf when cell from_vid, to_vid does not exist - * @post costs[from_vid, to_vid] = 0 when from_vid = to_vid - * - */ -Base_Matrix::Base_Matrix(Vroom_matrix_t *matrix_rows, size_t total_matrix_rows, - const Identifiers &location_ids, double scaling_factor) { - /* - * Sets the selected nodes identifiers - */ - m_ids.insert(m_ids.begin(), location_ids.begin(), location_ids.end()); - - /* - * Create matrix - */ - m_time_matrix.resize( - m_ids.size(), - std::vector(m_ids.size(), - /* - * Set initial values to infinity - */ - (std::numeric_limits::max)())); - m_cost_matrix.resize( - m_ids.size(), - std::vector(m_ids.size(), (std::numeric_limits::max)())); - - Identifiers inserted; - /* - * Cycle the matrix data - */ - for (size_t i = 0; i < total_matrix_rows; ++i) { - auto cell = matrix_rows[i]; - /* - * skip if row is not from selected nodes - */ - if (!(has_id(cell.start_id) && has_id(cell.end_id))) continue; - - /* - * Save the information. Scale the time matrix according to scaling_factor - */ - m_time_matrix[get_index(cell.start_id)][get_index(cell.end_id)] = - static_cast(std::round(cell.duration / scaling_factor)); - m_cost_matrix[get_index(cell.start_id)][get_index(cell.end_id)] = - static_cast(cell.cost); - - /* - * If the opposite direction is infinity insert the same cost - */ - if (m_time_matrix[get_index(cell.end_id)][get_index(cell.start_id)] == - (std::numeric_limits::max)()) { - m_time_matrix[get_index(cell.end_id)][get_index(cell.start_id)] = - m_time_matrix[get_index(cell.start_id)][get_index(cell.end_id)]; - } - if (m_cost_matrix[get_index(cell.end_id)][get_index(cell.start_id)] == - (std::numeric_limits::max)()) { - m_cost_matrix[get_index(cell.end_id)][get_index(cell.start_id)] = - m_cost_matrix[get_index(cell.start_id)][get_index(cell.end_id)]; - } - } - - /* - * Set the diagonal values to 0 - */ - for (size_t i = 0; i < m_time_matrix.size(); ++i) { - m_time_matrix[i][i] = 0; - m_cost_matrix[i][i] = 0; - } -} /* * constructor for euclidean @@ -396,39 +312,6 @@ Base_Matrix::Base_Matrix(const std::map, Id> & } } -/** - * @brief Get VROOM duration matrix from vrprouting Base Matrix - * - * @return vroom::Matrix The vroom cost matrix - */ -vroom::Matrix -Base_Matrix::get_vroom_duration_matrix() const { - size_t matrix_size = m_ids.size(); - vroom::Matrix vroom_matrix(matrix_size); - for (size_t i = 0; i < matrix_size; i++) { - for (size_t j = 0; j < matrix_size; j++) { - vroom_matrix[i][j] = static_cast(m_time_matrix[i][j]); - } - } - return vroom_matrix; -} - -/** - * @brief Get VROOM cost matrix from vrprouting Base Matrix - * - * @return vroom::Matrix The vroom cost matrix - */ -vroom::Matrix -Base_Matrix::get_vroom_cost_matrix() const { - size_t matrix_size = m_ids.size(); - vroom::Matrix vroom_matrix(matrix_size); - for (size_t i = 0; i < matrix_size; i++) { - for (size_t j = 0; j < matrix_size; j++) { - vroom_matrix[i][j] = static_cast(m_cost_matrix[i][j]); - } - } - return vroom_matrix; -} /** * @returns false at the moment it finds an infinity value @@ -521,26 +404,6 @@ Base_Matrix::fix_triangle_inequality(size_t depth) { return depth; } -bool -Base_Matrix::is_symmetric() const { - for (size_t i = 0; i < m_time_matrix.size(); ++i) { - for (size_t j = 0; j < m_time_matrix.size(); ++j) { - if (0.000001 < std::fabs(m_time_matrix[i][j] - m_time_matrix[j][i])) { - std::ostringstream log; - log << "i \t" << i - << "j \t" << j - << "m_time_matrix[i][j] \t" << m_time_matrix[i][j] - << "m_time_matrix[j][i] \t" << m_time_matrix[j][i] - << "\n"; - log << (*this); - pgassertwm(false, log.str()); - return false; - } - } - } - return true; -} - /** * @param [in,out] log stream variable where to print diff --git a/src/cpp_common/vroom_matrix.cpp b/src/cpp_common/vroom_matrix.cpp new file mode 100644 index 000000000..ead977b2b --- /dev/null +++ b/src/cpp_common/vroom_matrix.cpp @@ -0,0 +1,236 @@ +/*PGR-GNU***************************************************************** +FILE: vroom_matrix.cpp + +Copyright (c) 2024 pgRouting developers +Mail: project@pgrouting.org + +Developer: +Copyright (c) 2024 Celia Virginia Vergara Castillo +Mail: vicky aat erosion.dev + +------ + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + ********************************************************************PGR-GNU*/ + +#include "cpp_common/vroom_matrix.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cpp_common/identifiers.hpp" +#include "cpp_common/assert.hpp" +#include "cpp_common/matrix_cell_t.hpp" +#include "cpp_common/vroom_matrix_t.hpp" + + +namespace vrprouting { +namespace vroom { + +/** + * @param [in] id original identifier + * @returns true when it exists on the saved ids + */ +bool +Matrix::has_id(Id id) const { + auto pos = std::lower_bound(m_ids.cbegin(), m_ids.cend(), id); + return pos != m_ids.end() && *pos == id; +} + +/** + * Given an original node identifier returns the internal index + * @param [in] id + * @returns the position of the identifier + */ +Idx +Matrix::get_index(Id id) const { + auto pos = std::lower_bound(m_ids.begin(), m_ids.end(), id); + if (pos == m_ids.end()) { + std::ostringstream msg; + msg << "Not found " << id; + throw std::make_pair(std::string("(INTERNAL) Matrix: Unable to find node on matrix"), msg.str()); + } + pgassert(pos != m_ids.end()); + + return static_cast(pos - m_ids.begin()); +} + +/** + * Given the internal index, returns the original node identifier + * @param [in] index + * @returns the original node identifier + */ +Id +Matrix::get_original_id(Idx index) const { + if (index >= m_ids.size()) { + std::ostringstream msg; + msg << "Out of range" << index; + throw std::make_pair(std::string("(INTERNAL) Matrix: The given index is out of range"), msg.str()); + } + pgassert(index < m_ids.size()); + + return static_cast(m_ids[index]); +} + + +/** + * @brief Constructor for VROOM matrix input + * + * @param [in] matrix_rows The set of costs + * @param [in] total_matrix_rows The size of the set of costs + * @param [in] location_ids The location identifiers + * @param [in] scaling_factor Multiplier + * + * @pre matrix_rows is not empty + * @post location_ids has all the ids + * @post matrix_rows[u, v] is ignored when u or v are not in location_id + * @post m_dmatrix & m_cmatrix ready to use with vroom + * @throws matrix_rows[u, v] = inf, inf + * + */ +Matrix::Matrix( + Vroom_matrix_t *matrix_rows, size_t total_matrix_rows, + const Identifiers &location_ids, double scaling_factor) { + /* + * Sets the selected nodes identifiers + */ + m_ids.insert(m_ids.begin(), location_ids.begin(), location_ids.end()); + std::vector>> m_matrix; + + /* + * Create matrix + * Set initial values to infinity + */ + m_matrix.resize( + m_ids.size(), + std::vector>(m_ids.size(), + std::make_pair( + (std::numeric_limits::max)(), + (std::numeric_limits::max)()))); + + Identifiers inserted; + /* + * Cycle the matrix data + */ + for (size_t i = 0; i < total_matrix_rows; ++i) { + auto cell = matrix_rows[i]; + /* + * skip if row is not from selected nodes + */ + if (!(has_id(cell.start_id) && has_id(cell.end_id))) continue; + + auto sid = get_index(cell.start_id); + auto eid = get_index(cell.end_id); + + /* + * Save the information. Scale the time matrix according to scaling_factor + */ + m_matrix[sid][eid] = + std::make_pair( + static_cast(std::round(cell.duration / scaling_factor)), + static_cast(cell.cost)); + + /* + * If the opposite direction is infinity insert the same cost + */ + if (m_matrix[eid][sid].second == (std::numeric_limits::max)()) { + m_matrix[eid][sid] = m_matrix[sid][eid]; + } + } + + /* + * Set the diagonal values to 0 + */ + for (size_t i = 0; i < m_matrix.size(); ++i) { + m_matrix[i][i] = std::make_pair(0, 0); + } + + /* + * Verify matrix cells preconditions + */ + if (has_infinity(m_matrix)) { + throw std::string("An Infinity value was found on the Matrix. Might be missing information of a node"); + } + + set_vroom_duration_matrix(m_matrix); + set_vroom_cost_matrix(m_matrix); +} + +::vroom::Matrix<::vroom::Duration> +Matrix::get_vroom_duration_matrix() const { + return m_dmatrix; +} + +::vroom::Matrix<::vroom::Cost> +Matrix::get_vroom_cost_matrix() const { + return m_cmatrix; +} + +/** + * @brief sets the VROOM duration matrix from vrprouting Base Matrix + */ +void +Matrix::set_vroom_duration_matrix(const VMatrix &m_matrix) { + size_t matrix_size = m_ids.size(); + m_dmatrix = ::vroom::Matrix<::vroom::Duration>(matrix_size); + for (size_t i = 0; i < matrix_size; i++) { + for (size_t j = 0; j < matrix_size; j++) { + m_dmatrix[i][j] = static_cast<::vroom::Duration>(m_matrix[i][j].first); + } + } +} + +/** + * @brief sets the VROOM cost matrix from vrprouting Base Matrix + */ +void +Matrix::set_vroom_cost_matrix(const VMatrix &m_matrix) { + size_t matrix_size = m_ids.size(); + m_cmatrix = ::vroom::Matrix<::vroom::Cost>(matrix_size); + for (size_t i = 0; i < matrix_size; i++) { + for (size_t j = 0; j < matrix_size; j++) { + m_cmatrix[i][j] = static_cast<::vroom::Cost>(m_matrix[i][j].second); + } + } +} + +/** + * @returns false at the moment it finds an infinity value + * @returns true otherwise + */ +bool +Matrix::has_infinity(const VMatrix &m_matrix) const { + const auto inf1 = (std::numeric_limits<::vroom::Duration>::max)(); + const auto inf2 = (std::numeric_limits<::vroom::Cost>::max)(); + for (const auto &row : m_matrix) { + for (const auto &val : row) { + /* + * found infinity? + */ + if (val.first == inf1 || val.second == inf2) return true; + } + } + return false; +} + +} // namespace vroom +} // namespace vrprouting diff --git a/src/problem/vroom.cpp b/src/problem/vroom.cpp index 55f08ba59..ba7d301ff 100644 --- a/src/problem/vroom.cpp +++ b/src/problem/vroom.cpp @@ -46,27 +46,27 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #include "cpp_common/vroom_time_window_t.hpp" #include "cpp_common/vroom_vehicle_t.hpp" -#include "cpp_common/base_matrix.hpp" +#include "cpp_common/vroom_matrix.hpp" #include "cpp_common/interruption.hpp" #include "cpp_common/messages.hpp" namespace vrprouting { namespace problem { -std::vector +std::vector<::vroom::TimeWindow> Vroom::get_vroom_time_windows(const std::vector &time_windows) const { - std::vector tws; + std::vector<::vroom::TimeWindow> tws; for (auto time_window : time_windows) { - tws.push_back(vroom::TimeWindow(time_window.tw_open, time_window.tw_close)); + tws.push_back(::vroom::TimeWindow(time_window.tw_open, time_window.tw_close)); } return !tws.empty() ? tws - : std::vector(1, vroom::TimeWindow()); + : std::vector<::vroom::TimeWindow>(1, ::vroom::TimeWindow()); } -vroom::Amount +::vroom::Amount Vroom::get_vroom_amounts(const std::vector &amounts) const { - vroom::Amount amt; + ::vroom::Amount amt; if (!amounts.empty()) { for (auto amount : amounts) { amt.push_back(amount); @@ -75,22 +75,22 @@ Vroom::get_vroom_amounts(const std::vector &amounts) const { const unsigned int amount_size = m_vehicles.size() ? static_cast(m_vehicles[0].capacity.size()) : 0; // Default to zero amount with provided size. - amt = vroom::Amount(amount_size); + amt = ::vroom::Amount(amount_size); } return amt; } -vroom::Amount +::vroom::Amount Vroom::get_vroom_amounts(const Amount *amounts, size_t count) const { return get_vroom_amounts(std::vector(amounts, amounts + count)); } -vroom::Skills +::vroom::Skills Vroom::get_vroom_skills(const Skill *skills, size_t count) const { return std::unordered_set (skills, skills + count); } -vroom::Job +::vroom::Job Vroom::get_vroom_job( const Vroom_job_t &job, const std::vector &job_tws) const { @@ -98,8 +98,8 @@ Vroom::get_vroom_job( auto pickup = get_vroom_amounts(job.pickup, job.pickup_size); auto skills = get_vroom_skills(job.skills, job.skills_size); auto time_windows = get_vroom_time_windows(job_tws); - auto location_id = static_cast(m_matrix.get_index(job.location_id)); - return vroom::Job( + auto location_id = static_cast<::vroom::Index>(m_matrix.get_index(job.location_id)); + return ::vroom::Job( job.id, location_id, job.setup, job.service, delivery, pickup, skills, job.priority, time_windows, job.data); @@ -134,7 +134,7 @@ Vroom::add_jobs(const Vroom_job_t *jobs, size_t count, std::vector(jobs_tws, jobs_tws + total_jobs_tws)); } -std::pair +std::pair<::vroom::Job, ::vroom::Job> Vroom::get_vroom_shipment( const Vroom_shipment_t &shipment, const std::vector &pickup_tws, @@ -143,14 +143,14 @@ Vroom::get_vroom_shipment( auto skills = get_vroom_skills(shipment.skills, shipment.skills_size); auto p_time_windows = get_vroom_time_windows(pickup_tws); auto d_time_windows = get_vroom_time_windows(delivery_tws); - auto p_location_id = static_cast(m_matrix.get_index(shipment.p_location_id)); - auto d_location_id = static_cast(m_matrix.get_index(shipment.d_location_id)); - vroom::Job pickup = vroom::Job( - shipment.id, vroom::JOB_TYPE::PICKUP, p_location_id, + auto p_location_id = static_cast<::vroom::Index>(m_matrix.get_index(shipment.p_location_id)); + auto d_location_id = static_cast<::vroom::Index>(m_matrix.get_index(shipment.d_location_id)); + auto pickup = ::vroom::Job( + shipment.id, ::vroom::JOB_TYPE::PICKUP, p_location_id, shipment.p_setup, shipment.p_service, amount, skills, shipment.priority, p_time_windows, shipment.p_data); - vroom::Job delivery = vroom::Job( - shipment.id, vroom::JOB_TYPE::DELIVERY, d_location_id, + auto delivery = ::vroom::Job( + shipment.id, ::vroom::JOB_TYPE::DELIVERY, d_location_id, shipment.d_setup, shipment.d_service, amount, skills, shipment.priority, d_time_windows, shipment.d_data); return std::make_pair(pickup, delivery); @@ -194,7 +194,7 @@ Vroom::add_shipments( std::vector(shipment_tws, shipment_tws + total_shipment_tws)); } -std::vector +std::vector<::vroom::Break> Vroom::get_vroom_breaks( const std::vector &breaks, const std::vector &breaks_tws) const { @@ -206,36 +206,36 @@ Vroom::get_vroom_breaks( } breaks_tws_map[id].push_back(break_tw); } - std::vector v_breaks; + std::vector<::vroom::Break> v_breaks; for (const auto &v_break : breaks) { v_breaks.push_back( - vroom::Break( + ::vroom::Break( v_break.id, get_vroom_time_windows(breaks_tws_map[v_break.id]), v_break.service, v_break.data)); } return v_breaks; } -vroom::Vehicle +::vroom::Vehicle Vroom::get_vroom_vehicle( const Vroom_vehicle_t &vehicle, const std::vector &breaks, const std::vector &breaks_tws) const { auto capacity = get_vroom_amounts(vehicle.capacity, vehicle.capacity_size); auto skills = get_vroom_skills(vehicle.skills, vehicle.skills_size); - auto time_window = vroom::TimeWindow(vehicle.tw_open, vehicle.tw_close); + auto time_window = ::vroom::TimeWindow(vehicle.tw_open, vehicle.tw_close); auto v_breaks = get_vroom_breaks(breaks, breaks_tws); - std::optional start_id; - std::optional end_id; + std::optional<::vroom::Location> start_id; + std::optional<::vroom::Location> end_id; // Set the value of start or end index only if they are present if (vehicle.start_id != -1) { - start_id = static_cast(m_matrix.get_index(vehicle.start_id)); + start_id = static_cast<::vroom::Index>(m_matrix.get_index(vehicle.start_id)); } if (vehicle.end_id != -1) { - end_id = static_cast(m_matrix.get_index(vehicle.end_id)); + end_id = static_cast<::vroom::Index>(m_matrix.get_index(vehicle.end_id)); } - return vroom::Vehicle(vehicle.id, start_id, end_id, - vroom::DEFAULT_PROFILE, capacity, skills, time_window, + return ::vroom::Vehicle(vehicle.id, start_id, end_id, + ::vroom::DEFAULT_PROFILE, capacity, skills, time_window, v_breaks, vehicle.data, vehicle.speed_factor, static_cast(vehicle.max_tasks)); } @@ -292,12 +292,12 @@ Vroom::add_vehicles(const Vroom_vehicle_t *vehicles, size_t count, * param[in] matrix The matrix */ void -Vroom::add_matrix(const vrprouting::base::Base_Matrix &matrix) { +Vroom::add_matrix(const vrprouting::vroom::Matrix &matrix) { m_matrix = matrix; } void -Vroom::get_amount(vroom::Amount vroom_amount, Amount **amount) { +Vroom::get_amount(::vroom::Amount vroom_amount, Amount **amount) { size_t amount_size = vroom_amount.size(); for (size_t i = 0; i < amount_size; i++) { *((*amount) + i) = vroom_amount[i]; @@ -305,16 +305,16 @@ Vroom::get_amount(vroom::Amount vroom_amount, Amount **amount) { } StepType -Vroom::get_job_step_type(vroom::JOB_TYPE vroom_job_type) { +Vroom::get_job_step_type(::vroom::JOB_TYPE vroom_job_type) { StepType step_type; switch (vroom_job_type) { - case vroom::JOB_TYPE::SINGLE: + case ::vroom::JOB_TYPE::SINGLE: step_type = 2; break; - case vroom::JOB_TYPE::PICKUP: + case ::vroom::JOB_TYPE::PICKUP: step_type = 3; break; - case vroom::JOB_TYPE::DELIVERY: + case ::vroom::JOB_TYPE::DELIVERY: step_type = 4; break; } @@ -322,19 +322,19 @@ Vroom::get_job_step_type(vroom::JOB_TYPE vroom_job_type) { } StepType -Vroom::get_step_type(vroom::Step step) { +Vroom::get_step_type(::vroom::Step step) { StepType step_type = 0; switch (step.step_type) { - case vroom::STEP_TYPE::START: + case ::vroom::STEP_TYPE::START: step_type = 1; break; - case vroom::STEP_TYPE::END: + case ::vroom::STEP_TYPE::END: step_type = 6; break; - case vroom::STEP_TYPE::BREAK: + case ::vroom::STEP_TYPE::BREAK: step_type = 5; break; - case vroom::STEP_TYPE::JOB: + case ::vroom::STEP_TYPE::JOB: step_type = get_job_step_type(step.job_type); break; } @@ -342,9 +342,9 @@ Vroom::get_step_type(vroom::Step step) { } std::vector -Vroom::get_results(vroom::Solution solution) { +Vroom::get_results(::vroom::Solution solution) { std::vector results; - std::vector routes = solution.routes; + auto routes = solution.routes; Idx vehicle_seq = 1; char *empty_desc = strdup("{}"); for (auto route : routes) { @@ -411,7 +411,7 @@ Vroom::get_results(vroom::Solution solution) { vehicle_seq++; } - std::vector unassigned = solution.unassigned; + auto unassigned = solution.unassigned; Idx step_seq = 1; for (auto job : unassigned) { StepType job_step = get_job_step_type(job.type); @@ -441,7 +441,7 @@ Vroom::get_results(vroom::Solution solution) { } // The summary of the entire problem - vroom::Summary summary = solution.summary; + auto summary = solution.summary; Idx vehicle_id = 0; Idx job_id = 0; results.push_back({ @@ -485,7 +485,7 @@ Vroom::solve( const unsigned int amount_size = m_vehicles.size() ? static_cast(m_vehicles[0].capacity.size()) : 0; - vroom::Input problem_instance; + ::vroom::Input problem_instance; problem_instance.set_amount_size(amount_size); for (const auto &vehicle : m_vehicles) { @@ -497,10 +497,10 @@ Vroom::solve( for (const auto &shipment : m_shipments) { problem_instance.add_shipment(shipment.first, shipment.second); } - vroom::Matrix duration_matrix = m_matrix.get_vroom_duration_matrix(); - vroom::Matrix cost_matrix = m_matrix.get_vroom_cost_matrix(); - problem_instance.set_durations_matrix(vroom::DEFAULT_PROFILE, std::move(duration_matrix)); - problem_instance.set_costs_matrix(vroom::DEFAULT_PROFILE, std::move(cost_matrix)); + auto duration_matrix = m_matrix.get_vroom_duration_matrix(); + auto cost_matrix = m_matrix.get_vroom_cost_matrix(); + problem_instance.set_durations_matrix(::vroom::DEFAULT_PROFILE, std::move(duration_matrix)); + problem_instance.set_costs_matrix(::vroom::DEFAULT_PROFILE, std::move(cost_matrix)); unsigned threads = 4; if (timeout < 0) { @@ -513,7 +513,7 @@ Vroom::solve( static_cast(exploration_level), threads, timeout_ms); results = get_results(solution); } - } catch (const vroom::Exception &ex) { + } catch (const ::vroom::Exception &ex) { throw; } catch (const std::exception &ex) { throw; diff --git a/src/vroom/vroom_driver.cpp b/src/vroom/vroom_driver.cpp index 91df5f20f..e90e60782 100644 --- a/src/vroom/vroom_driver.cpp +++ b/src/vroom/vroom_driver.cpp @@ -40,7 +40,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #include "cpp_common/alloc.hpp" #include "cpp_common/assert.hpp" #include "cpp_common/identifiers.hpp" -#include "cpp_common/base_matrix.hpp" +#include "cpp_common/vroom_matrix.hpp" #include "cpp_common/vroom_vehicle_t.hpp" #include "cpp_common/vroom_shipment_t.hpp" #include "cpp_common/vroom_job_t.hpp" @@ -128,6 +128,8 @@ vrp_do_vroom( pgassert(total_vehicles); pgassert(total_matrix_rows); + using Matrix = vrprouting::vroom::Matrix; + auto start_time = std::chrono::high_resolution_clock::now(); Identifiers location_ids; @@ -178,19 +180,7 @@ vrp_do_vroom( /* * Create the matrix. Also, scale the time matrix according to min_speed_factor */ - vrprouting::base::Base_Matrix matrix(matrix_rows, total_matrix_rows, - location_ids, min_speed_factor); - - /* - * Verify matrix cells preconditions - */ - if (!matrix.has_no_infinity()) { - (*return_tuples) = NULL; - (*return_count) = 0; - err << "An Infinity value was found on the Matrix. Might be missing information of a node"; - *err_msg = to_pg_msg(err.str()); - return; - } + Matrix matrix(matrix_rows, total_matrix_rows, location_ids, min_speed_factor); /* * Verify size of matrix cell lies in the limit @@ -218,7 +208,7 @@ vrp_do_vroom( std::chrono::duration_cast(end_time - start_time) .count()); - std::vector < Vroom_rt > results = problem.solve(exploration_level, timeout, loading_time); + std::vector results = problem.solve(exploration_level, timeout, loading_time); auto count = results.size(); if (count == 0) { @@ -257,6 +247,11 @@ vrp_do_vroom( err << except.message; *err_msg = to_pg_msg(err.str().c_str()); *log_msg = to_pg_msg(log.str().c_str()); + } catch (std::string &except) { + (*return_tuples) = free(*return_tuples); + (*return_count) = 0; + *err_msg = to_pg_msg(except.c_str()); + *log_msg = to_pg_msg(log.str().c_str()); } catch (std::exception &except) { (*return_tuples) = free(*return_tuples); (*return_count) = 0;