Pārlūkot izejas kodu

Merge branch 'addAlgDeykstra'

klmnvan 5 mēneši atpakaļ
vecāks
revīzija
78f8b62d30

+ 1 - 0
MathModelingSimulator/Assets/TheoryDijkstra.txt

@@ -4,3 +4,4 @@
 1. Каждой вершине графа ставим метку – минимальное известное расстояние от этой вершины до вершины A. Для стартовой – это 0, для остальных – ?, т.к. пока неизвестны.
 2. На каждом следующем шаге нужно посетить одну вершину для уменьшения значения метки. Начинаем посещать с той, метка которой минимальная. Сравниваем метку вершины A и нового пути до этой вершины и выбираем минимальное значение.
 3. Алгоритм продолжается, пока все вершины не будут посещены.
+В ответ на задание запишите минимальный путь от 1 точки до любой, путь до которой наибольший

+ 83 - 0
MathModelingSimulator/Function/Dijkstra'sAlgorithm.cs

@@ -0,0 +1,83 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MathModelingSimulator.Function
+{
+    public class Dijkstra_sAlgorithm
+    {
+        int cPoint; //Количество точек
+        int[,] aMatrix; //Матрица со значениями весов ребер
+        int startPMain; //Начало маршрута
+        List<(int, int)> aRoutes = new List<(int, int)>(); //(путь, числовая характеристика)
+
+        public string? Start(int cPoint, int startPMain, int[,] aMatrix, List<(int, int)> aRoutes)
+        {
+            this.cPoint = cPoint;
+            this.startPMain = startPMain;
+            this.aMatrix = aMatrix;
+            this.aRoutes = aRoutes;
+            return SearchRoutes();
+        }
+
+        string? SearchRoutes()
+        {
+            //Перебираем все точки, которые нужно найти из aRoutes
+            for (int i = 0; i < aRoutes.Count; i++)
+            {
+                List<int> passedP = new List<int>();
+                aRoutes[i] = SearchMin(startPMain, aRoutes[i], 0, passedP);
+            }
+            string answer = aRoutes.FirstOrDefault(it => it.Item2 == aRoutes.Select(it => it.Item2).Max()).Item2.ToString();
+            return answer;
+        }
+
+        (int, int) SearchMin(int startP, (int, int) searchP, int sum, List<int> passedP)
+        {
+            //Когда из первой строки сразу находится искомое значение
+            if (aMatrix[startP, searchP.Item1] != -1)
+            {
+                int startEqual = sum + aMatrix[startP, searchP.Item1];
+                if (searchP.Item2 > startEqual) searchP.Item2 = startEqual;
+            }
+            for (int j = 0; j < cPoint; j++)
+            {
+                //Проверка, что данная точка ещё не была посещена, не равна искомой (т.к. это проверяется сверху) и не пустая
+                if (passedP.IndexOf(j) == -1 && j != searchP.Item1 && aMatrix[startP, j] != -1)
+                { 
+                    if (startP == startPMain) sum = 0;
+                    sum += aMatrix[startP, j];
+                    passedP.Add(startP);
+                    List<int> buffer = new List<int>(passedP);
+                    searchP = SearchMin(j, searchP, sum, buffer);
+                }
+            }
+            return searchP;
+        }
+
+        void InputData()
+        {
+            //Ввод матрицы маршрутов
+            aMatrix = new int[cPoint, cPoint];
+            int count;
+            Console.WriteLine("Заполните матрицу со значениями весов ребер: ");
+            for (int i = 0; i < cPoint; i++)
+            {
+                string[] buffer = new string[cPoint - 1];
+                //Вводится строка таблицы с числами через пробел в буферную строку
+                buffer = Console.ReadLine().Split(" ").ToArray();
+                count = 0;
+                //Буферная строка подставляется в массив таблицы метода
+                foreach (string k in buffer)
+                {
+                    if (k != "-") aMatrix[i, count] = Convert.ToInt32(k);
+                    else aMatrix[i, count] = -1;
+                    count++;
+                }
+                if (i != startPMain) aRoutes.Add((i, int.MaxValue));
+            }
+        }
+    }
+}

+ 239 - 31
MathModelingSimulator/ViewModels/CreateSimulatorViewModel.cs

@@ -10,6 +10,7 @@ using System.Diagnostics;
 using Avalonia.Media;
 using MathModelingSimulator.Views;
 using MathModelingSimulator.Function;
+using static System.Runtime.InteropServices.JavaScript.JSType;
 
 namespace MathModelingSimulator.ViewModels
 {
@@ -51,21 +52,56 @@ namespace MathModelingSimulator.ViewModels
 		public List<string> ListSimulatorsView { get => listSimulatorsView; set => SetProperty(ref listSimulatorsView, value); }
 
 		string selectedSimulator = "";
-		public string SelectedSimulator { get => selectedSimulator; set => SetProperty(ref selectedSimulator, value); }
+		public string SelectedSimulator 
+		{ 
+			get 
+            {
+                if (selectedSimulator == "Àëãîðèòì Äåéêñòðû")
+                {
+                    MessageDykstra = "Ïðè ââîäå âðó÷íóþ: åñëè äî òî÷êè íåò ïóòè, îñòàâüòå ïîëå ïóñòûì\nÏðè ñ÷èòûâàíèè èç ôàéëà: åñëè äî òî÷êè íåò ïóòè óêàæèòå çíàêîì\"-\"\n îòâåò çàïèøèòå ìèíèìàëüíûé ïóòü îò 1 òî÷êè äî ëþáîé, ïóòü äî êîòîðîé íàèáîëüøèé";
+                    IsVisibleMessageDykstra = true;
+                }
+                else
+                {
+                    IsVisibleMessageDykstra = false;
+                }
+                return selectedSimulator;
+            } 
+			set 
+			{ 
+				SetProperty(ref selectedSimulator, value); 
+				if(selectedSimulator == "Àëãîðèòì Äåéêñòðû")
+				{
+					MessageDykstra = "Ïðè ââîäå âðó÷íóþ: åñëè äî òî÷êè íåò ïóòè, îñòàâüòå ïîëå ïóñòûì\nÏðè ñ÷èòûâàíèè èç ôàéëà: åñëè äî òî÷êè íåò ïóòè óêàæèòå çíàêîì\"-\"\n îòâåò çàïèøèòå ìèíèìàëüíûé ïóòü îò 1 òî÷êè äî ëþáîé, ïóòü äî êîòîðîé íàèáîëüøèé";
+					IsVisibleMessageDykstra = true;
+				}
+				else
+				{
+					IsVisibleMessageDykstra = false;
+				}
+			}
+		}
 
         string answer = "";
         public string Answer { get => answer; set => SetProperty(ref answer, value); }
 		#endregion
 
 		int[,] _matrixBD;
+		int?[,] _matrixBDD;
 		int _idTask = 0;
 
         private string messageRezult = "";
         public string MessageRezult { get => messageRezult; set => this.SetProperty(ref messageRezult, value); }
 
+        private string messageDykstra = "";
+        public string MessageDykstra { get => messageDykstra; set => this.SetProperty(ref messageDykstra, value); }
+
         private bool isVisibleRezult = false;
         public bool IsVisibleRezult { get => isVisibleRezult; set => this.SetProperty(ref isVisibleRezult, value); }
 
+        private bool isVisibleMessageDykstra = false;
+        public bool IsVisibleMessageDykstra { get => isVisibleMessageDykstra; set => this.SetProperty(ref isVisibleMessageDykstra, value); }
+
         public CreateSimulatorViewModel()
 		{
 			listSimulators = ContextDb.Simulators.ToList();
@@ -98,12 +134,56 @@ namespace MathModelingSimulator.ViewModels
                     case "Çàäà÷à Êîììèâîÿæåðà": GetTravelingSalesmanProblem(); break;
                     case "Òðàíñïîðòíûå çàäà÷è. Ìåòîä àïïðîêñèìàöèè Ôîãåëÿ": GetAnswerZadFogel(); break;
                     case "Çàäà÷à Äæîíñîíà": GetAnswerZadDzhonsons(); break;
-                    case "Àëãîðèòì Äåéêñòðû": MessageRezult = "ß ïîêà íå óìåþ òàêîå ðåøàòü"; break;
+                    case "Àëãîðèòì Äåéêñòðû": GetAnswerZadDeykstra(); break;
                 }
             }
 		}
 
-		void GetAnswerZadFogel()
+        void GetAnswerZadDeykstra()
+        {
+            if(CountRows == CountColumns)
+            {
+                Dijkstra_sAlgorithm dijkstra_SAlgorithm = new Dijkstra_sAlgorithm();
+                var aMatrix = new int[_matrixBDD.GetLength(0), _matrixBDD.GetLength(0)];
+                List<(int, int)> aRoutes = new List<(int, int)>();
+                for (int i = 0; i < _matrixBDD.GetLength(0); i++)
+                {
+                    for (int j = 0; j < _matrixBDD.GetLongLength(1); j++)
+                    {
+                        if (_matrixBDD[i, j] != null)
+                        {
+                            aMatrix[i, j] = (int)_matrixBDD[i, j];
+                            _matrixBD[i, j] = (int)_matrixBDD[i, j];
+                        }
+                        else
+                        {
+                            aMatrix[i, j] = -1;
+                            _matrixBD[i, j] = -1;
+                        }
+                    }
+                    if (i != 0) aRoutes.Add((i, int.MaxValue));
+                }
+                var rezult = dijkstra_SAlgorithm.Start(_matrixBDD.GetLength(0), 0, aMatrix, aRoutes);
+                if (rezult != null)
+                {
+                    Answer = rezult.ToString();
+                }
+                else
+                {
+                    IsVisibleRezult = true;
+                    MessageRezult = "Âàøà ìàòðèöà íå ïîäõîäèò äëÿ ýòîé çàäà÷è";
+                    Answer = "0";
+                }
+            }
+            else
+            {
+                IsVisibleRezult = true;
+                MessageRezult = "Âàøà ìàòðèöà íå ïîäõîäèò äëÿ ýòîé çàäà÷è";
+                Answer = "0";
+            }
+        }
+
+        void GetAnswerZadFogel()
 		{
             BasicMethods mFodel = new BasicMethods();
 			var ai = new int[_matrixBD.GetLength(1) - 1];
@@ -147,18 +227,44 @@ namespace MathModelingSimulator.ViewModels
 
 
         void fillMatrix()
-		{
+        {
             var countRows = matrix.Children.Count;
             var countColumns = (matrix.Children[0] as StackPanel).Children.Count;
-            _matrixBD = new int[countRows, countColumns];
+            if (selectedSimulator != "Àëãîðèòì Äåéêñòðû")
+            {
+                _matrixBD = new int[countRows, countColumns];
+            }
             for (int i = 0; i < countRows; i++)
             {
                 for (int j = 0; j < countColumns; j++)
                 {
-                    var buffer = (matrix.Children[i] as StackPanel).Children[j].Name.Split(" ").Select(int.Parse).ToList();
-                    _matrixBD[Convert.ToInt32(buffer[0]), Convert.ToInt32(buffer[1])] = Convert.ToInt32(((matrix.Children[i] as StackPanel).Children[j] as TextBox).Text);
+                    if (selectedSimulator != "Àëãîðèòì Äåéêñòðû")
+                    {
+                        var buffer = (matrix.Children[i] as StackPanel).Children[j].Name.Split(" ").Select(int.Parse).ToList();
+                        _matrixBD[Convert.ToInt32(buffer[0]), Convert.ToInt32(buffer[1])] = Convert.ToInt32(((matrix.Children[i] as StackPanel).Children[j] as TextBox).Text);
+                    }
+                    else
+                    {
+                        if(CountRows == CountColumns)
+                        {
+                            List<int?> buffer = (matrix.Children[i] as StackPanel)?.Children[j]?.Name
+                                .Split(" ")
+                                .Select(it => (it == "-") ? (int?)null : int.TryParse(it, out var result) ? (int?)result : null)
+                                .ToList();
+                            string textValue = ((matrix.Children[i] as StackPanel)?.Children[j] as TextBox)?.Text;
+                            int? valueToAdd = null;
+
+                            if (!string.IsNullOrEmpty(textValue))
+                            {
+                                valueToAdd = Convert.ToInt32(textValue);
+                            }
+
+                            _matrixBDD[buffer[0] ?? 0, buffer[1] ?? 0] = valueToAdd;
+                        }
+                    }
                 }
             }
+
         }
 
         void GetAnswerZadDzhonsons()
@@ -285,6 +391,7 @@ namespace MathModelingSimulator.ViewModels
 		public async void AttachFileClick()
 		{
 			int[,] newMatrix = null;
+			int?[,] newMatrixD = null;
 			IsVisibleEnterMatrix = false;
 			var topLevel = TopLevel.GetTopLevel(PageSwitch.View);
 			var files = await topLevel.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
@@ -296,9 +403,17 @@ namespace MathModelingSimulator.ViewModels
 			{
 				await using var stream = await files[0].OpenReadAsync(); //Îòêðûâàåò ôàéë äëÿ ÷òåíèÿ 
 				using var streamReader = new StreamReader(stream);
-				newMatrix = ReadFilesToTwoArray(stream);
+				if (selectedSimulator == "Àëãîðèòì Äåéêñòðû")
+				{
+                    newMatrixD = ReadFilesToTwoArrayD(stream);
+                    ShowMatrixD(newMatrixD);
+                }
+				else
+				{
+                    newMatrix = ReadFilesToTwoArray(stream);
+                    ShowMatrix(newMatrix);
+                } 
 			}
-			ShowMatrix(newMatrix);
 		}
 
 		/// <summary>
@@ -335,37 +450,85 @@ namespace MathModelingSimulator.ViewModels
             }
 		}
 
-		/// <summary>
-		/// ×òåíèå èç ôàéëà â ìàññèâ
+        /// <summary>
+		/// Îòîáðàæàåò ìàòðèöó
 		/// </summary>
-		/// <param name="stream"></param>
-		/// <returns></returns>
-		private int[,] ReadFilesToTwoArray(Stream stream)
+		public async void ShowMatrixD(int?[,] taskMatrix)
+        {
+            Matrix = new StackPanel();
+            Matrix.Margin = new Avalonia.Thickness(0, 10, 0, 0);
+            _matrixBD = new int[taskMatrix.GetLength(0), taskMatrix.GetLength(1)];
+            for (int i = 0; i < taskMatrix.GetLength(0); i++)
+            {
+                StackPanel lbHorizontal = new StackPanel();
+                lbHorizontal.Margin = new Avalonia.Thickness(0, 0, 0, 10);
+                List<TextBox> listTextBox = new List<TextBox>();
+                int count = 0;
+               
+                for (int j = 0; j < taskMatrix.GetLength(1); j++)
+                {
+                    if (taskMatrix[i,j] == null)
+                    {
+                        _matrixBD[i,j] = -1;
+                    }
+                    else
+                    {
+                        _matrixBD[i, j] = (int)taskMatrix[i, j];
+                    }
+                    TextBox textBox = new TextBox();
+                    textBox.Text = taskMatrix[i, j].ToString();
+                    textBox.Padding = new Avalonia.Thickness(20);
+                    textBox.HorizontalContentAlignment = Avalonia.Layout.HorizontalAlignment.Center;
+                    textBox.VerticalContentAlignment = Avalonia.Layout.VerticalAlignment.Center;
+                    textBox.CornerRadius = new Avalonia.CornerRadius(10);
+                    textBox.BorderThickness = new Avalonia.Thickness(1);
+                    count++;
+                    textBox.Name = $"{i} {j} {count}"; //i j (íîìåð ýëåìåíòà)
+                    textBox.BorderBrush = new SolidColorBrush(0xFF09A0B3);
+                    textBox.Margin = new Avalonia.Thickness(10, 0);
+                    listTextBox.Add(textBox);
+                    if(i == j)
+                    {
+                        textBox.Text = null;
+                        textBox.IsEnabled = false;
+                    }
+                }
+                lbHorizontal.Children.Add(listTextBox);
+                lbHorizontal.Orientation = Avalonia.Layout.Orientation.Horizontal;
+                Matrix.Children.Add(lbHorizontal);
+            }
+        }
+
+        /// <summary>
+        /// ×òåíèå èç ôàéëà â ìàññèâ
+        /// </summary>
+        /// <param name="stream"></param>
+        /// <returns></returns>
+        private int[,] ReadFilesToTwoArray(Stream stream)
 		{
 			try
 			{
 				List<List<int>> tempList = new List<List<int>>();
 				using (StreamReader reader = new StreamReader(stream))
 				{
-					string? line;
+                    string? line;
 					while ((line = reader.ReadLine()) != null)
 					{
-						tempList.Add(line.Split(';', ',', ' ').Select(int.Parse).ToList());
-					}
+                        tempList.Add(line.Split(';', ',', ' ').Select(int.Parse).ToList());
+                    }
 				}
-				// Ïðåîáðàçîâàíèå tempList â äâóìåðíûé ìàññèâ int[,]
-				int[,] array = new int[tempList.Count, tempList[0].Count];
-				for (int i = 0; i < tempList.Count; i++)
-				{
-					for (int j = 0; j < tempList[i].Count; j++)
-					{
-						array[i, j] = tempList[i][j];
-					}
-				}
-				CountRows = array.GetLength(0);
-				CountColumns = array.GetLength(1);
-				return array;
-			}
+                int[,] array = new int[tempList.Count, tempList[0].Count];
+                for (int i = 0; i < tempList.Count; i++)
+                {
+                    for (int j = 0; j < tempList[i].Count; j++)
+                    {
+                        array[i, j] = tempList[i][j];
+                    }
+                }
+                CountRows = array.GetLength(0);
+                CountColumns = array.GetLength(1);
+                return array;
+            }
 			catch
 			{
 				Trace.Listeners.Add(logFileListener);
@@ -374,5 +537,50 @@ namespace MathModelingSimulator.ViewModels
 			}
 		}
 
-	}
+        /// <summary>
+        /// ×òåíèå èç ôàéëà â ìàññèâ
+        /// </summary>
+        /// <param name="stream"></param>
+        /// <returns></returns>
+        private int?[,] ReadFilesToTwoArrayD(Stream stream)
+        {
+            try
+            {
+                List<List<int?>> tempListD = new List<List<int?>>();
+                using (StreamReader reader = new StreamReader(stream))
+                {
+                    string? line;
+                    while ((line = reader.ReadLine()) != null)
+                    {
+                        var listBuf = line.Split(';', ',', ' ').ToList();
+                        List<int?> tempD = new List<int?>();
+                        for (int i = 0; i < listBuf.Count; i++)
+                        {
+                            if (listBuf[i] == "-") tempD.Add(null);
+                            else tempD.Add(Convert.ToInt32(listBuf[i]));
+                        }
+                        tempListD.Add(tempD);
+                    }
+                }
+                _matrixBDD = new int?[tempListD.Count, tempListD[0].Count];
+                for (int i = 0; i < tempListD.Count; i++)
+                {
+                    for (int j = 0; j < tempListD[i].Count; j++)
+                    {
+                        _matrixBDD[i, j] = tempListD[i][j];
+                    }
+                }
+                CountRows = _matrixBDD.GetLength(0);
+                CountColumns = _matrixBDD.GetLength(1);
+                return _matrixBDD;
+            }
+            catch
+            {
+                Trace.Listeners.Add(logFileListener);
+                Trace.WriteLine("ERROR CreateSimulatorVM: Ïîëüçîâàòåëü ïðèêðåïèë ïóñòîé ôàéë èëè íåïðàâèëüíûé ôîðìàò");
+                return null;
+            }
+        }
+
+    }
 }

+ 11 - 0
MathModelingSimulator/Views/CreateSimulatorView.axaml

@@ -92,6 +92,17 @@
 					Padding="15 8"
 					Command="{Binding CreateSimulatorVM.EnterMatrix}"/>
 
+				<TextBlock
+					Grid.Column="1"
+					Grid.Row="0"
+					FontSize="14"
+					Foreground="#FFFFFF"
+					Margin="0 10 0 0"
+					HorizontalAlignment="Center"
+					TextWrapping="Wrap"
+					IsVisible="{Binding CreateSimulatorVM.IsVisibleMessageDykstra}"
+					Text="{Binding CreateSimulatorVM.MessageDykstra}"/>
+
 				<Grid ColumnDefinitions="*, *"
 					  Margin="0 30 0 0"
 					  RowDefinitions="*"