Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ authors:
repository-code: 'https://github.com/physycom/DynamicalSystemFramework'
url: 'https://physycom.github.io/DynamicalSystemFramework/'
license: CC-BY-NC-SA-4.0
version: 5.3.3
date-released: '2026-04-09'
version: 5.3.4
date-released: '2026-04-13'
9 changes: 4 additions & 5 deletions benchmark/Bench_Network.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@
network.importNodeProperties((DATA_FOLDER / "forlì_nodes.csv").string());
auto itNode = network.nodes().cbegin();
for (auto _ : state) {
auto paths = network.allPathsTo(itNode->first,
[](auto const& pEdge) { return pEdge->length(); });
auto paths =
network.allPathsTo(itNode->first, [](auto const& edge) { return edge.length(); });

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 15.5 rule Note test

MISRA 15.5 rule
++itNode;
}
}
Expand All @@ -75,9 +75,8 @@
auto itSource = network.nodes().cbegin();
auto itTarget = std::next(network.nodes().cbegin(), network.nodes().size() / 2);
for (auto _ : state) {
auto path = network.shortestPath(itSource->first,
itTarget->first,
[](auto const& pEdge) { return pEdge->length(); });
auto path = network.shortestPath(
itSource->first, itTarget->first, [](auto const& edge) { return edge.length(); });

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 15.5 rule Note test

MISRA 15.5 rule
benchmark::DoNotOptimize(path);
++itSource;
++itTarget;
Expand Down
6 changes: 3 additions & 3 deletions examples/stalingrado.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
graph.addStreets(s01, s12, s23, s34);
graph.adjustNodeCapacities();
graph.addCoil(19);
auto const& coil = graph.edge(19);
auto& coil = graph.edge(19);

// Create the dynamics
FirstOrderDynamics dynamics{graph, false, 69};
Expand All @@ -101,8 +101,8 @@
++it;
}
if (progress % 300 == 0) {
ofs << progress << ';' << coil->counts() << std::endl;
coil->resetCounter();
ofs << progress << ';' << coil.counts() << std::endl;

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 10.1 rule Note

MISRA 10.1 rule
coil.resetCounter();
}
dynamics.addAgents(*it, pItinerary, 0);
}
Expand Down
15 changes: 9 additions & 6 deletions profiling/parse_massif.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,17 @@

const char equal{'='};
std::string buffer;
while (getline(file, buffer)) {
while (std::getline(file, buffer)) {

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 14.4 rule Note

MISRA 14.4 rule
if (buffer.find("mem_heap_B") != std::string::npos) {
std::stringstream buffer_stream(buffer);
std::string value;
getline(buffer_stream, value, equal);
std::getline(buffer_stream, value, equal);
if (value == "mem_heap_B") {
getline(buffer_stream, value);
std::getline(buffer_stream, value);
mem_values.push_back(std::stol(value));
}
}
}

file.close();
return mem_values;
};

Expand All @@ -39,7 +37,12 @@
}

auto mem_values{parse_massif(argv[1])};
long long int integral{std::accumulate(mem_values.begin(), mem_values.end(), 0)};
if (mem_values.empty()) {

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 14.4 rule Note

MISRA 14.4 rule
std::cerr << "No mem_heap_B values found in file: " << argv[1] << '\n';
return 1;

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 15.5 rule Note

MISRA 15.5 rule
}

long long integral{std::accumulate(mem_values.begin(), mem_values.end(), 0LL)};
long max_mem{*std::max_element(mem_values.begin(), mem_values.end())};

std::cout << "integral: " << integral << " B\n";
Expand Down
3 changes: 3 additions & 0 deletions src/dsf/base/Dynamics.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ namespace dsf {
/// @brief Get the graph
/// @return const network_t&, The graph
inline auto const& graph() const { return m_graph; };
/// @brief Get the graph (mutable)
/// @return network_t&, The graph
inline auto& graph() { return m_graph; };
/// @brief Get the id of the simulation
/// @return const Id&, The id of the simulation
inline auto const& id() const { return m_id; };
Expand Down
87 changes: 33 additions & 54 deletions src/dsf/base/Network.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,22 +65,22 @@

/// @brief Get a node by id
/// @param nodeId The node's id
/// @return std::unique_ptr<node_t> const& A const reference to the node
std::unique_ptr<node_t> const& node(Id nodeId) const;
/// @return const node_t& A reference to the node
inline const auto& node(Id nodeId) const { return *m_nodes.at(nodeId); };
/// @brief Get a node by id
/// @param nodeId The node's id
/// @return std::unique_ptr<node_t>& A reference to the node
std::unique_ptr<node_t>& node(Id nodeId);
/// @return node_t& A reference to the node
inline auto& node(Id nodeId) { return *m_nodes.at(nodeId); };
/// @brief Get an edge by id
/// @param edgeId The edge's id
/// @return std::unique_ptr<edge_t> const& A const reference to the edge
std::unique_ptr<edge_t> const& edge(Id edgeId) const;
/// @return const edge_t& A reference to the edge
inline const auto& edge(Id edgeId) const { return *m_edges.at(edgeId); };
/// @brief Get an edge by id
/// @param edgeId The edge's id
/// @return std::unique_ptr<edge_t>& A reference to the edge
std::unique_ptr<edge_t>& edge(Id edgeId);
/// @return edge_t& A reference to the edge
inline auto& edge(Id edgeId) { return *m_edges.at(edgeId); }

std::unique_ptr<edge_t> const& edge(Id source, Id target) const;
edge_t& edge(Id source, Id target) const;
/// @brief Get a node by id
Comment thread
Grufoony marked this conversation as resolved.
/// @tparam TNode The type of the node
/// @param nodeId The node's id
Expand All @@ -97,29 +97,29 @@
TEdge& edge(Id edgeId);

/// @brief Compute betweenness centralities for all nodes using Brandes' algorithm
/// @tparam WeightFunc A callable type that takes a const reference to a unique_ptr<edge_t> and returns a double representing the edge weight
/// @param getEdgeWeight A callable that takes a const reference to a unique_ptr<edge_t> and returns a double (must be positive)
/// @tparam WeightFunc A callable type that takes a const reference to edge_t and returns a double representing the edge weight
/// @param getEdgeWeight A callable that takes a const reference to edge_t and returns a double (must be positive)
/// @details Implements Brandes' algorithm for directed weighted graphs.
/// The computed centrality for each node v is:
/// C_B(v) = sum_{s != v != t} sigma_st(v) / sigma_st
/// where sigma_st is the number of shortest paths from s to t,
/// and sigma_st(v) is the number of those paths passing through v.
/// Results are stored via Node::setBetweennessCentrality.
template <typename WeightFunc>
requires(std::is_invocable_r_v<double, WeightFunc, std::unique_ptr<edge_t> const&>)
requires(std::is_invocable_r_v<double, WeightFunc, edge_t const&>)

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 12.3 rule Note

MISRA 12.3 rule
void computeBetweennessCentralities(WeightFunc getEdgeWeight);

/// @brief Compute edge betweenness centralities for all edges using Brandes' algorithm
/// @tparam WeightFunc A callable type that takes a const reference to a unique_ptr<edge_t> and returns a double representing the edge weight
/// @param getEdgeWeight A callable that takes a const reference to a unique_ptr<edge_t> and returns a double (must be positive)
/// @tparam WeightFunc A callable type that takes a const reference to edge_t and returns a double representing the edge weight
/// @param getEdgeWeight A callable that takes a const reference to edge_t and returns a double (must be positive)
/// @details Implements Brandes' algorithm for directed weighted graphs.
/// The computed centrality for each edge e is:
/// C_B(e) = sum_{s != t} sigma_st(e) / sigma_st
/// where sigma_st is the number of shortest paths from s to t,
/// and sigma_st(e) is the number of those paths using edge e.
/// Results are stored via Edge::setBetweennessCentrality.
template <typename WeightFunc>
requires(std::is_invocable_r_v<double, WeightFunc, std::unique_ptr<edge_t> const&>)
requires(std::is_invocable_r_v<double, WeightFunc, edge_t const&>)

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 12.3 rule Note

MISRA 12.3 rule
void computeEdgeBetweennessCentralities(WeightFunc getEdgeWeight);
};
template <typename node_t, typename edge_t>
Expand Down Expand Up @@ -213,43 +213,22 @@
}

// Get fresh references to both nodes after all potential vector reallocations
auto const& sourceNode = node(sourceNodeId);
auto const& targetNode = node(targetNodeId);
sourceNode->addOutgoingEdge(tmpEdge.id());
targetNode->addIngoingEdge(tmpEdge.id());
auto& sourceNode = node(sourceNodeId);
auto& targetNode = node(targetNodeId);
sourceNode.addOutgoingEdge(tmpEdge.id());
targetNode.addIngoingEdge(tmpEdge.id());
if (geometry.empty()) {
if (sourceNode->geometry().has_value() && targetNode->geometry().has_value()) {
if (sourceNode.geometry().has_value() && targetNode.geometry().has_value()) {
tmpEdge.setGeometry(
dsf::geometry::PolyLine{*sourceNode->geometry(), *targetNode->geometry()});
dsf::geometry::PolyLine{*sourceNode.geometry(), *targetNode.geometry()});
}
}
m_edges.emplace(tmpEdge.id(), std::make_unique<TEdge>(std::move(tmpEdge)));
}

template <typename node_t, typename edge_t>
requires(std::is_base_of_v<Node, node_t> && std::is_base_of_v<Edge, edge_t>)
std::unique_ptr<node_t> const& Network<node_t, edge_t>::node(Id nodeId) const {
return m_nodes.at(nodeId);
}
template <typename node_t, typename edge_t>
requires(std::is_base_of_v<Node, node_t> && std::is_base_of_v<Edge, edge_t>)
std::unique_ptr<node_t>& Network<node_t, edge_t>::node(Id nodeId) {
return m_nodes.at(nodeId);
}
template <typename node_t, typename edge_t>
requires(std::is_base_of_v<Node, node_t> && std::is_base_of_v<Edge, edge_t>)
std::unique_ptr<edge_t> const& Network<node_t, edge_t>::edge(Id edgeId) const {
return m_edges.at(edgeId);
}
template <typename node_t, typename edge_t>
requires(std::is_base_of_v<Node, node_t> && std::is_base_of_v<Edge, edge_t>)
std::unique_ptr<edge_t>& Network<node_t, edge_t>::edge(Id edgeId) {
return m_edges.at(edgeId);
}
template <typename node_t, typename edge_t>
requires(std::is_base_of_v<Node, node_t> && std::is_base_of_v<Edge, edge_t>)
std::unique_ptr<edge_t> const& Network<node_t, edge_t>::edge(Id source,
Id target) const {
edge_t& Network<node_t, edge_t>::edge(Id source, Id target) const {

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 12.3 rule Note

MISRA 12.3 rule
auto const it = std::find_if(
m_edges.cbegin(), m_edges.cend(), [source, target](auto const& pair) {
return pair.second->source() == source && pair.second->target() == target;
Expand All @@ -258,28 +237,28 @@
throw std::out_of_range(
std::format("Edge with source {} and target {} not found.", source, target));
}
return it->second;
return *it->second;

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 15.5 rule Note

MISRA 15.5 rule
}

template <typename node_t, typename edge_t>
requires(std::is_base_of_v<Node, node_t> && std::is_base_of_v<Edge, edge_t>)
template <typename TNode>
requires(std::is_base_of_v<node_t, TNode>)
TNode& Network<node_t, edge_t>::node(Id nodeId) {
return dynamic_cast<TNode&>(*node(nodeId));
return dynamic_cast<TNode&>(node(nodeId));

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 15.5 rule Note

MISRA 15.5 rule
}
template <typename node_t, typename edge_t>
requires(std::is_base_of_v<Node, node_t> && std::is_base_of_v<Edge, edge_t>)
template <typename TEdge>
requires(std::is_base_of_v<edge_t, TEdge>)
TEdge& Network<node_t, edge_t>::edge(Id edgeId) {
return dynamic_cast<TEdge&>(*edge(edgeId));
return dynamic_cast<TEdge&>(edge(edgeId));

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 15.5 rule Note

MISRA 15.5 rule
}

template <typename node_t, typename edge_t>
requires(std::is_base_of_v<Node, node_t> && std::is_base_of_v<Edge, edge_t>)
template <typename WeightFunc>
requires(std::is_invocable_r_v<double, WeightFunc, std::unique_ptr<edge_t> const&>)
requires(std::is_invocable_r_v<double, WeightFunc, edge_t const&>)

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 12.3 rule Note

MISRA 12.3 rule
void Network<node_t, edge_t>::computeBetweennessCentralities(WeightFunc getEdgeWeight) {
// Initialize all node betweenness centralities to 0
for (auto& [nodeId, pNode] : m_nodes) {
Expand Down Expand Up @@ -321,12 +300,12 @@
S.push(v);

for (auto const& edgeId : m_nodes.at(v)->outgoingEdges()) {
auto const& pEdge = m_edges.at(edgeId);
Id w = pEdge->target();
auto const& edgeObj = *m_edges.at(edgeId);
Id w = edgeObj.target();
if (visited.contains(w)) {
continue;
}
double edgeWeight = getEdgeWeight(pEdge);
double edgeWeight = getEdgeWeight(edgeObj);
double newDist = dist[v] + edgeWeight;

if (newDist < dist[w]) {
Expand Down Expand Up @@ -364,7 +343,7 @@
template <typename node_t, typename edge_t>
requires(std::is_base_of_v<Node, node_t> && std::is_base_of_v<Edge, edge_t>)
template <typename WeightFunc>
requires(std::is_invocable_r_v<double, WeightFunc, std::unique_ptr<edge_t> const&>)
requires(std::is_invocable_r_v<double, WeightFunc, edge_t const&>)

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 12.3 rule Note

MISRA 12.3 rule
void Network<node_t, edge_t>::computeEdgeBetweennessCentralities(
WeightFunc getEdgeWeight) {
// Initialize all edge betweenness centralities to 0
Expand Down Expand Up @@ -408,12 +387,12 @@
S.push(v);

for (auto const& eId : m_nodes.at(v)->outgoingEdges()) {
auto const& pEdge = m_edges.at(eId);
Id w = pEdge->target();
auto const& edgeObj = *m_edges.at(eId);
Id w = edgeObj.target();
if (visited.contains(w)) {
continue;
}
double edgeWeight = getEdgeWeight(pEdge);
double edgeWeight = getEdgeWeight(edgeObj);
double newDist = dist[v] + edgeWeight;

if (newDist < dist[w]) {
Expand Down
Loading
Loading