Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
88 commits
Select commit Hold shift + click to select a range
36390b3
Init io node set in importOSMNodes
Grufoony Jan 30, 2025
c0d7d0e
Add general addAgentsRandomly function
Grufoony Jan 30, 2025
c92c5d6
Bugfix
Grufoony Jan 30, 2025
3ef73b2
Logging
Grufoony Jan 30, 2025
9107a59
Formatting
Grufoony Jan 30, 2025
49d79b0
Merge branch 'main' into io_nodes
Grufoony Jan 30, 2025
28da2e4
Update version
Grufoony Jan 30, 2025
ce51ac3
Bugfix + logging
Grufoony Jan 30, 2025
054471c
ChatGPPT optimization
Grufoony Jan 30, 2025
943d578
Add path caching
Grufoony Jan 31, 2025
6e6fb57
Merge branch 'pathCaching' into io_nodes
Grufoony Jan 31, 2025
1fd0ddb
Improve
Grufoony Jan 31, 2025
76f3d46
Merge branch 'pathCaching' into io_nodes
Grufoony Jan 31, 2025
8262983
To revise
Grufoony Jan 31, 2025
b0dc230
First tryal
Grufoony Jan 31, 2025
d88767b
Handle oneway
Grufoony Jan 31, 2025
ae67561
Prova
Grufoony Jan 31, 2025
12c289c
Merge branch 'main' into io_nodes
Grufoony Jan 31, 2025
c15e7bd
Update version
Grufoony Jan 31, 2025
98b3762
Merge branch 'main' into io_nodes
Grufoony Jan 31, 2025
4ff36b2
Update version
Grufoony Jan 31, 2025
fe2f5c0
Fix merge
Grufoony Jan 31, 2025
7f39bfa
Add debug logs
Grufoony Feb 3, 2025
6242461
Merge branch 'main' into io_nodes
Grufoony Feb 3, 2025
c09776c
Info to Debug
Grufoony Feb 3, 2025
f51bbf7
Enhance code security
Grufoony Feb 3, 2025
422f160
Enhance code security
Grufoony Feb 3, 2025
628b5f3
Bugfix
Grufoony Feb 3, 2025
5263389
Remove optional from street dequeue
Grufoony Feb 3, 2025
657a149
To remove asap
Grufoony Feb 3, 2025
e3c31d4
Merge branch 'main' into io_nodes
Grufoony Feb 3, 2025
731a36c
Log messages
Grufoony Feb 4, 2025
56e9d02
Bugfix
Grufoony Feb 4, 2025
69f8a99
Optimize `addAgentsRandomly` functions
Grufoony Feb 5, 2025
1201949
Merge branch 'main' into io_nodes
Grufoony Feb 5, 2025
daa2cf9
Update version
Grufoony Feb 5, 2025
81ac4f9
Fix tests
Grufoony Feb 5, 2025
16be79f
Init porting with a lot of seg faults
Grufoony Feb 7, 2025
0a6f541
Some fixes
Grufoony Feb 7, 2025
ea88684
Assertions
Grufoony Feb 7, 2025
80af522
Merge branch 'main' into implementNewAdjacency
Grufoony Feb 7, 2025
6b22c06
Fix some tests
Grufoony Feb 7, 2025
4ab9b7e
Fix assertions
Grufoony Feb 7, 2025
bc4ce7e
Fix graph tests
Grufoony Feb 7, 2025
cec0bd3
Optimize updatePath function
Grufoony Feb 7, 2025
f8c8a4e
Update version
Grufoony Feb 7, 2025
1c0b0a2
Better
Grufoony Feb 7, 2025
6d8d3ec
Parallelizing
Grufoony Feb 7, 2025
4533964
What about evolving nodes in parallel
Grufoony Feb 7, 2025
88d72e6
Trying to implement TBB
Grufoony Feb 9, 2025
4169247
Fix mac installation
Grufoony Feb 9, 2025
d4d3d17
Merge branch 'main' into optimizePaths
Grufoony Feb 10, 2025
7a5ef15
Will this fix workflows?
Grufoony Feb 10, 2025
80c9ff3
mb
Grufoony Feb 10, 2025
bf969b8
Try to fix codeQL
Grufoony Feb 10, 2025
3456890
Parallilize node loop
Grufoony Feb 10, 2025
d256770
Bugfix
Grufoony Feb 10, 2025
90bd4d6
Merge branch 'parallelNodes' into parallel_io_nodes
Grufoony Feb 10, 2025
0015c43
Fix
Grufoony Feb 10, 2025
b1bae34
Change street evolution algorithm
Grufoony Feb 10, 2025
7225f1c
Merge branch 'newStreetEvolution' into parallelNodes
Grufoony Feb 10, 2025
7de0641
Parallelize streets
Grufoony Feb 10, 2025
43fdec5
Merge branch 'parallelNodes' into parallel_io_nodes
Grufoony Feb 10, 2025
fa0ee5c
Merge branch 'main' into implementNewAdjacency
Grufoony Feb 12, 2025
0258f6b
Bugfixes
Grufoony Feb 12, 2025
11093f9
Refactor dynamics tests
Grufoony Feb 12, 2025
c2a04c3
Merge main
Grufoony Feb 12, 2025
de9b52d
My bad
Grufoony Feb 12, 2025
f906b5b
Almost working
Grufoony Feb 12, 2025
8348e4d
To finish
Grufoony Feb 12, 2025
e93b44c
Add documentation
Grufoony Feb 13, 2025
819994f
Update version
Grufoony Feb 13, 2025
1aa80b8
End of implementation
Grufoony Feb 13, 2025
50d35bf
Merge branch 'main' into implementNewAdjacency
Grufoony Feb 13, 2025
07c29b1
CSC-CSR
Grufoony Feb 13, 2025
7c22984
Bench in microseconds
Grufoony Feb 13, 2025
3e16890
Fix
Grufoony Feb 13, 2025
907157f
Merge
Grufoony Feb 13, 2025
e57f68b
Still merge
Grufoony Feb 13, 2025
8246048
Add empty function to Adj matrix
Grufoony Feb 14, 2025
799bda5
Small refactor
Grufoony Feb 14, 2025
2839ee7
Init managing edge geometries
Grufoony Feb 15, 2025
da03500
Bugfix but not much a bugfix
Grufoony Feb 15, 2025
ebe0b50
Save also edge name
Grufoony Feb 15, 2025
a92501b
Moved geometry vector
Grufoony Feb 15, 2025
15520a5
Automatically set edge angle
Grufoony Feb 15, 2025
7be7599
Merge branch 'main' into edgeGeometry
Grufoony Feb 18, 2025
e218f6a
Some refactoring
Grufoony Feb 18, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/dsm/dsm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

static constexpr uint8_t DSM_VERSION_MAJOR = 2;
static constexpr uint8_t DSM_VERSION_MINOR = 4;
static constexpr uint8_t DSM_VERSION_PATCH = 1;
static constexpr uint8_t DSM_VERSION_PATCH = 2;

static auto const DSM_VERSION =
std::format("{}.{}.{}", DSM_VERSION_MAJOR, DSM_VERSION_MINOR, DSM_VERSION_PATCH);
Expand Down
3 changes: 3 additions & 0 deletions src/dsm/headers/AdjacencyMatrix.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ namespace dsm {
/// @brief Get the number of links in the adjacency matrix
/// @return The number of links in the adjacency matrix
size_t size() const;
/// @brief Check if the adjacency matrix is empty
/// @return True if the adjacency matrix is empty, false otherwise
bool empty() const;
/// @brief Get the number of nodes in the adjacency matrix
/// @return The number of nodes in the adjacency matrix
size_t n() const;
Expand Down
4 changes: 2 additions & 2 deletions src/dsm/headers/Dynamics.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@
}
}

if (path.size() == 0) {
if (path.empty()) {
Logger::error(
std::format("Path with id {} and destination {} is empty. Please check the "
"adjacency matrix.",
Expand Down Expand Up @@ -569,7 +569,7 @@

template <typename agent_t>
Measurement<double> Dynamics<agent_t>::streetMeanDensity(bool normalized) const {
if (m_graph.streetSet().size() == 0) {
if (m_graph.streetSet().empty()) {

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 14.4 rule Note

MISRA 14.4 rule
return Measurement(0., 0.);
}
std::vector<double> densities;
Expand Down
12 changes: 9 additions & 3 deletions src/dsm/headers/Edge.hpp
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
#pragma once

#include <utility>
#include <vector>
#include "../utility/Typedef.hpp"

namespace dsm {
class Edge {
protected:
std::vector<std::pair<double, double>> m_geometry;
Id m_id;
std::pair<Id, Id> m_nodePair;
int m_capacity;
int m_transportCapacity;
double m_angle;

void m_setAngle(std::pair<double, double> srcNodeCoordinates,
std::pair<double, double> dstNodeCoordinates);

public:
/// @brief Construct a new Edge object
/// @param id The edge's id
Expand All @@ -25,12 +30,11 @@ namespace dsm {
std::pair<Id, Id> nodePair,
int capacity = 1,
int transportCapacity = 1,
double angle = 0.0);
std::vector<std::pair<double, double>> geometry = {});

void setCapacity(int capacity);
void setTransportCapacity(int capacity);
void setAngle(std::pair<double, double> srcNodeCoordinates,
std::pair<double, double> dstNodeCoordinates);
void setGeometry(std::vector<std::pair<double, double>> geometry);

/// @brief Get the edge's id
/// @return Id The edge's id
Expand All @@ -45,6 +49,8 @@ namespace dsm {
/// @return std::pair<Id, Id> The edge's node pair, where the first element is the source node id and the second
/// element is the target node id. The pair is (u, v) with the edge u -> v.
std::pair<Id, Id> const& nodePair() const;

std::vector<std::pair<double, double>> const& geometry() const;
/// @brief Get the edge's capacity, in number of agents
/// @return int The edge's capacity, in number of agents
int capacity() const;
Expand Down
16 changes: 10 additions & 6 deletions src/dsm/headers/Graph.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ namespace dsm {
private:
std::unordered_map<Id, std::unique_ptr<Node>> m_nodes;
std::unordered_map<Id, std::unique_ptr<Street>> m_streets;
std::unordered_map<std::string, Id> m_nodeMapping;
AdjacencyMatrix m_adjacencyMatrix;
std::unordered_map<std::string, Id> m_nodeMapping;
std::vector<Id> m_inputNodes;
std::vector<Id> m_outputNodes;
unsigned long long m_maxAgentCapacity;
Expand Down Expand Up @@ -110,9 +110,8 @@ namespace dsm {
/// @brief Build the graph's adjacency matrix and computes max capacity
/// @details The adjacency matrix is built using the graph's streets and nodes. N.B.: The street ids
/// are reassigned using the max node id, i.e. newStreetId = srcId * n + dstId, where n is the max node id.
/// Moreover, street angles and geometries are set using the nodes' coordinates.
void buildAdj();
/// @brief Build the graph's street angles using the node's coordinates
void buildStreetAngles();
/// @brief Adjust the nodes' transport capacity
/// @details The nodes' capacity is adjusted using the graph's streets transport capacity, which may vary basing on the number of lanes. The node capacity will be set to the sum of the incoming streets' transport capacity.
void adjustNodeCapacities();
Expand Down Expand Up @@ -144,14 +143,19 @@ namespace dsm {
/// @throws std::invalid_argument if the file is not found, invalid or the format is not supported
void importOSMEdges(const std::string& fileName);

/// @brief Export the graph's nodes to a csv-like file separated with ';'
/// @param path The path to the file to export the nodes to
/// @details The file format is csv-like, with the first line being the column names: id;lon;lat
void exportNodes(const std::string& fileName);
/// @brief Export the graph's edges to a csv-like file separated with ';'
/// @param path The path to the file to export the edges to
/// @details The file format is csv-like, with the first line being the column names: id;source_id;target_id;name;geometry
void exportEdges(const std::string& fileName);
/// @brief Export the graph's adjacency matrix to a file
/// @param path The path to the file to export the adjacency matrix to (default: ./matrix.dsm)
/// @param isAdj A boolean value indicating if the file contains the adjacency matrix or the distance matrix.
/// @throws std::invalid_argument if the file is not found or invalid
void exportMatrix(std::string path = "./matrix.dsm", bool isAdj = true);
/// @brief Export the nodes' coordinates to a file
/// @param path The path to the file to export the nodes' coordinates to (default: ./nodes.dsm)
void exportCoordinates(std::string const& path = "./coordinates.csv");

/// @brief Add a node to the graph
/// @param node A std::unique_ptr to the node to add
Expand Down
1 change: 1 addition & 0 deletions src/dsm/headers/Road.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ namespace dsm {
double maxSpeed = 13.8888888889,
int nLanes = 1,
std::string name = std::string(),
std::vector<std::pair<double, double>> geometry = {},
std::optional<int> capacity = std::nullopt,
int transportCapacity = 1);
/// @brief Set the mean vehicle length, in meters (default is 5)
Expand Down
66 changes: 37 additions & 29 deletions src/dsm/headers/RoadDynamics.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
std::unordered_map<Id, std::array<unsigned long long, 4>> m_turnCounts;
std::unordered_map<Id, std::array<long, 4>> m_turnMapping;
std::unordered_map<Id, double> m_streetTails;
std::vector<Id> m_agentsToRemove;

/// @brief Get the next street id
/// @param agentId The id of the agent
Expand Down Expand Up @@ -326,7 +327,8 @@
// reset Agent's values
pAgent->reset();
} else {
this->removeAgent(agentId);
m_agentsToRemove.push_back(agentId);
// this->removeAgent(agentId);
}
continue;
}
Expand All @@ -343,7 +345,7 @@
if (destinationNode->isIntersection()) {
auto& intersection = dynamic_cast<Intersection&>(*destinationNode);
auto const delta{nextStreet->deltaAngle(pStreet->angle())};
m_increaseTurnCounts(pStreet->id(), delta);
// m_increaseTurnCounts(pStreet->id(), delta);
intersection.addAgent(delta, agentId);
} else if (destinationNode->isRoundabout()) {
auto& roundabout = dynamic_cast<Roundabout&>(*destinationNode);
Expand Down Expand Up @@ -417,7 +419,7 @@
0, static_cast<Id>(this->m_graph.nNodes() - 1)};
for (const auto& [agentId, agent] : this->agents()) {
if (agent->delay() > 0) {
const auto& street{this->m_graph.streetSet()[agent->streetId().value()]};
const auto& street{this->m_graph.street(agent->streetId().value())};
if (agent->delay() > 1) {
agent->incrementDistance();
} else {
Expand All @@ -434,11 +436,11 @@
bool bArrived{false};
if (!agent->isRandom()) {
if (this->itineraries().at(agent->itineraryId())->destination() ==
street->nodePair().second) {
street->target()) {
agent->updateItinerary();
}
if (this->itineraries().at(agent->itineraryId())->destination() ==
street->nodePair().second) {
street->target()) {
bArrived = true;
}
}
Expand Down Expand Up @@ -719,31 +721,37 @@
bool const bUpdateData =
m_dataUpdatePeriod.has_value() && this->m_time % m_dataUpdatePeriod.value() == 0;
auto const N{this->m_graph.nNodes()};
for (auto const& [nodeId, _] : this->m_graph.nodeSet()) {
for (auto const& srcNodeId : this->m_graph.adjMatrix().getCol(nodeId)) {
auto const streetId{srcNodeId * N + nodeId};
auto const& pStreet{this->m_graph.street(streetId)};
// Logger::info(std::format("Evolving street {}", streetId));
if (bUpdateData) {
m_streetTails[streetId] += pStreet->nExitingAgents();
}
for (auto i = 0; i < pStreet->transportCapacity(); ++i) {
this->m_evolveStreet(pStreet, reinsert_agents);
}
}
}
std::for_each(
this->m_graph.nodeSet().cbegin(),
this->m_graph.nodeSet().cend(),
[&](const auto& pair) {

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 14.4 rule Note

MISRA 14.4 rule

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 13.1 rule Note

MISRA 13.1 rule
for (auto const& sourceId : this->m_graph.adjMatrix().getCol(pair.first)) {
auto const streetId = sourceId * N + pair.first;

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 12.1 rule Note

MISRA 12.1 rule
auto const& pStreet{this->m_graph.street(streetId)};
if (bUpdateData) {
m_streetTails[streetId] += pStreet->nExitingAgents();
}
for (auto i = 0; i < pStreet->transportCapacity(); ++i) {
this->m_evolveStreet(pStreet, reinsert_agents);
}
}
});
std::for_each(this->m_agentsToRemove.cbegin(),
this->m_agentsToRemove.cend(),
[this](const auto& agentId) { this->removeAgent(agentId); });
m_agentsToRemove.clear();
// Move transport capacity agents from each node
for (const auto& [nodeId, pNode] : this->m_graph.nodeSet()) {
for (auto i = 0; i < pNode->transportCapacity(); ++i) {
if (!this->m_evolveNode(pNode)) {
break;
}
}
if (pNode->isTrafficLight()) {
auto& tl = dynamic_cast<TrafficLight&>(*pNode);
++tl; // Increment the counter
}
}
std::for_each(this->m_graph.nodeSet().cbegin(),
this->m_graph.nodeSet().cend(),
[&](const auto& pair) {

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 13.1 rule Note

MISRA 13.1 rule
for (auto i = 0; i < pair.second->transportCapacity(); ++i) {
this->m_evolveNode(pair.second);
}
if (pair.second->isTrafficLight()) {

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 14.4 rule Note

MISRA 14.4 rule
auto& tl = dynamic_cast<TrafficLight&>(*pair.second);
++tl;
}
});
// cycle over agents and update their times
this->m_evolveAgents();
// increment time simulation
Expand Down
2 changes: 2 additions & 0 deletions src/dsm/headers/Street.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ namespace dsm {
double maxSpeed = 13.8888888889,
int nLanes = 1,
std::string name = std::string(),
std::vector<std::pair<double, double>> geometry = {},
std::optional<int> capacity = std::nullopt,
int transportCapacity = 1);
virtual ~Street() = default;
Expand Down Expand Up @@ -131,6 +132,7 @@ namespace dsm {
double maxSpeed = 13.8888888889,
int nLanes = 1,
std::string name = std::string(),
std::vector<std::pair<double, double>> geometry = {},
double flowRate = 1.,
std::optional<int> capacity = std::nullopt,
int transportCapacity = 1);
Expand Down
4 changes: 4 additions & 0 deletions src/dsm/sources/AdjacencyMatrix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ namespace dsm {
assert(m_columnIndices.size() == m_rowIndices.size());
return m_columnIndices.size();
}
bool AdjacencyMatrix::empty() const {
assert(m_columnIndices.size() == m_rowIndices.size());
return m_columnIndices.empty();
}

void AdjacencyMatrix::insert(Id row, Id col) {
m_n = std::max(m_n, static_cast<size_t>(row + 1));
Expand Down
48 changes: 30 additions & 18 deletions src/dsm/sources/Edge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,38 @@
std::pair<Id, Id> nodePair,
int capacity,
int transportCapacity,
double angle)
: m_id(id),
std::vector<std::pair<double, double>> geometry)
: m_geometry{std::move(geometry)},
m_id(id),
m_nodePair(nodePair),
m_capacity{capacity},
m_transportCapacity{transportCapacity},
m_angle{angle} {
m_transportCapacity{transportCapacity} {
if (capacity < 1) {
Logger::error(std::format("Edge capacity ({}) must be greater than 0.", capacity));
}
if (transportCapacity < 1) {
Logger::error(std::format("Edge transport capacity ({}) must be greater than 0.",
transportCapacity));
}
if (std::abs(angle) > 2 * std::numbers::pi) {
Logger::error(
std::format("Edge angle ({}) must be in the range [-2pi, 2pi].", angle));
if (m_geometry.size() > 1) {

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 10.4 rule Note

MISRA 10.4 rule
m_setAngle(m_geometry[m_geometry.size() - 2], m_geometry.back());

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 10.4 rule Note

MISRA 10.4 rule
} else {
m_angle = 0.;
}
}

void Edge::m_setAngle(std::pair<double, double> srcNodeCoordinates,
std::pair<double, double> dstNodeCoordinates) {
// N.B.: lat, lon <==> y, x
double const dx{dstNodeCoordinates.first - srcNodeCoordinates.first};
double const dy{dstNodeCoordinates.second - srcNodeCoordinates.second};
m_angle = std::atan2(dy, dx);
if (m_angle < 0.) {
m_angle += 2 * std::numbers::pi;
}
assert(!(std::abs(m_angle) > 2 * std::numbers::pi));

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 12.1 rule Note

MISRA 12.1 rule
}

void Edge::setCapacity(int capacity) {
if (capacity < 1) {
Logger::error(std::format("Edge capacity ({}) must be greater than 0.", capacity));
Expand All @@ -45,17 +58,13 @@
m_transportCapacity = capacity;
}

void Edge::setAngle(std::pair<double, double> srcNodeCoordinates,
std::pair<double, double> dstNodeCoordinates) {
// N.B.: lat, lon <==> y, x
double const dy{dstNodeCoordinates.first - srcNodeCoordinates.first};
double const dx{dstNodeCoordinates.second - srcNodeCoordinates.second};
double angle{std::atan2(dy, dx)};
if (angle < 0.) {
angle += 2 * std::numbers::pi;
void Edge::setGeometry(std::vector<std::pair<double, double>> geometry) {
m_geometry = std::move(geometry);
if (m_geometry.size() > 1) {

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 10.4 rule Note

MISRA 10.4 rule
m_setAngle(m_geometry[m_geometry.size() - 2], m_geometry.back());

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 10.4 rule Note

MISRA 10.4 rule
} else {
m_angle = 0.;
}
assert(!(std::abs(angle) > 2 * std::numbers::pi));
m_angle = angle;
}

Id Edge::id() const { return m_id; }
Expand All @@ -65,9 +74,12 @@
int Edge::capacity() const { return m_capacity; }
int Edge::transportCapacity() const { return m_transportCapacity; }
double Edge::angle() const { return m_angle; }
std::vector<std::pair<double, double>> const& Edge::geometry() const {

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 12.3 rule Note

MISRA 12.3 rule
return m_geometry;
}

double Edge::deltaAngle(double const previousEdgeAngle) const {
double deltaAngle{this->m_angle - previousEdgeAngle};
double deltaAngle{m_angle - previousEdgeAngle};
if (deltaAngle > std::numbers::pi) {
deltaAngle -= 2 * std::numbers::pi;
} else if (deltaAngle < -std::numbers::pi) {
Expand Down
Loading
Loading