From dc50883e1dee7bd218f0c2948dc804392b57ebe9 Mon Sep 17 00:00:00 2001 From: Phlake Date: Sun, 5 Dec 2021 20:09:34 +0200 Subject: [PATCH 1/3] Added lab_4 --- main.py | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 main.py diff --git a/main.py b/main.py new file mode 100644 index 0000000..62bff42 --- /dev/null +++ b/main.py @@ -0,0 +1,50 @@ +from queue import PriorityQueue +from sys import maxsize +from collections import defaultdict + + +class Graph: + + def __init__(self, vertices): + self.vertices = vertices + self.graph = defaultdict(list) + self.distance = [maxsize] * self.vertices + + def add_line(self, start_vert, end_vert, weight): + self.graph[start_vert].append((end_vert, weight)) + self.graph[end_vert].append((start_vert, weight)) + + def dijkstra(self, vertex_start): + self.distance[vertex_start] = 0 + q = PriorityQueue() + q.put((self.distance[vertex_start], vertex_start)) + while not q.empty(): + dist, vertex = q.get() + for adj_vertex, weight in self.graph[vertex]: + if self.distance[vertex] + weight < self.distance[adj_vertex]: + self.distance[adj_vertex] = self.distance[vertex] + weight + q.put((self.distance[adj_vertex], adj_vertex)) + return self.distance + + +graph = Graph(9) +graph.add_line(0, 1, 4) +graph.add_line(0, 6, 7) +graph.add_line(1, 6, 11) +graph.add_line(1, 7, 20) +graph.add_line(1, 2, 9) +graph.add_line(2, 3, 6) +graph.add_line(2, 4, 2) +graph.add_line(3, 4, 10) +graph.add_line(3, 5, 5) +graph.add_line(4, 5, 15) +graph.add_line(4, 7, 1) +graph.add_line(4, 8, 5) +graph.add_line(5, 8, 12) +graph.add_line(6, 7, 1) +graph.add_line(7, 8, 3) + +D = graph.dijkstra(0) + +for end_vertex in range(len(D)): + print("Distance from 0 to", end_vertex, "==", D[end_vertex]) From 9f9d0c48ffa71668ca7f81e7b1d3f0510d81ceaf Mon Sep 17 00:00:00 2001 From: Phlake Date: Mon, 6 Dec 2021 05:12:49 +0200 Subject: [PATCH 2/3] Added tests, readme and minor tweaks --- .gitignore | 2 ++ README.md | 14 +++++++++++-- dijkstra.out | 1 + main.py | 51 +++++++++++++++++++++++++++------------------ test.py | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 104 insertions(+), 22 deletions(-) create mode 100644 dijkstra.out create mode 100644 test.py diff --git a/.gitignore b/.gitignore index 510c73d..8b16403 100644 --- a/.gitignore +++ b/.gitignore @@ -102,6 +102,8 @@ venv.bak/ # Rope project settings .ropeproject +.idea + # mkdocs documentation /site diff --git a/README.md b/README.md index 84b53db..8dfb2c0 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,12 @@ -# Algorithms - +# Algorithms lab_4 + +## Task +Build directed and weighted graph from input and implement Dijkstra algorithm to find average distance from vertex S +to all available vertexes + +## How to run + + `cd` into folder where you want to store this repository + + Clone this repository `git clone https://github.com/MKruchok/Algorithms.git` + + Choose branch lab_4 with command `git checkout lab_4` + + Go into folder with files with command `cd Algorithms` + + run `py main.py` on Windows \ No newline at end of file diff --git a/dijkstra.out b/dijkstra.out new file mode 100644 index 0000000..d00518b --- /dev/null +++ b/dijkstra.out @@ -0,0 +1 @@ +5.555555555555555 \ No newline at end of file diff --git a/main.py b/main.py index 62bff42..2ff21a8 100644 --- a/main.py +++ b/main.py @@ -1,5 +1,4 @@ from queue import PriorityQueue -from sys import maxsize from collections import defaultdict @@ -8,43 +7,55 @@ class Graph: def __init__(self, vertices): self.vertices = vertices self.graph = defaultdict(list) - self.distance = [maxsize] * self.vertices + self.distance = [999] * self.vertices - def add_line(self, start_vert, end_vert, weight): - self.graph[start_vert].append((end_vert, weight)) - self.graph[end_vert].append((start_vert, weight)) + def add_line(self, first_vert, second_vert, weight): + self.graph[first_vert].append((second_vert, weight)) + self.graph[second_vert].append((first_vert, weight)) - def dijkstra(self, vertex_start): - self.distance[vertex_start] = 0 + def dijkstra(self, main_vertex): + self.distance[main_vertex] = 0 q = PriorityQueue() - q.put((self.distance[vertex_start], vertex_start)) + q.put((self.distance[main_vertex], main_vertex)) while not q.empty(): - dist, vertex = q.get() - for adj_vertex, weight in self.graph[vertex]: - if self.distance[vertex] + weight < self.distance[adj_vertex]: - self.distance[adj_vertex] = self.distance[vertex] + weight + dist, current_vertex = q.get() + for adj_vertex, weight in self.graph[current_vertex]: + if self.distance[current_vertex] + weight < self.distance[adj_vertex]: + self.distance[adj_vertex] = self.distance[current_vertex] + weight q.put((self.distance[adj_vertex], adj_vertex)) return self.distance +def insert_out(result): + file = open("dijkstra.out", 'w') + file.write(str(result)) + + graph = Graph(9) graph.add_line(0, 1, 4) -graph.add_line(0, 6, 7) -graph.add_line(1, 6, 11) -graph.add_line(1, 7, 20) +graph.add_line(0, 4, 1) +graph.add_line(1, 6, 12) +graph.add_line(1, 7, 24) graph.add_line(1, 2, 9) graph.add_line(2, 3, 6) graph.add_line(2, 4, 2) -graph.add_line(3, 4, 10) +graph.add_line(3, 4, 3) graph.add_line(3, 5, 5) -graph.add_line(4, 5, 15) +graph.add_line(4, 5, 9) graph.add_line(4, 7, 1) graph.add_line(4, 8, 5) graph.add_line(5, 8, 12) graph.add_line(6, 7, 1) graph.add_line(7, 8, 3) -D = graph.dijkstra(0) +s = 8 +distance_main = graph.dijkstra(s) +distance_sum = 0 + +for end_vertex in range(len(distance_main)): + print("Distance from", s, "to", end_vertex, "==", distance_main[end_vertex]) + distance_sum += distance_main[end_vertex] -for end_vertex in range(len(D)): - print("Distance from 0 to", end_vertex, "==", D[end_vertex]) +middle = distance_sum / len(distance_main) +insert_out(middle) +print("Arithmetic mean ==", round(middle, 2)) diff --git a/test.py b/test.py new file mode 100644 index 0000000..0565f0a --- /dev/null +++ b/test.py @@ -0,0 +1,58 @@ +import unittest +from main import Graph + + +class TestDijkstra(unittest.TestCase): + def setUp(self): + self.graph = Graph(9) + self.graph.add_line(2, 3, 6) + self.graph.add_line(1, 6, 12) + self.graph.add_line(1, 7, 24) + self.graph.add_line(1, 2, 9) + self.graph.add_line(0, 4, 1) + self.graph.add_line(0, 1, 14) + self.graph.add_line(4, 8, 5) + self.graph.add_line(3, 5, 5) + self.graph.add_line(2, 4, 34) + self.graph.add_line(3, 4, 3) + self.graph.add_line(4, 5, 9) + self.graph.add_line(4, 7, 1) + self.graph.add_line(5, 8, 12) + self.graph.add_line(7, 8, 3) + self.graph.add_line(6, 7, 1) + + def test_0(self): + result = [0, 14, 10, 4, 1, 9, 3, 2, 5] + self.assertEqual(self.graph.dijkstra(0), result) + + def test_1(self): + result = [14, 0, 9, 15, 14, 20, 12, 13, 16] + self.assertEqual(self.graph.dijkstra(1), result) + + def test_2(self): + result = [10, 9, 0, 6, 9, 11, 11, 10, 13] + self.assertEqual(self.graph.dijkstra(2), result) + + def test_3(self): + result = [4, 15, 6, 0, 3, 5, 5, 4, 7] + self.assertEqual(self.graph.dijkstra(3), result) + + def test_4(self): + result = [1, 14, 9, 3, 0, 8, 2, 1, 4] + self.assertEqual(self.graph.dijkstra(4), result) + + def test_5(self): + result = [9, 20, 11, 5, 8, 0, 10, 9, 12] + self.assertEqual(self.graph.dijkstra(5), result) + + def test_6(self): + result = [3, 12, 11, 5, 2, 10, 0, 1, 4] + self.assertEqual(self.graph.dijkstra(6), result) + + def test_7(self): + result = [2, 13, 10, 4, 1, 9, 1, 0, 3] + self.assertEqual(self.graph.dijkstra(7), result) + + def test_8(self): + result = [5, 16, 13, 7, 4, 12, 4, 3, 0] + self.assertEqual(self.graph.dijkstra(8), result) From 5823cccba46173630a8cf7d0c7155c5e2ba9069c Mon Sep 17 00:00:00 2001 From: Phlake Date: Thu, 2 Jun 2022 12:12:28 +0300 Subject: [PATCH 3/3] minor changes --- main.py | 30 ------------------------------ test.py | 9 ++++++++- 2 files changed, 8 insertions(+), 31 deletions(-) diff --git a/main.py b/main.py index 2ff21a8..f473c8a 100644 --- a/main.py +++ b/main.py @@ -29,33 +29,3 @@ def dijkstra(self, main_vertex): def insert_out(result): file = open("dijkstra.out", 'w') file.write(str(result)) - - -graph = Graph(9) -graph.add_line(0, 1, 4) -graph.add_line(0, 4, 1) -graph.add_line(1, 6, 12) -graph.add_line(1, 7, 24) -graph.add_line(1, 2, 9) -graph.add_line(2, 3, 6) -graph.add_line(2, 4, 2) -graph.add_line(3, 4, 3) -graph.add_line(3, 5, 5) -graph.add_line(4, 5, 9) -graph.add_line(4, 7, 1) -graph.add_line(4, 8, 5) -graph.add_line(5, 8, 12) -graph.add_line(6, 7, 1) -graph.add_line(7, 8, 3) - -s = 8 -distance_main = graph.dijkstra(s) -distance_sum = 0 - -for end_vertex in range(len(distance_main)): - print("Distance from", s, "to", end_vertex, "==", distance_main[end_vertex]) - distance_sum += distance_main[end_vertex] - -middle = distance_sum / len(distance_main) -insert_out(middle) -print("Arithmetic mean ==", round(middle, 2)) diff --git a/test.py b/test.py index 0565f0a..bb16f3b 100644 --- a/test.py +++ b/test.py @@ -22,8 +22,15 @@ def setUp(self): self.graph.add_line(6, 7, 1) def test_0(self): + self.distance_main = self.graph.dijkstra(0) + self.distance_sum = 0 + for end_vertex in range(len(self.distance_main)): + print("Distance from", 0, "to", end_vertex, "==", self.distance_main[end_vertex]) + self.distance_sum += self.distance_main[end_vertex] result = [0, 14, 10, 4, 1, 9, 3, 2, 5] - self.assertEqual(self.graph.dijkstra(0), result) + self.middle = self.distance_sum / len(self.distance_main) + print("Arithmetic mean ==", round(self.middle, 2)) + self.assertEqual(self.distance_main, result) def test_1(self): result = [14, 0, 9, 15, 14, 20, 12, 13, 16]