diff --git a/Pth/algorithms/dijkstra.cpp b/Pth/algorithms/dijkstra.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5fef1efbf99cebf8fb9c8cc55878c0999d65da9e --- /dev/null +++ b/Pth/algorithms/dijkstra.cpp @@ -0,0 +1,95 @@ +#include "dijkstra.h" + +Dijkstra::Dijkstra() {} + +std::vector<double> Dijkstra::runSequential(const std::vector<std::vector<double>>& graph, int src) { + int numVertices = graph.size(); + std::vector<double> dist(numVertices, std::numeric_limits<double>::infinity()); + std::vector<bool> visited(numVertices, false); + + dist[src] = 0.0; + + for (int count = 0; count < numVertices; count++) { + // Finde Knoten mit minimalem Abstand + double minDist = std::numeric_limits<double>::infinity(); + int u = -1; + + for (int v = 0; v < numVertices; v++) { + if (!visited[v] && dist[v] < minDist) { + minDist = dist[v]; + u = v; + } + } + + // Wenn kein erreichbarer Knoten gefunden wurde, beenden + if (u == -1) { + break; + } + + // Markiere den Knoten als besucht + visited[u] = true; + + // Aktualisiere Distanzwerte der Nachbarknoten (sequentiell) + for (int v = 0; v < numVertices; v++) { + if (!visited[v] && graph[u][v] > 0 && + dist[u] != std::numeric_limits<double>::infinity() && + dist[u] + graph[u][v] < dist[v]) { + dist[v] = dist[u] + graph[u][v]; + } + } + } + + return dist; +} + +std::vector<double> Dijkstra::runParallel(const std::vector<std::vector<double>>& graph, int src) { + int numVertices = graph.size(); + std::vector<double> dist(numVertices, std::numeric_limits<double>::infinity()); + std::vector<bool> visited(numVertices, false); + + dist[src] = 0.0; + + for (int count = 0; count < numVertices; count++) { + // Finde Knoten mit minimalem Abstand (nicht parallelisierbar) + double minDist = std::numeric_limits<double>::infinity(); + int u = -1; + + for (int v = 0; v < numVertices; v++) { + if (!visited[v] && dist[v] < minDist) { + minDist = dist[v]; + u = v; + } + } + + // Wenn kein erreichbarer Knoten gefunden wurde, beenden + if (u == -1) { + break; + } + + // Markiere den Knoten als besucht + visited[u] = true; + +// Aktualisiere Distanzwerte der Nachbarknoten - parallelisierbar mit OpenMP +#pragma omp parallel for + for (int v = 0; v < numVertices; v++) { + if (!visited[v] && graph[u][v] > 0 && + dist[u] != std::numeric_limits<double>::infinity()) { + double newDist = dist[u] + graph[u][v]; +// Thread-sichere Aktualisierung mit atomarer Operation +#pragma omp critical + { + if (newDist < dist[v]) { + dist[v] = newDist; + } + } + } + } + } + + return dist; +} + +std::vector<double> Dijkstra::run(const std::vector<std::vector<double>>& graph, int src) { + // Standardmäßig die parallele Version verwenden + return runParallel(graph, src); +}