diff --git a/Headers/0003_Graph/0013_AllPairsShortestPathsFloydWarshall.h b/Headers/0003_Graph/0013_AllPairsShortestPathsFloydWarshall.h new file mode 100644 index 0000000..4dea0a1 --- /dev/null +++ b/Headers/0003_Graph/0013_AllPairsShortestPathsFloydWarshall.h @@ -0,0 +1,24 @@ +#pragma once + +#include +using namespace std; + +namespace AllPairsShortestPathsFloydWarshall +{ + class Graph + { + private: + int _noOfVertices; + vector> _adjMatrix; + vector> _shortestPathMatrixFloydWarshall; + vector> _predecessorMatrix; + void InitializeDistanceAndPredecessors(); + void GetShortestPath(int source, int destination, vector& path); + + public: + void CreateGraph(int noOfVertices); + void PushDirectedEdge(int valueU, int valueV, int weight); + void FindAllPairsShortestPathsFloydWarshallSolution(); + vector> GetFloydWarshallShortestPath(); + }; +} \ No newline at end of file diff --git a/SourceCodes/0003_Graph/0013_AllPairsShortestPathsFloydWarshall.cc b/SourceCodes/0003_Graph/0013_AllPairsShortestPathsFloydWarshall.cc new file mode 100644 index 0000000..53a6095 --- /dev/null +++ b/SourceCodes/0003_Graph/0013_AllPairsShortestPathsFloydWarshall.cc @@ -0,0 +1,104 @@ +#include "../Headers/0003_Graph/0013_AllPairsShortestPathsFloydWarshall.h" +#include +using namespace std; + +namespace AllPairsShortestPathsFloydWarshall +{ + // Graph Private Member Methods + void Graph::InitializeDistanceAndPredecessors() + { + this->_shortestPathMatrixFloydWarshall = this->_adjMatrix; + + for (int i = 0; i < this->_noOfVertices; i++) + { + for (int j = 0; j < this->_noOfVertices; j++) + { + if ((i == j) || this->_adjMatrix[i][j] == INT_MAX) + { + this->_predecessorMatrix[i][j] = -1; + } + else + { + this->_predecessorMatrix[i][j] = i + 1; + } + } + } + } + + void Graph::GetShortestPath(int source, int destination, vector& path) + { + if (this->_predecessorMatrix[source - 1][destination - 1] != source) + { + int predecessor = this->_predecessorMatrix[source - 1][destination - 1]; + this->GetShortestPath(source, predecessor, path); + path.push_back(predecessor); + } + } + + // Graph Public Member Methods + void Graph::CreateGraph(int noOfVertices) + { + this->_noOfVertices = noOfVertices; + this->_adjMatrix = vector>(this->_noOfVertices, vector(this->_noOfVertices, INT_MAX)); + this->_shortestPathMatrixFloydWarshall = vector>(this->_noOfVertices, vector(this->_noOfVertices, INT_MAX)); + this->_predecessorMatrix = vector>(this->_noOfVertices, vector(this->_noOfVertices, INT_MAX)); + + for (int i = 0; i < this->_noOfVertices; i++) + { + for (int j = 0; j < this->_noOfVertices; j++) + { + if (i == j) + { + this->_adjMatrix[i][j] = 0; + } + } + } + } + + void Graph::PushDirectedEdge(int valueU, int valueV, int weight) + { + this->_adjMatrix[valueU - 1][valueV - 1] = weight; + } + + void Graph::FindAllPairsShortestPathsFloydWarshallSolution() + { + this->InitializeDistanceAndPredecessors(); + + for (int k = 0; k < this->_noOfVertices; k++) + { + for (int i = 0; i < this->_noOfVertices; i++) + { + for (int j = 0; j < this->_noOfVertices; j++) + { + if ((this->_shortestPathMatrixFloydWarshall[i][j] > (this->_shortestPathMatrixFloydWarshall[i][k] + this->_shortestPathMatrixFloydWarshall[k][j])) + && + (this->_shortestPathMatrixFloydWarshall[i][k] != INT_MAX && this->_shortestPathMatrixFloydWarshall[k][j] != INT_MAX)) + { + this->_shortestPathMatrixFloydWarshall[i][j] = this->_shortestPathMatrixFloydWarshall[i][k] + this->_shortestPathMatrixFloydWarshall[k][j]; + this->_predecessorMatrix[i][j] = this->_predecessorMatrix[k][j]; + } + } + } + } + } + + vector> Graph::GetFloydWarshallShortestPath() + { + vector> result; + for (int i = 0; i < this->_noOfVertices; i++) + { + for (int j = 0; j < this->_noOfVertices; j++) + { + if (i != j) + { + vector path = {}; + path.push_back(i + 1); + this->GetShortestPath(i + 1, j + 1, path); + path.push_back(j + 1); + result.push_back(path); + } + } + } + return result; + } +} \ No newline at end of file diff --git a/SourceCodes/0003_Graph/CMakeLists.txt b/SourceCodes/0003_Graph/CMakeLists.txt index d2171df..4bfca4c 100644 --- a/SourceCodes/0003_Graph/CMakeLists.txt +++ b/SourceCodes/0003_Graph/CMakeLists.txt @@ -12,6 +12,7 @@ set(0003GRAPH_SOURCES 0010_DirectedAcyclicGraphShortestPath.cc 0011_SingleSourceShortestPathDijkstra.cc 0012_DifferenceConstraintsShortestPaths.cc + 0013_AllPairsShortestPathsFloydWarshall.cc ) diff --git a/Tests/0003_Graph/0013_AllPairsShortestPathsFloydWarshallTest.cc b/Tests/0003_Graph/0013_AllPairsShortestPathsFloydWarshallTest.cc new file mode 100644 index 0000000..d14130f --- /dev/null +++ b/Tests/0003_Graph/0013_AllPairsShortestPathsFloydWarshallTest.cc @@ -0,0 +1,36 @@ +#include +#include "../Headers/0003_Graph/0013_AllPairsShortestPathsFloydWarshall.h" +#include"../0000_CommonUtilities/UnitTestHelper.h" +using namespace std; + +namespace AllPairsShortestPathsFloydWarshall +{ + UnitTestHelper unitTestHelper; + + TEST(FloydWarshall, SimpleGraph) + { + // Arrange + Graph graph; + int noOfVertices = 5; + string expectedResult = "[1 5 4 3 2][1 5 4 3][1 5 4][1 5][2 4 1][2 4 3][2 4][2 4 1 5][3 2 4 1][3 2][3 2 4][3 2 4 1 5][4 1][4 3 2][4 3][4 1 5][5 4 1][5 4 3 2][5 4 3][5 4]"; + + // Act + graph.CreateGraph(noOfVertices); + + graph.PushDirectedEdge(1, 2, 3); + graph.PushDirectedEdge(1, 3, 8); + graph.PushDirectedEdge(1, 5, -4); + graph.PushDirectedEdge(2, 4, 1); + graph.PushDirectedEdge(2, 5, 7); + graph.PushDirectedEdge(3, 2, 4); + graph.PushDirectedEdge(4, 3, -5); + graph.PushDirectedEdge(4, 1, 2); + graph.PushDirectedEdge(5, 4, 6); + + graph.FindAllPairsShortestPathsFloydWarshallSolution(); + string actualResult = unitTestHelper.SerializeVectorToString(graph.GetFloydWarshallShortestPath()); + + // Assert + ASSERT_EQ(actualResult, expectedResult); + } +} \ No newline at end of file diff --git a/Tests/0003_Graph/CMakeLists.txt b/Tests/0003_Graph/CMakeLists.txt index 1d024f1..3ec92b1 100644 --- a/Tests/0003_Graph/CMakeLists.txt +++ b/Tests/0003_Graph/CMakeLists.txt @@ -24,6 +24,7 @@ add_executable( 0010_DirectedAcyclicGraphShortestPathTest.cc 0011_SingleSourceShortestPathDijkstraTest.cc 0012_DifferenceConstraintsShortestPathsTest.cc + 0013_AllPairsShortestPathsFloydWarshallTest.cc ) target_link_libraries(