Program.cs

379 lines | 17.519 kB Blame History Raw Download
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HyperGraph
{
    class Program
    {
        /* 6 7
        0 0 1 0 1 0 0
        0 0 0 0 0 1 0
        1 1 1 0 0 0 0
        0 0 0 1 0 1 1
        0 1 1 1 0 0 0
        0 0 0 0 1 0 1
        */

        /* 11 3
        1 1 1
        1 0 0
        1 0 0
        1 0 0
        0 1 0
        0 1 0
        0 1 0
        0 1 0
        0 0 1
        0 0 1
        1 1 1
        */

        /*
        1 0 0 0
        1 0 0 0
        1 0 0 0
        0 1 0 0
        0 1 0 0
        0 1 0 0
        0 0 1 0
        0 0 1 0
        0 0 1 0
        0 0 0 1
        0 0 0 1
        0 0 0 1
        1 1 1 1             
        */

        static void Main(string[] args)
        {
            Menu();            
        }

        //  Все перестановки графа вывести в файл
        static void ExampleAllTranspos(HyperGraph graph, System.IO.StreamWriter output)
        {
            //  Массив (лист) всех возможных перестановок одного множества (гипер-ребра)
            List<List<string>> transpos;

            //  Обработать все гипер-ребра
            for (int i = 0; i < graph.HyperEdge.Count; i++)
            {
                //  Получить массив перестановок текущего гипер-ребра
                transpos = Combinatorics<string>.Transposition(graph.HyperEdge[i]);

                // Вывод всех вершин текущего гипер-ребра 
                output.Write("Current edge include:");
                for (int g = 0; g < graph.HyperEdge[i].Count; g++)
                    output.Write(" {0}", graph.HyperEdge[i][g]);

                //  Вывод всех перестановок текущего гипер-ребра
                output.WriteLine();

                //  Вывод начальной перестановки
                output.Write("1:");
                for (int g = 0; g < graph.HyperEdge[i].Count; g++)
                    output.Write(" {0}", graph.HyperEdge[i][g]);
                output.WriteLine("\r\n\t-----------");
                //  Алгоритм перестановок не учитывает начальную, а начинает со следующей
                for (int g = 0; g < transpos.Count; g++)
                {
                    output.Write("{0}: ", g + 2);
                    for (int f = 0; f < transpos[g].Count; f++)
                        output.Write("{0} ", transpos[g][f]);
                    output.WriteLine("\r\n\t-----------");
                }
                output.WriteLine();
            }
        }

        //  Найти общие вершины для всех гипер-ребер, подсчитать количество автоморфизмов гипер-графа и вывести все перестановки оставшихся ребер
        static void ExampleTheorema(HyperGraph graph, System.IO.StreamWriter output)
        {
            //  Получить результат вычислений
            var result = Theorem.TheoremAutomorphism(graph);
            //  Выполняется ли условие согласно теореме 2
            Console.WriteLine("Is Theorem 2: " + result.isSatisfyTheorem);
            if (result.isSatisfyTheorem)
            {
                //  Вывод числа автоморфизмов в консоль
                Console.WriteLine("Count of automorphism: " + result.CountAutomorphism);
            }
            //  Выполняется ли условие согласно теореме 2
            output.WriteLine("Is Theorem 2: " + result.isSatisfyTheorem);
            //  Если да, то вывести
            if (result.isSatisfyTheorem)
            {
                //  Вывод вершин и числа автоморфизмов в файл
                output.WriteLine("Automorphism with nodes: ");
                foreach (var node in result.AutomorphismNodes)
                    output.Write(node + " ");
                output.WriteLine();
                //  Вывод всех перестановок общих вершин
                List<List<string>> transpos = Combinatorics<string>.Transposition(result.AutomorphismNodes);
                //  Вывод начальной перестановки
                output.Write("1:");
                for (int g = 0; g < result.AutomorphismNodes.Count; g++)
                    output.Write(" {0}", result.AutomorphismNodes[g]);
                output.WriteLine("\r\n\t-----------");
                //  Алгоритм перестановок не учитывает начальную, а начинает со следующей
                for (int g = 0; g < transpos.Count; g++)
                {
                    output.Write("{0}: ", g + 2);
                    for (int f = 0; f < transpos[g].Count; f++)
                        output.Write("{0} ", transpos[g][f]);
                    output.WriteLine("\r\n\t-----------");
                }                

                output.WriteLine("\r\nCount of automorphism: " + result.CountAutomorphism + "\r\n");

                //  Вывести перестановки в файл
                ExampleAllTranspos(result.GraphWithoutAutoEdges, output);
                //output.Write("Automorphism with nodes: ");                
            }
            //  Уничтожить временный граф
            result.GraphWithoutAutoEdges.Dispose();
        }

        static void Menu()
        {
            string inputPath = "D:\\input.txt", outputPath = "D:\\output.txt";
            System.IO.StreamReader input;
            System.IO.StreamWriter output;
            //  Экземпляр гипер-графа, созданный на основе загружаемой матрицы инцидентности
            HyperGraph graph = null;

            while (true)
            {
                Console.Write("Путь к файлу входных данных (матрица инцидентности): ");
                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine(inputPath);              
                Console.ResetColor();
                Console.Write("Путь к файлу результатов: ");
                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine(outputPath);
                Console.ResetColor();

                Console.WriteLine("\nДля выбора пункта меню введите соответствующую цифру.\n");
                Console.WriteLine("1. Изменить путь к файлу входных данных.");
                Console.WriteLine("2. Изменить путь к файлу результатов.\n");

                if (graph == null)
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("3. Выполнить загрузку гиперграфа из файла.\n");
                    Console.ResetColor();
                }
                else
                    Console.WriteLine("3. Выполнить загрузку гиперграфа из файла.\n");
                Console.WriteLine("4. Вывести все перестановки вершин в ребрах гиперграфа.");
                Console.WriteLine("5. Выполнить расчет числа автоморфизмов согласно теореме 1.");
                Console.WriteLine("6. Выполнить расчет числа автоморфизмов согласно теореме 2.");

                Console.WriteLine("\n0. Выход.\n");                

                ConsoleKeyInfo key = Console.ReadKey(true);

                input = null; output = null;
                switch (key.Key)
                {
                    case ConsoleKey.D1:
                        {
                            Console.Clear();
                            Console.WriteLine("Пример: " + @"D:\\input.txt");
                            Console.WriteLine("Введите полный путь к файлу входных данных:");
                            var path = Console.ReadLine();
                            if (System.IO.File.Exists(path))
                            {
                                inputPath = path;
                                Console.WriteLine("Файл существует.");
                            }
                            else
                            {
                                PrintError("Файл не найден. Искомый путь: " + path);
                            }
                        } break;
                    case ConsoleKey.D2:
                        {
                            Console.Clear();
                            Console.WriteLine("Пример: " + @"D:\\output.txt");
                            Console.ForegroundColor = ConsoleColor.Red;
                            Console.Write("Внимание!");
                            Console.ResetColor();
                            Console.WriteLine(" Файл будет перезаписан или создан.");
                            Console.WriteLine("Введите полный путь к файлу результатов:");
                            var path = Console.ReadLine();
                            if (LoadStreamWriter(out output, path))
                                outputPath = path;
                        } break;
                    case ConsoleKey.D3:
                        {
                            Console.Clear();
                            
                            if (LoadStreamReader(out input, inputPath))
                            {
                                input.BaseStream.Position = 0;                                
                                try
                                {
                                    graph = new HyperGraph(Matrix<int>.LoadFromStream(input));
                                    Console.WriteLine("Гиперграф загружен.");
                                }
                                catch (Exception e)
                                {
                                    PrintError(e.Message);
                                }
                                input.Close();
                            }                           
                        } break;
                    case ConsoleKey.D4:
                        {
                            Console.Clear();
                            if (graph != null)
                            {                                
                                try
                                {
                                    LoadStreamWriter(out output, outputPath);
                                    //  Все перестановки гипер-графа
                                    ExampleAllTranspos(graph, output);
                                    Console.WriteLine("\nВывод выполнен в файл: " + outputPath);
                                }
                                catch (Exception e)
                                {
                                    PrintError(e.Message);
                                }
                            }
                            else
                            {
                                PrintError("Гиперграф не загружен.");
                            }                           
                        }
                        break;
                    case ConsoleKey.D5:
                        {
                            Console.Clear();
                            if (graph != null)
                            {
                                try
                                {
                                    //  Если НЕ удовлетворяет условию "в каждом гиперребре одинаковое количество вершин"
                                    if (!Theorem.isEqualNumberOfVertices(graph))
                                    {
                                        LoadStreamWriter(out output, outputPath);
                                        //  Вычислить количество автоморфизмов графа и вывести перестановки
                                        ExampleTheorema(graph, output);
                                        output.Close();
                                        Console.WriteLine("\nВывод выполнен в файл: " + outputPath);
                                    }
                                    else
                                    //  Нужно вычислять по другой теореме
                                    {
                                        Console.WriteLine("\nЧисло автоморфизмов графа должно вычисляться по теореме 2.");
                                    }
                                }
                                catch (Exception e)
                                {
                                    PrintError(e.Message);
                                }
                            }
                            else
                            {
                                PrintError("Гиперграф не загружен.");
                            }
                            
                        } break;
                    case ConsoleKey.D6:
                        {
                            Console.Clear();
                            if (graph != null)
                            {
                                try
                                {
                                    //  Если удовлетворяет условию "в каждом гиперребре одинаковое количество вершин"
                                    if (Theorem.isEqualNumberOfVertices(graph))
                                    {
                                        LoadStreamWriter(out output, outputPath);
                                        //  Вычислить количество автоморфизмов графа
                                        var result = Theorem.TheoremAutomorphismForEqualNumberOfVertices(graph);
                                        output.WriteLine("\r\nCount of automorphism: " + result + "\r\n");
                                        output.Close();
                                        Console.WriteLine("\nВывод выполнен в файл: " + outputPath);
                                    }
                                    else
                                    //  Нужно вычислять по другой теореме
                                    {
                                        Console.WriteLine("\nЧисло автоморфизмов графа должно вычисляться по теореме 1.");
                                    }
                                }
                                catch (Exception e)
                                {
                                    PrintError(e.Message);
                                }
                            }
                            else
                            {
                                PrintError("Гиперграф не загружен.");
                            }
                        } break;
                    case ConsoleKey.D0: { if (input != null) input.Close(); if (output != null) output.Close(); Environment.Exit(0); } break;
                    default: break;
                }
                if (input != null)
                    input.Close();
                if (output != null)
                    output.Close();

                Console.WriteLine("\nДля продолжения нажмите любую клавишу.");
                Console.ReadKey();
                Console.Clear();
            }
            
        }

        static bool LoadStreamReader(out System.IO.StreamReader stream, string path)
        {
            try
            {
                stream = new System.IO.StreamReader(path);
                return true;
            }
            catch (Exception e)
            {
                PrintError(new string[] { e.Message, "Укажите корректный путь к файлу входных данных." });
                stream = null;
                return false;
            }
        }

        static bool LoadStreamWriter(out System.IO.StreamWriter stream, string path)
        {
            try
            {
                stream = new System.IO.StreamWriter(path);
                return true;
            }
            catch (Exception e)
            {
                PrintError(e.Message);
                stream = null;
                return false;
            }
        }

        static void PrintError(string message)
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine(message);
            Console.ResetColor();
        }
        static void PrintError(string[] messages)
        {
            Console.ForegroundColor = ConsoleColor.Red;
            foreach (var message in messages)
                Console.WriteLine(message);
            Console.ResetColor();
        }
    }
}