diff --git a/hw5Routers/hw5Routers.Test/AlgorithmTest.cs b/hw5Routers/hw5Routers.Test/AlgorithmTest.cs new file mode 100644 index 0000000..1da0844 --- /dev/null +++ b/hw5Routers/hw5Routers.Test/AlgorithmTest.cs @@ -0,0 +1,61 @@ +using NUnit.Framework; + +namespace Hw5Routers.Test +{ + public class Tests + { + [Test] + public void AlgorithmTestFirst() + { + int[,] graphFirst = + { + {0, 2, 4, 6 }, + {2, 0, 0, 8 }, + {4, 0, 0, 9 }, + {6, 8, 9, 0 } + }; + int[,] graphFirstResult = + { + {0, 0, 0, 6 }, + {0, 0, 0, 8 }, + {0, 0, 0, 9 }, + {6, 8, 9, 0 } + }; + Assert.AreEqual(AlgorithmPrima.Algorithm(graphFirst), graphFirstResult); + } + + [Test] + public void AlgorithmTestSecond() + { + int[,] graphSecond = + { + {0, 0, 0, 3 }, + {0, 0, 0, 6 }, + {0, 0, 0, 9 }, + {3, 6, 9, 0 } + }; + int[,] graphSecondResult = + { + {0, 0, 0, 3 }, + {0, 0, 0, 6 }, + {0, 0, 0, 9 }, + {3, 6, 9, 0 } + }; + Assert.AreEqual(AlgorithmPrima.Algorithm(graphSecond), graphSecondResult); + } + + [Test] + public void AlgorithmExceptionTest() + { + int[,] graph = + { + {0, 3, 0, 0}, + {3, 0, 0, 0}, + {0, 0, 0, 2}, + {0, 0, 2, 0} + }; + Assert.Throws(() => AlgorithmPrima.Algorithm(graph)); + } + + } +} \ No newline at end of file diff --git a/hw5Routers/hw5Routers.Test/FileFunctionsTest.cs b/hw5Routers/hw5Routers.Test/FileFunctionsTest.cs new file mode 100644 index 0000000..0bb3faf --- /dev/null +++ b/hw5Routers/hw5Routers.Test/FileFunctionsTest.cs @@ -0,0 +1,20 @@ +using NUnit.Framework; +using System.IO; + +namespace Hw5Routers.Test +{ + class FileFunctionsTest + { + [Test] + public void FileTest() + { + string[] result = + { + "1: 2 (10), 3 (5)" + }; + FileFunctions.WriteInFile(AlgorithmPrima.Algorithm(FileFunctions.CreateGraph("..\\..\\..\\RoutersTest.txt")), "..\\..\\RoutersTestResult.txt"); + var resultFromFile = File.ReadLines("..\\..\\RoutersTestResult.txt"); + Assert.AreEqual(result, resultFromFile); + } + } +} \ No newline at end of file diff --git a/hw5Routers/hw5Routers.Test/RoutersTest.txt b/hw5Routers/hw5Routers.Test/RoutersTest.txt new file mode 100644 index 0000000..3d90741 --- /dev/null +++ b/hw5Routers/hw5Routers.Test/RoutersTest.txt @@ -0,0 +1,2 @@ +1: 2 (10), 3 (5) +2: 3 (1) \ No newline at end of file diff --git a/hw5Routers/hw5Routers.Test/RoutersTestResult.txt b/hw5Routers/hw5Routers.Test/RoutersTestResult.txt new file mode 100644 index 0000000..58c5eed --- /dev/null +++ b/hw5Routers/hw5Routers.Test/RoutersTestResult.txt @@ -0,0 +1 @@ +1: 2 (10), 3 (5) \ No newline at end of file diff --git a/hw5Routers/hw5Routers.Test/hw5Routers.Test.csproj b/hw5Routers/hw5Routers.Test/hw5Routers.Test.csproj new file mode 100644 index 0000000..3bac018 --- /dev/null +++ b/hw5Routers/hw5Routers.Test/hw5Routers.Test.csproj @@ -0,0 +1,19 @@ + + + + netcoreapp3.1 + + false + + + + + + + + + + + + + diff --git a/hw5Routers/hw5Routers.sln b/hw5Routers/hw5Routers.sln new file mode 100644 index 0000000..bb76626 --- /dev/null +++ b/hw5Routers/hw5Routers.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31005.135 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hw5Routers", "hw5Routers\Hw5Routers.csproj", "{55F17858-3620-46FF-BF81-AF2E7DD2595D}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "hw5Routers.Test", "hw5Routers.Test\hw5Routers.Test.csproj", "{B3DF091C-3CAD-4E6A-9401-94EFDBA9E0D2}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {55F17858-3620-46FF-BF81-AF2E7DD2595D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {55F17858-3620-46FF-BF81-AF2E7DD2595D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {55F17858-3620-46FF-BF81-AF2E7DD2595D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {55F17858-3620-46FF-BF81-AF2E7DD2595D}.Release|Any CPU.Build.0 = Release|Any CPU + {B3DF091C-3CAD-4E6A-9401-94EFDBA9E0D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B3DF091C-3CAD-4E6A-9401-94EFDBA9E0D2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B3DF091C-3CAD-4E6A-9401-94EFDBA9E0D2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B3DF091C-3CAD-4E6A-9401-94EFDBA9E0D2}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {054D180F-116B-4C02-B1C8-C947EB1CCD17} + EndGlobalSection +EndGlobal diff --git a/hw5Routers/hw5Routers/AlgorithmPrima.cs b/hw5Routers/hw5Routers/AlgorithmPrima.cs new file mode 100644 index 0000000..312766d --- /dev/null +++ b/hw5Routers/hw5Routers/AlgorithmPrima.cs @@ -0,0 +1,112 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Hw5Routers +{ + /// + /// Класс, реализующий алгоритм Прима + /// + public static class AlgorithmPrima + { + private static bool CheckGraph(int[,] matrix) + { + var vertexStatus = new int[matrix.GetLength(0)]; + int number = 1; + vertexStatus[0] = number; + int count = 0; + while (count < matrix.GetLength(0) && !Check(vertexStatus)) + { + for (int i = 0; i < matrix.GetLength(0); i++) + { + if (vertexStatus[i] == number) + { + for (int j = 0; j < matrix.GetLength(0); j++) + { + if (matrix[i, j] != 0 && vertexStatus[j] == 0) + { + vertexStatus[j] = number + 1; + } + } + } + } + number++; + count++; + } + return Check(vertexStatus); + } + + private static bool Check(int[] vertexStatus) + { + for (int i = 0; i < vertexStatus.Length; i++) + { + if (vertexStatus[i] == 0) + { + return false; + } + } + return true; + } + + private static int MaxKey(int[] key, bool[] isConsist) + { + int max = int.MinValue; + int indexMax = -1; + for (int i = 0; i < key.Length; i++) + { + if (!isConsist[i] && key[i] > max) + { + max = key[i]; + indexMax = i; + } + } + return indexMax; + } + + /// + /// алгоритм Прима + /// + /// новую матрицу + public static int[,] Algorithm(int[,] matrix) + { + if (!CheckGraph(matrix)) + { + throw new GraphDisconnectedException(); + } + int size = matrix.GetLength(0); + int[] parent = new int[size]; + int[] key = new int[size]; + bool[] isConsist = new bool[size]; + for (int i = 0; i < size; i++) + { + key[i] = int.MinValue; + } + key[0] = 0; + parent[0] = -1; + for (int count = 0; count < size - 1; count++) + { + int indexFirst = MaxKey(key, isConsist); + isConsist[indexFirst] = true; + for (int indexSecond = 0; indexSecond < size; indexSecond++) + { + if (matrix[indexFirst, indexSecond] != 0 && !isConsist[indexSecond] && matrix[indexFirst, indexSecond] > key[indexSecond]) + { + parent[indexSecond] = indexFirst; + key[indexSecond] = matrix[indexFirst, indexSecond]; + } + } + } + return CreateMatrix(parent, matrix); + } + + private static int[,] CreateMatrix(int[] parent, int[,] matrix) + { + var newMatrix = new int[matrix.GetLength(0), matrix.GetLength(0)]; + for (int i = 1; i < matrix.GetLength(0); ++i) + { + newMatrix[parent[i], i] = newMatrix[i, parent[i]] = matrix[i, parent[i]]; + } + return newMatrix; + } + } +} \ No newline at end of file diff --git a/hw5Routers/hw5Routers/FileFunctions.cs b/hw5Routers/hw5Routers/FileFunctions.cs new file mode 100644 index 0000000..21b8f60 --- /dev/null +++ b/hw5Routers/hw5Routers/FileFunctions.cs @@ -0,0 +1,112 @@ +using System; +using System.IO; +using System.Collections.Generic; + +namespace Hw5Routers +{ + /// + /// класс для работы с файлами + /// + public static class FileFunctions + { + /// + /// создает граф по файлу + /// + /// матрицу графа + public static int[,] CreateGraph(string filePath) + { + if (filePath == "") + { + throw new NoParametersException(); + } + int vertices = CountVertexes(filePath); + var matrix = new int[vertices, vertices]; + using var file = new StreamReader(filePath); + string stringLine = file.ReadLine(); + while (stringLine != null) + { + string[] split = new string[] { " ", ",", ":" }; + string[] lineDrop = stringLine.Split(split, StringSplitOptions.RemoveEmptyEntries); + var numberFirst = Int32.Parse(lineDrop[0]) - 1; + for (int i = 1; i < lineDrop.Length - 1; i += 2) + { + var numberSecond = Int32.Parse(lineDrop[i]) - 1; + var distance = Int32.Parse(lineDrop[i + 1].Substring(1, lineDrop[i + 1].Length - 2)); + matrix[numberFirst, numberSecond] = matrix[numberSecond, numberFirst]; + matrix[numberFirst, numberSecond] = distance; + } + stringLine = file.ReadLine(); + } + return matrix; + } + + private static int CountVertexes(string path) + { + using var file = new StreamReader(path); + string stringLine = file.ReadLine(); + var list = new List(); + int vertice = 0; + while (stringLine != null) + { + stringLine = stringLine.Replace(':', ' '); + stringLine = stringLine.Replace(',', ' '); + string[] lineDrop = stringLine.Split(" ", StringSplitOptions.RemoveEmptyEntries); + var number = Int32.Parse(lineDrop[0]) - 1; + if (!list.Contains(number)) + { + list.Add(number); + vertice++; + } + for (int i = 0; i < lineDrop.Length / 2; ++i) + { + number = Int32.Parse(lineDrop[2 * i + 1]) - 1; + if (!list.Contains(number)) + { + list.Add(number); + vertice++; + } + } + stringLine = file.ReadLine(); + } + return vertice; + } + + /// + /// записывает итогую матрицу в файл + /// + public static void WriteInFile(int[,] matrix, string filePath) + { + if (filePath == "") + { + throw new NoParametersException(); + } + var fileOut = new FileInfo(filePath); + if (fileOut.Exists) + { + fileOut.Delete(); + } + using var newFile = new FileStream(filePath, FileMode.Create); + var file = new StreamWriter(newFile); + for (int i = 0; i < matrix.GetLength(0) - 1; i++) + { + var line = $"{i + 1}: "; + for (int j = i + 1; j < matrix.GetLength(0); ++j) + { + if (matrix[i, j] != 0) + { + line += $"{j + 1} ({matrix[i, j]}), "; + } + } + if (line != $"{i + 1}: ") + { + file.WriteLine(line.Substring(0, line.Length - 2)); + } + } + file.Close(); + if (fileOut.Exists) + { + fileOut.MoveTo(filePath); + } + } + } +} diff --git a/hw5Routers/hw5Routers/GraphDisconnectedException.cs b/hw5Routers/hw5Routers/GraphDisconnectedException.cs new file mode 100644 index 0000000..6c36378 --- /dev/null +++ b/hw5Routers/hw5Routers/GraphDisconnectedException.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Hw5Routers +{ + /// + /// Исключение, когда граф несвязанный + /// + public class GraphDisconnectedException : Exception + { + public GraphDisconnectedException() + { + } + + public GraphDisconnectedException(string message) + : base(message) + { + } + } +} diff --git a/hw5Routers/hw5Routers/NoParametersException.cs b/hw5Routers/hw5Routers/NoParametersException.cs new file mode 100644 index 0000000..8541790 --- /dev/null +++ b/hw5Routers/hw5Routers/NoParametersException.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Hw5Routers +{ + public class NoParametersException : Exception + { + public NoParametersException() + { + } + + public NoParametersException(string message) + : base(message) + { + } + } +} diff --git a/hw5Routers/hw5Routers/Program.cs b/hw5Routers/hw5Routers/Program.cs new file mode 100644 index 0000000..b859e31 --- /dev/null +++ b/hw5Routers/hw5Routers/Program.cs @@ -0,0 +1,24 @@ +using System; +using System.IO; + +namespace Hw5Routers +{ + class Program + { + static void Main(string[] args) + { + try + { + FileFunctions.WriteInFile(AlgorithmPrima.Algorithm(FileFunctions.CreateGraph(args[0])), args[1]); + } + catch (GraphDisconnectedException) + { + Console.Error.WriteLine("Граф несвязный!"); + } + catch (NoParametersException) + { + Console.Error.WriteLine("Введите параметры: путь до входного файла и путь до выходного файла."); + } + } + } +} diff --git a/hw5Routers/hw5Routers/Routers.txt b/hw5Routers/hw5Routers/Routers.txt new file mode 100644 index 0000000..3d90741 --- /dev/null +++ b/hw5Routers/hw5Routers/Routers.txt @@ -0,0 +1,2 @@ +1: 2 (10), 3 (5) +2: 3 (1) \ No newline at end of file diff --git a/hw5Routers/hw5Routers/Routers2.txt b/hw5Routers/hw5Routers/Routers2.txt new file mode 100644 index 0000000..1b57312 --- /dev/null +++ b/hw5Routers/hw5Routers/Routers2.txt @@ -0,0 +1,2 @@ +1: 2 (10) +3: 4 (1) \ No newline at end of file diff --git a/hw5Routers/hw5Routers/hw5Routers.csproj b/hw5Routers/hw5Routers/hw5Routers.csproj new file mode 100644 index 0000000..c73e0d1 --- /dev/null +++ b/hw5Routers/hw5Routers/hw5Routers.csproj @@ -0,0 +1,8 @@ + + + + Exe + netcoreapp3.1 + + +