diff --git a/app/main.cpp b/app/main.cpp index 4485790..942c647 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -1,6 +1,15 @@ -#include "add.h" -#include +#include "Dijkstra.h" +#include int main() { - std::cout << "2 + 2 = " << add(2, 2) << std::endl; + int start = 0, end = 5; + std::vector< std::vector > g = + { { make_edge(0, 1, 1) }, + { make_edge(1, 2, 2), make_edge(1, 4, 8) }, + { make_edge(2, 3, 3) }, + { make_edge(3, 4, 5) }, + { make_edge(4, 5, 1) }, + { make_edge(5, -1, -1) } }; + Dijkstra(g, start, end); } + diff --git a/include/Dijkstra.h b/include/Dijkstra.h new file mode 100644 index 0000000..1f135d5 --- /dev/null +++ b/include/Dijkstra.h @@ -0,0 +1,20 @@ +#ifndef INCLUDE_DIJKSTRA_H_ +#define INCLUDE_DIJKSTRA_H_ + +#include +#include +#include +#include + +const int INF = 1000000000; + +// list of adjacent edges for each vertex +struct edge { + int vFrom, vTo; + int weight; +}; + +edge make_edge(int vFrom_, int vTo_, int weight_); +int Dijkstra(std::vector< std::vector > g, int start, int end); + +#endif // INCLUDE_DIJKSTRA_H_ diff --git a/include/add.h b/include/add.h deleted file mode 100644 index ebb1c94..0000000 --- a/include/add.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef INCLUDE_ADD_H_ -#define INCLUDE_ADD_H_ - -int add(int x, int y); - -#endif // INCLUDE_ADD_H_ diff --git a/src/Dijkstra.cpp b/src/Dijkstra.cpp new file mode 100644 index 0000000..994550f --- /dev/null +++ b/src/Dijkstra.cpp @@ -0,0 +1,67 @@ +#include +#include +#include +#include "Dijkstra.h" + +edge make_edge(int vFrom_, int vTo_, int weight_) { + edge c; + c.vFrom = vFrom_; + c.vTo = vTo_; + c.weight = weight_; + return c; +} + +int Dijkstra(std::vector< std::vector > g, int start, int end) { + int* parent = new int[g.size()]; + std::vector dist(g.size()); + std::set> s; + int flag; + int size = g.size(); + + if ((size == 0) || ((end == start) && (g[0][0].vFrom != end))) + throw std::logic_error("Input Error\n"); + + if (end == start) + return 0; + + for (int i = 0; i < size; i++) + parent[i] = -1; + for (int i = 0; i < size; i++) + dist[i] = INF; + dist[start] = 0; + s.insert(std::make_pair(dist[start], start)); + + while (!s.empty()) { + int v = s.begin()->second; + if (v == end) { + int i = 1; + std::cout << "Our path: "; + while ( i <= flag ) { + std::cout << parent[i]; + std::cout << " "; + i++; + } + std::cout << "" << std::endl; + std::cout << "Shortest path length: "; + std::cout << s.begin()->first; + std::cout << "" << std::endl; + return s.begin()->first; + } + s.erase(s.begin()); + + int v_size = g[v].size(); + for (int j = 0; j < v_size; j++) { + int u = g[v][j].vTo; + if (u < 0) break; + int w = g[v][j].weight; + if (dist[u] > dist[v] + w) { + s.erase(std::make_pair(dist[u], u)); + dist[u] = dist[v] + w; + parent[u] = v; + s.insert(std::make_pair(dist[u], u)); + } + flag = u; + } + } + return 0; +} diff --git a/src/add.cpp b/src/add.cpp deleted file mode 100644 index 35bf82f..0000000 --- a/src/add.cpp +++ /dev/null @@ -1,3 +0,0 @@ -int add(int x, int y) { - return x + y; -} diff --git a/test/test_Dijkstra.cpp b/test/test_Dijkstra.cpp new file mode 100644 index 0000000..33ea623 --- /dev/null +++ b/test/test_Dijkstra.cpp @@ -0,0 +1,69 @@ +#include +#include +#include "Dijkstra.h" + +TEST(Dijkstra, can_find_min_way_1) { + int start = 0, end = 5; + std::vector< std::vector > g = + { { make_edge(0, 1, 1) }, + { make_edge(1, 2, 2), make_edge(1, 4, 8) }, + { make_edge(2, 3, 3) }, + { make_edge(3, 4, 5) }, + { make_edge(4, 5, 1) }, + { make_edge(5, -1, -1) } }; + EXPECT_EQ(Dijkstra(g, start, end), 10); +} + +TEST(Dijkstra, can_find_min_way_2) { + int start = 0, end = 5; + std::vector< std::vector > g = + { { make_edge(0, 1, 2), make_edge(0, 5, 10) }, + { make_edge(1, 2, 1), make_edge(1, 4, 5) }, + { make_edge(2, 3, 1) }, + { make_edge(3, 4, 1) }, + { make_edge(4, 5, 1) }, + { make_edge(5, -1, -1) } }; + EXPECT_EQ(Dijkstra(g, start, end), 6); +} + +TEST(Dijkstra, can_find_min_way_3) { + int start = 0, end = 5; + std::vector< std::vector > g = + { { make_edge(0, 1, 2), make_edge(0, 5, 6) }, + { make_edge(1, 2, 1), make_edge(1, 4, 5) }, + { make_edge(2, 3, 1) }, + { make_edge(3, 4, 1) }, + { make_edge(4, 5, 1) }, + { make_edge(5, -1, -1) } }; + EXPECT_EQ(Dijkstra(g, start, end), 6); +} + + +TEST(Dijkstra, can_find_min_way_4) { + int start = 0, end = 2; + std::vector< std::vector > g = + { { make_edge(0, 1, 1), make_edge(0, 2, 3) }, + { make_edge(1, 2, 5)}, + { make_edge(2, -1, -1) } }; + EXPECT_EQ(Dijkstra(g, start, end), 3); +} + +TEST(Dijkstra, can_work_with_graph_of_one_element) { + int start = 2, end = 2; + std::vector< std::vector > g = + { {make_edge(2, -1, -1)} }; + EXPECT_EQ(Dijkstra(g, start, end), 0); +} + +TEST(Dijkstra, can_work_with_throw_for_graph_of_one_element_1) { + int start = 2, end = 2; + std::vector< std::vector > g = + { { make_edge(1, -1, -1) } }; + EXPECT_ANY_THROW(Dijkstra(g, start, end)); +} + +TEST(Dijkstra, can_work_with_throw_for_graph_of_one_element_2) { + int start = 0, end = 0; + std::vector< std::vector > g; + EXPECT_ANY_THROW(Dijkstra(g, start, end)); +} diff --git a/test/test_add.cpp b/test/test_add.cpp deleted file mode 100644 index 66c2df3..0000000 --- a/test/test_add.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include -#include "add.h" - -TEST(Addition, CanAddTwoNumbers) { - EXPECT_EQ(add(2, 2), 4); - EXPECT_EQ(add(-2, 2), 0); -}