/// <summary>Создает случайный граф</summary>
        /// <param name="elements">Количество элементов</param>
        /// <returns>Созданный граф</returns>
        private static Graph CreateRandomGraph(int elements = ELEMENTS)
        {
            Graph newGraph = new Graph();

            //Добавляем в граф вершины
            for (int i = 0; i < elements; i++)
            {
                newGraph.AddNode(i);
            }

            GraphPrinter.CreateGraphInfo(newGraph);

            //Добавляем связи между вершинами
            for (int i = 0; i < elements; i++)
            {
                for (int j = 0; j < rnd.Next(1) + 2; j++)
                {
                    bool isGenerated = false;
                    while (!isGenerated)
                    {
                        int toNode = rnd.Next(elements);
                        if (toNode != i)
                        {
                            isGenerated = newGraph.AddEdge(i, toNode, rnd.Next(MAX_WEIGHT));
                        }
                        if (newGraph.Nodes[i].Edges.Count >= 2)
                        {
                            isGenerated = true;
                        }
                    }
                }
            }
            return(newGraph);
        }
Exemple #2
0
        /// <summary>
        /// Поиск (обход) графа в глубину
        /// </summary>
        /// <param name="id">Искомое значение</param>
        /// <returns>true, если вершина с таким значением есть в графе</returns>
        public bool DFS(int id)
        {
            GraphPrinter.ClearText();//Очищаем текстовый буфер печатальщика
            bool isFound = DFS(id, this.Nodes[0]);

            ColorPrint("Поиск завершен");
            Console.WriteLine();
            return(isFound);
        }
Exemple #3
0
 /// <summary>Вывод дерева на экран с раскраской вершин
 /// Используется для визуализации алгоритмов обхода графа</summary>
 /// <param name="line">Строка идущая в текстовый буфер</param>
 private void ColorPrint(string line = null)
 {
     Console.Clear();
     if (line != null)
     {
         GraphPrinter.AddText(line);
     }
     GraphPrinter.Print(this, false);
     System.Threading.Thread.Sleep(Delay);//небольшая задержка для наглядности работы алгоритма
 }
Exemple #4
0
        /// <summary>
        /// Поиск (обход) графа в ширину
        /// </summary>
        /// <param name="id">Искомое значение</param>
        /// <returns>true, если вершина с таким значением есть в графе</returns>
        public bool BFS(int id)
        {
            GraphPrinter.ClearText();                //Очищаем текстовый буфер печатальщика

            Queue <Node> bufer = new Queue <Node>(); //Сюда будут заносится вершины для последующей проверки

            bufer.Enqueue(this.Nodes[0]);            //Обход начинаем с 0-й вершины

            bool isFound = false;

            //Повторяем до тех пор пока не найдем или пока не кончатся вершины
            while (bufer.Count != 0 && !isFound)
            {
                Node element = bufer.Dequeue();//Достаем элемент из очереди
                if (element.ID == id)
                {
                    isFound = true;                  //Если это нужны элемент то радуемся
                }
                //Выставляем флаг проверки того, что элемент обрабатывается или найден
                //ПУРПУРНЫЙ - элемент в процессе обработки
                //ЗЕЛЕНЫЙ - элемент обработан и совпадает с искомым значением
                element.State = isFound ? Node.Status.founded : Node.Status.in_process;
                ColorPrint($"Проверяемая вершина: {element.ID}");

                if (!isFound)//Если не нашли значение то добавляем сопряженные вершины в очередь на проверку
                {
                    foreach (Edge edge in element.Edges)
                    {
                        if (edge.ConnectedNode.State == Node.Status.not_processed)
                        {
                            //ЖЕЛТЫЙ - элемент помещается в очередь для последующей обработки
                            edge.ConnectedNode.State = Node.Status.marked_to_process;
                            bufer.Enqueue(edge.ConnectedNode);
                            ColorPrint($"Вершина {edge.ConnectedNode.ID} идет в очередь");
                        }
                    }
                    //КРАСНЫЙ - элемент обработан
                    element.State = Node.Status.processed;
                }
            }
            ColorPrint("Поиск завершен");
            Console.WriteLine();

            return(isFound);
        }
        /// <summary>Меню передвижения вершины</summary>
        /// <param name="graph">Граф</param>
        /// <param name="menu">Содержание меню</param>
        private static void MoveMenu(Graph graph, string[] menu)
        {
            string menuMessage = MenuMessage(menu);
            int    id          = NumberInput(messages[Messages.EnterNumber], 0, graph.Count - 1, false);

            graph.FindNode(id).State = Node.Status.marked_to_process;
            Print(graph, false);
            bool isExit = false;

            while (!isExit)
            {
                int input = NumberInput(menuMessage, 0, menu.Length - 1);
                switch (input)
                {
                case 1:    //Left
                    GraphPrinter.MoveNode(id, -1, 0);
                    break;

                case 2:    //Right
                    GraphPrinter.MoveNode(id, 1, 0);
                    break;

                case 3:    //Down
                    GraphPrinter.MoveNode(id, 0, 1);
                    break;

                case 4:    //Up
                    GraphPrinter.MoveNode(id, 0, -1);
                    break;

                case 5:    //change node
                    Print(graph);
                    id = NumberInput(messages[Messages.EnterNumber], 0, graph.Count - 1, false);
                    graph.FindNode(id).State = Node.Status.marked_to_process;
                    break;

                case 0:    //exit
                    isExit = true;
                    break;
                }
                Console.Clear();
                Print(graph, false);
            }
        }
        /// <summary>Создает заранее зарадкоженый граф (для наглядности ДЗ)</summary>
        /// <returns>Созданный граф</returns>
        private static Graph CreatePredefinedGraph()
        {
            const int ELEMENTS_PREDEF = 15;

            Graph newGraph = new Graph();

            //Добавляем в граф вершины
            for (int i = 0; i < ELEMENTS_PREDEF; i++)
            {
                newGraph.AddNode(i);
            }

            //Предварительное создание массива координат вершин
            GraphPrinter.CreateGraphInfo(newGraph);

            //Расставляем вершины так как нам нужно
            int[,] coords =
            {
                { 32,  0 }, { 16,  3 }, { 32,  4 }, { 48,  2 }, {  6,  7 }, { 24,  7 }, { 36,  8 }, { 54, 7 },
                {  7, 11 }, { 22, 12 }, { 36, 12 }, { 54, 12 }, { 18, 15 }, { 30, 15 }, { 34, 19 }
            };

            for (int i = 0; i < ELEMENTS_PREDEF; i++)
            {
                GraphPrinter.MoveNode(i, coords[i, 0], coords[i, 1], false);
            }

            //Добавляем ребра
            int[,] edges =
            {
                { 0,  1 }, {  0,  2 }, {  0,  3 }, {  1,  4 }, {  1,  5 }, { 2,  6 }, { 3, 6 }, { 3,  7 },
                { 4,  8 }, {  5,  9 }, {  5, 10 }, {  6, 10 }, {  6, 11 }, { 7, 11 }, { 8, 9 }, { 8, 12 },
                { 9, 13 }, { 10, 13 }, { 11, 14 }, { 13, 14 }, { 12, 14 }
            };

            for (int i = 0; i < edges.Length / 2; i++)
            {
                newGraph.AddEdge(edges[i, 0], edges[i, 1], rnd.Next(MAX_WEIGHT));
            }

            return(newGraph);
        }
        /// <summary>Меню работы с графом</summary>
        /// <param name="graph">Граф</param>
        /// <param name="menu">Содержание меню</param>
        private static Graph GraphMenu(Graph graph, string[] menu)
        {
            string menuMessage = MenuMessage(menu);

            Print(graph);
            bool isExit = false;

            while (!isExit)
            {
                int input = NumberInput(menuMessage, 0, menu.Length - 1);
                switch (input)
                {
                case 1:    //add edge between two nodes
                    Print(graph);
                    int firstID  = NumberInput(messages[Messages.EnterNumber], 0, graph.Count - 1, false);
                    int secondID = NumberInput(messages[Messages.EnterNumber], 0, graph.Count - 1, false);
                    int weight   = NumberInput(messages[Messages.EnterNumber], 0, MAX_WEIGHT - 1, false);
                    graph.AddEdge(firstID, secondID, weight);
                    Print(graph);
                    break;

                case 2:    //add edge between two nodes
                    Print(graph);
                    firstID  = NumberInput(messages[Messages.EnterNumber], 0, graph.Count - 1, false);
                    secondID = NumberInput(messages[Messages.EnterNumber], 0, graph.Count - 1, false);
                    graph.RemoveEdge(firstID, secondID);
                    Print(graph);
                    break;

                case 3:    //change two nodes
                    Print(graph);
                    firstID  = NumberInput(messages[Messages.EnterNumber], 0, graph.Count - 1, false);
                    secondID = NumberInput(messages[Messages.EnterNumber], 0, graph.Count - 1, false);
                    GraphPrinter.ChangeTwoNodes(firstID, secondID);
                    Print(graph);
                    break;

                case 4:    //move one node
                    Print(graph);
                    MoveMenu(graph, moveMenu);
                    break;

                case 5:    //create random graph
                    Print(graph);
                    graph = CreateGraph(true, elements);
                    break;

                case 6:    //return to default graph
                    Print(graph);
                    graph = CreateGraph(false);
                    break;

                case 0:    //exit
                    isExit = true;
                    break;
                }
                Console.Clear();
                Print(graph);
            }
            return(graph);
        }
 /// <summary>Вызов печати графаы</summary>
 /// <param name="graph"></param>
 /// <param name="isColorsClear"></param>
 private static void Print(Graph graph, bool isColorsClear = true)
 {
     Console.Clear();
     GraphPrinter.ClearText();
     GraphPrinter.Print(graph, isColorsClear);
 }