Skip to content
Open
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
10 changes: 10 additions & 0 deletions cpp/cmake/boost.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
set(BOOST_INCLUDE_LIBRARIES heap)
set(BOOST_ENABLE_CMAKE ON)
include(FetchContent)
FetchContent_Declare(
Boost
URL https://github.com/boostorg/boost/releases/download/boost-1.87.0/boost-1.87.0-cmake.tar.gz
USES_TERMINAL_DOWNLOAD TRUE
DOWNLOAD_NO_EXTRACT FALSE
)
FetchContent_MakeAvailable(Boost)
91 changes: 91 additions & 0 deletions cpp/include/algo_analysis/algorithms/dijkstra_with_fib.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#ifndef DIJKSTRA_WITH_FIB_HPP
#define DIJKSTRA_WITH_FIB_HPP


#include <algo_analysis/algorithms/algorithm.hpp>
#include <algo_analysis/graphs/adjacency_list_graph.hpp>
#include <boost/heap/fibonacci_heap.hpp>
#include <iostream>
#include <algorithm>
#include <queue>

// Dijkstra's algorithm
template<typename WeightType>
struct DijkstraWithFibAlgorithm : public Algorithm<WeightType> {
using Edge = Edge<WeightType>;

// Graph representation
struct Graph : public AdjacencyListGraph<WeightType> {
using BaseClass = AdjacencyListGraph<WeightType>;

size_t nodesNumber;

Graph() : BaseClass() {}

Graph(const std::vector<Edge> &edges): BaseClass(edges) {
nodesNumber = BaseClass::neighbors.size();
}
};

struct Node {
size_t vertex;
WeightType distance;

bool operator>(const Node& other) const {
return distance > other.distance;
}
};


std::vector<WeightType> distances; // Distances from the start node
Graph graph;

DijkstraWithFibAlgorithm() {

}

WeightType inf;

// Fit the algorithm to the graph
void fit(const EdgesListGraph<WeightType> &graph_) override {
graph = Graph(graph_.edges);
inf = 1;
for (const Edge &edge : graph_.edges) {
inf += edge.weight;
}
}

// Compute distances from the start node
std::vector<WeightType> computeDistances(size_t startIndex) override {
int n = graph.nodesNumber;
distances = std::vector<WeightType>(n, inf);
distances[startIndex] = 0;

boost::heap::fibonacci_heap<Node, boost::heap::compare<std::greater<Node>>> q;
q.push({ startIndex, 0 });

while (!q.empty()) {
auto [ u, dist ] = q.top();
q.pop();

if (dist > distances[u]) continue;

for (const Edge& edge : graph.neighbors[u]) {
size_t v = edge.toIndex;
WeightType newDist = distances[u] + edge.weight;

if (newDist < distances[v]) {
distances[v] = newDist;
q.push({ v, newDist });
}
}
}

return distances;
}

};



#endif
92 changes: 92 additions & 0 deletions cpp/include/algo_analysis/algorithms/floid.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#ifndef FLOID_HPP
#define FLOID_HPP

#include <algo_analysis/algorithms/algorithm.hpp>
#include <algo_analysis/graphs/adjacency_list_graph.hpp>
#include <iostream>
#include <queue>

// Floid algorithm
template <typename WeightType>
struct FloidAlgorithm : public Algorithm<WeightType> {
using Edge = Edge<WeightType>;

// Graph representation
struct Graph : public AdjacencyListGraph<WeightType> {
using BaseClass = AdjacencyListGraph<WeightType>;

size_t nodesNumber;

Graph() : BaseClass() {}

Graph(const std::vector<Edge> &edges): BaseClass(edges) {
nodesNumber = BaseClass::neighbors.size();
}
};


std::vector<std::vector<WeightType>> distances; // Distances from each node to all the rest
WeightType inf;
Graph graph;

FloidAlgorithm() {

}

// Fit the algorithm to the graph
void fit(const EdgesListGraph<WeightType> &graph_) override {
graph = Graph(graph_.edges);
inf = 1;
for (const Edge &edge : graph_.edges) {
inf += edge.weight;
}

distances.resize(graph.nodesNumber, std::vector<WeightType>(graph.nodesNumber, inf));
for (int v = 0; v < distances.size(); ++v) {
distances[v][v] = 0;
}
for (const Edge &edge : graph_.edges) {
distances[edge.fromIndex][edge.toIndex] = edge.weight;
}

calcDistances();
}

// Compute distances from the start node
std::vector<WeightType> computeDistances(size_t startIndex) override {
std::vector<WeightType> result = distances[startIndex];
// mark infinities as unreachable
for (auto& w : result) {
if (w >= inf) w = -1;
}
return result;
}

private:
void calcDistances() {
int n = distances.size();
for (int i = 0; i < n; ++i) {
for (int u = 0; u < n; ++u) {
for (int v = 0; v < n; ++v) {
distances[u][v] = std::min(
distances[u][v],
distances[u][i] + distances[i][v]
);
}
}
}
}

/// @brief Just for debugging purposes
void printDistances() const {
int n = distances.size();
for (int u = 0; u < n; ++u) {
for (int v = 0; v < n; ++v) {
std::cout << distances[u][v] << ' ';
}
std::cout << std::endl;
}
}
};

#endif
6 changes: 5 additions & 1 deletion cpp/micro_benchmarks/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ FetchContent_Declare(
GIT_TAG v1.8.3)
FetchContent_MakeAvailable(googlebenchmark)

include(../cmake/boost.cmake)

add_custom_target(micro_benchmarks)

include_directories(SYSTEM ${ALGO_ANALYSIS_INCLUDE_DIR})
Expand All @@ -36,7 +38,7 @@ set(TOP_LEVEL_DIR "${PROJECT_SOURCE_DIR}/..")
function(add_benchmark test_name test_src)
add_executable(${test_name} ${PROJECT_SOURCES} ${test_src})

target_link_libraries(${test_name} PUBLIC benchmark::benchmark)
target_link_libraries(${test_name} PUBLIC benchmark::benchmark Boost::heap)

target_compile_features(${test_name} PRIVATE cxx_std_17)
target_compile_definitions(${test_name} PUBLIC TOP_LEVEL_DIR="${TOP_LEVEL_DIR}")
Expand All @@ -47,4 +49,6 @@ endfunction()
add_benchmark(DFSBenchmark dfs.cpp)
add_benchmark(BFSBenchmark bfs.cpp)
add_benchmark(DijkstraBenchmark dijkstra.cpp)
add_benchmark(DijkstraWithFibBenchmark dijkstra_with_fib.cpp)
add_benchmark(FordBellmanBenchmark ford_bellman.cpp)
add_benchmark(FloidBenchmark floid.cpp)
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
{
"context": {
"date": "2025-03-03T01:41:22+00:00",
"host_name": "d5962e068320",
"executable": "./micro_benchmarks/DijkstraWithFibBenchmark",
"num_cpus": 16,
"mhz_per_cpu": 48,
"cpu_scaling_enabled": false,
"caches": [
],
"load_avg": [0.640137,0.686523,0.703613],
"library_build_type": "debug"
},
"benchmarks": [
{
"name": "benchMark/1",
"family_index": 0,
"per_family_instance_index": 0,
"run_name": "benchMark/1",
"run_type": "iteration",
"repetitions": 1,
"repetition_index": 0,
"threads": 1,
"iterations": 1393,
"real_time": 1.2728448801150415e+06,
"cpu_time": 1.2728250739411341e+06,
"time_unit": "ns"
},
{
"name": "benchMark/2",
"family_index": 0,
"per_family_instance_index": 1,
"run_name": "benchMark/2",
"run_type": "iteration",
"repetitions": 1,
"repetition_index": 0,
"threads": 1,
"iterations": 541,
"real_time": 1.3001248465817112e+06,
"cpu_time": 1.3000489796672829e+06,
"time_unit": "ns"
},
{
"name": "benchMark/3",
"family_index": 0,
"per_family_instance_index": 2,
"run_name": "benchMark/3",
"run_type": "iteration",
"repetitions": 1,
"repetition_index": 0,
"threads": 1,
"iterations": 540,
"real_time": 1.3020578722245300e+06,
"cpu_time": 1.3019908907407410e+06,
"time_unit": "ns"
},
{
"name": "benchMark/4",
"family_index": 0,
"per_family_instance_index": 3,
"run_name": "benchMark/4",
"run_type": "iteration",
"repetitions": 1,
"repetition_index": 0,
"threads": 1,
"iterations": 535,
"real_time": 1.2960419009364033e+06,
"cpu_time": 1.2959945439252341e+06,
"time_unit": "ns"
},
{
"name": "benchMark/5",
"family_index": 0,
"per_family_instance_index": 4,
"run_name": "benchMark/5",
"run_type": "iteration",
"repetitions": 1,
"repetition_index": 0,
"threads": 1,
"iterations": 527,
"real_time": 1.3031827172666665e+06,
"cpu_time": 1.3030856223908912e+06,
"time_unit": "ns"
}
]
}
86 changes: 86 additions & 0 deletions cpp/micro_benchmarks/benchmarks_results/MacOS/floid.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
{
"context": {
"date": "2025-03-03T00:05:48+00:00",
"host_name": "d5962e068320",
"executable": "../../build/micro_benchmarks/FloidBenchmark",
"num_cpus": 16,
"mhz_per_cpu": 48,
"cpu_scaling_enabled": false,
"caches": [
],
"load_avg": [0.712402,0.681152,0.664062],
"library_build_type": "debug"
},
"benchmarks": [
{
"name": "benchMark/1",
"family_index": 0,
"per_family_instance_index": 0,
"run_name": "benchMark/1",
"run_type": "iteration",
"repetitions": 1,
"repetition_index": 0,
"threads": 1,
"iterations": 1000,
"real_time": 1.2278971260002437e+06,
"cpu_time": 1.2278868280000000e+06,
"time_unit": "ns"
},
{
"name": "benchMark/2",
"family_index": 0,
"per_family_instance_index": 1,
"run_name": "benchMark/2",
"run_type": "iteration",
"repetitions": 1,
"repetition_index": 0,
"threads": 1,
"iterations": 558,
"real_time": 1.2478864247299575e+06,
"cpu_time": 1.2478506523297487e+06,
"time_unit": "ns"
},
{
"name": "benchMark/3",
"family_index": 0,
"per_family_instance_index": 2,
"run_name": "benchMark/3",
"run_type": "iteration",
"repetitions": 1,
"repetition_index": 0,
"threads": 1,
"iterations": 547,
"real_time": 1.2409552120659300e+06,
"cpu_time": 1.2409081297989034e+06,
"time_unit": "ns"
},
{
"name": "benchMark/4",
"family_index": 0,
"per_family_instance_index": 3,
"run_name": "benchMark/4",
"run_type": "iteration",
"repetitions": 1,
"repetition_index": 0,
"threads": 1,
"iterations": 562,
"real_time": 1.2446258896799588e+06,
"cpu_time": 1.2445583434163705e+06,
"time_unit": "ns"
},
{
"name": "benchMark/5",
"family_index": 0,
"per_family_instance_index": 4,
"run_name": "benchMark/5",
"run_type": "iteration",
"repetitions": 1,
"repetition_index": 0,
"threads": 1,
"iterations": 560,
"real_time": 1.2480564732137672e+06,
"cpu_time": 1.2480045339285720e+06,
"time_unit": "ns"
}
]
}
Loading