From 201c38d6d4270821b606104cdda459a6286b5539 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A3=D1=81=D0=BE=D0=B2=D0=B0=20=D0=9C=D0=B0=D1=80=D0=B8?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=90=D0=BD=D0=B4=D1=80=D0=B5=D0=B5=D0=B2=D0=BD?= =?UTF-8?q?=D0=B0?= Date: Mon, 3 Apr 2017 17:47:22 +0300 Subject: [PATCH 1/3] Realization in t/c --- app/main.cpp | 8 ++++++-- include/Dijkstra.h | 17 +++++++++++++++++ include/add.h | 6 ------ src/Dijkstra.cpp | 31 +++++++++++++++++++++++++++++++ src/add.cpp | 3 --- test/test_Dijkstra.cpp | 7 +++++++ test/test_add.cpp | 7 ------- 7 files changed, 61 insertions(+), 18 deletions(-) create mode 100644 include/Dijkstra.h delete mode 100644 include/add.h create mode 100644 src/Dijkstra.cpp delete mode 100644 src/add.cpp create mode 100644 test/test_Dijkstra.cpp delete mode 100644 test/test_add.cpp diff --git a/app/main.cpp b/app/main.cpp index 4485790..545093a 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -1,6 +1,10 @@ -#include "add.h" +#include "Dijkstra.h" #include int main() { - std::cout << "2 + 2 = " << add(2, 2) << std::endl; + int start = 2; + /*нужно понять, как вводить список + смежных рёбер с реализованной структурой g[N] = ???*/ + //Dijkstra(start - 1); } + diff --git a/include/Dijkstra.h b/include/Dijkstra.h new file mode 100644 index 0000000..04352fd --- /dev/null +++ b/include/Dijkstra.h @@ -0,0 +1,17 @@ +#ifndef INCLUDE_ADD_H_ +#define INCLUDE_ADD_H_ +#include + +const int N = 100000; +const int INF = 1 << 30; + +// список смежных рёбер для каждой вершины +struct mytype { + int vFrom, vTo; + int weight; +}; +std::vector g[N]; + +int* Dijkstra(int start); + +#endif // INCLUDE_ADD_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..2198e40 --- /dev/null +++ b/src/Dijkstra.cpp @@ -0,0 +1,31 @@ +#include +#include "Dijkstra.h" + +int* Dijkstra(int start) { + int* parent = new int[N]; + int* dist = new int[N]; + std::set> s; + + for (int i = 0; i < N; i++) + parent[i] = -1; + for (int i = 0; i < N; i++) + dist[i] = INF; + dist[start] = 0; + s.insert(std::make_pair(dist[start], start)); + + while (!s.empty()) { + int v = s.begin()->second; + s.erase(s.begin()); + for (int j = 0; j < g[v].size(); j++) { + int u = g[v][j].vTo; + 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)); + } + } + } + return parent; +} 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..a00b800 --- /dev/null +++ b/test/test_Dijkstra.cpp @@ -0,0 +1,7 @@ +#include +#include "Dijkstra.h" + +TEST(Dijkstra, can_find) { + +} + 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); -} From 4d2d5d2971ab23f21bc064ee169923566e11231c Mon Sep 17 00:00:00 2001 From: Usova Marina A Date: Sun, 9 Apr 2017 21:32:00 +0300 Subject: [PATCH 2/3] Some changes in the algorithm, added tests --- app/main.cpp | 15 ++++++---- include/Dijkstra.h | 21 ++++++++------ src/Dijkstra.cpp | 49 ++++++++++++++++++++++++++------ test/test_Dijkstra.cpp | 64 +++++++++++++++++++++++++++++++++++++++++- 4 files changed, 126 insertions(+), 23 deletions(-) diff --git a/app/main.cpp b/app/main.cpp index 545093a..942c647 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -1,10 +1,15 @@ #include "Dijkstra.h" -#include +#include int main() { - int start = 2; - /*нужно понять, как вводить список - смежных рёбер с реализованной структурой g[N] = ???*/ - //Dijkstra(start - 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) } }; + Dijkstra(g, start, end); } diff --git a/include/Dijkstra.h b/include/Dijkstra.h index 04352fd..1f135d5 100644 --- a/include/Dijkstra.h +++ b/include/Dijkstra.h @@ -1,17 +1,20 @@ -#ifndef INCLUDE_ADD_H_ -#define INCLUDE_ADD_H_ +#ifndef INCLUDE_DIJKSTRA_H_ +#define INCLUDE_DIJKSTRA_H_ + #include +#include +#include +#include -const int N = 100000; -const int INF = 1 << 30; +const int INF = 1000000000; -// список смежных рёбер для каждой вершины -struct mytype { +// list of adjacent edges for each vertex +struct edge { int vFrom, vTo; int weight; }; -std::vector g[N]; -int* Dijkstra(int start); +edge make_edge(int vFrom_, int vTo_, int weight_); +int Dijkstra(std::vector< std::vector > g, int start, int end); -#endif // INCLUDE_ADD_H_ +#endif // INCLUDE_DIJKSTRA_H_ diff --git a/src/Dijkstra.cpp b/src/Dijkstra.cpp index 2198e40..f0109ca 100644 --- a/src/Dijkstra.cpp +++ b/src/Dijkstra.cpp @@ -1,23 +1,55 @@ +#include +#include #include #include "Dijkstra.h" -int* Dijkstra(int start) { - int* parent = new int[N]; - int* dist = new int[N]; +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; + + if ((g.size() == 0) || ((end == start) && (g[0][0].vFrom != end))) + throw std::logic_error("Input Error\n"); - for (int i = 0; i < N; i++) + if (end == start) + return 0; + + for (int i = 0; i < g.size(); i++) parent[i] = -1; - for (int i = 0; i < N; i++) + for (int i = 0; i < g.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()); - for (int j = 0; j < g[v].size(); j++) { + for (int j = 0; j < g[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)); @@ -25,7 +57,8 @@ int* Dijkstra(int start) { parent[u] = v; s.insert(std::make_pair(dist[u], u)); } - } + flag = u; + } } - return parent; + return 0; } diff --git a/test/test_Dijkstra.cpp b/test/test_Dijkstra.cpp index a00b800..33ea623 100644 --- a/test/test_Dijkstra.cpp +++ b/test/test_Dijkstra.cpp @@ -1,7 +1,69 @@ #include +#include #include "Dijkstra.h" -TEST(Dijkstra, can_find) { +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)); +} From 0f2d7a625422d886000c9f510bd069c057fe47de Mon Sep 17 00:00:00 2001 From: Usova Marina A Date: Sun, 9 Apr 2017 21:38:43 +0300 Subject: [PATCH 3/3] Fix cpplint --- src/Dijkstra.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Dijkstra.cpp b/src/Dijkstra.cpp index f0109ca..994550f 100644 --- a/src/Dijkstra.cpp +++ b/src/Dijkstra.cpp @@ -16,16 +16,17 @@ int Dijkstra(std::vector< std::vector > g, int start, int end) { std::vector dist(g.size()); std::set> s; int flag; + int size = g.size(); - if ((g.size() == 0) || ((end == start) && (g[0][0].vFrom != end))) + 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 < g.size(); i++) + for (int i = 0; i < size; i++) parent[i] = -1; - for (int i = 0; i < g.size(); i++) + for (int i = 0; i < size; i++) dist[i] = INF; dist[start] = 0; s.insert(std::make_pair(dist[start], start)); @@ -47,7 +48,9 @@ int Dijkstra(std::vector< std::vector > g, int start, int end) { return s.begin()->first; } s.erase(s.begin()); - for (int j = 0; j < g[v].size(); j++) { + + 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;