HyperGraph

Details

diff --git a/HyperGraphModel/Theorem.cs b/HyperGraphModel/Theorem.cs
index 1aa0a7f..b94bf2a 100644
--- a/HyperGraphModel/Theorem.cs
+++ b/HyperGraphModel/Theorem.cs
@@ -14,7 +14,7 @@ namespace HyperGraphModel
             //  Удовлетворяет ли гиперграф теореме
             public bool isSatisfyTheorem;
             //  Число автоморфизмов
-            public Int64 CountAutomorphism;
+            public long CountAutomorphism;
             //  Список общих вершин
             public List<string> AutomorphismNodes;
             //  Гипер-граф, содержащий гипер-ребра без общих вершин
@@ -23,6 +23,17 @@ namespace HyperGraphModel
 
         public static TheoremAuto TheoremAutomorphism(HyperGraph Graph)
         {
+            if (Theorem.isEqualNumberOfVertices(Graph))
+            {
+                return new TheoremAuto
+                {
+                    isSatisfyTheorem = false,
+                    CountAutomorphism = 0,
+                    AutomorphismNodes = null,
+                    GraphWithoutAutoEdges = null
+                };
+            }
+
             //  Копирую гипер-граф, чтобы не изменять исходный
             HyperGraph graph = new HyperGraph(Graph);
             //  Число автоморфизмов
@@ -66,6 +77,17 @@ namespace HyperGraphModel
 
         public static TheoremAuto TheoremAutomorphismForEqualNumberOfVertices(HyperGraph Graph)
         {
+            if (!Theorem.isEqualNumberOfVertices(Graph))
+            {
+                return new TheoremAuto
+                {
+                    isSatisfyTheorem = false,
+                    CountAutomorphism = 0,
+                    AutomorphismNodes = null,
+                    GraphWithoutAutoEdges = null
+                };
+            }
+
             //  Копирую гипер-граф, чтобы не изменять исходный
             HyperGraph graph = new HyperGraph(Graph);
             //  Число автоморфизмов
diff --git a/WPF/Common/WPF/Dictionary.xaml b/WPF/Common/WPF/Dictionary.xaml
index 9f8b794..9eba151 100644
--- a/WPF/Common/WPF/Dictionary.xaml
+++ b/WPF/Common/WPF/Dictionary.xaml
@@ -27,6 +27,7 @@
         <ResourceDictionary Source="Style/ScrollBarStyle.xaml" />
         <ResourceDictionary Source="Style/ComboBoxStyle.xaml" />
 
+        <ResourceDictionary Source="Icons/Check.xaml" />
         <ResourceDictionary Source="Icons/Copy.xaml" />
         <ResourceDictionary Source="Icons/Delete.xaml" />
         <ResourceDictionary Source="Icons/Read.xaml" />
diff --git a/WPF/Common/WPF/Icons/Check.xaml b/WPF/Common/WPF/Icons/Check.xaml
new file mode 100644
index 0000000..93f5388
--- /dev/null
+++ b/WPF/Common/WPF/Icons/Check.xaml
@@ -0,0 +1,19 @@
+<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
+
+    <Geometry x:Key="CheckOK_Geom">M9,20.42L2.79,14.21L5.62,11.38L9,14.77L18.88,4.88L21.71,7.71L9,20.42Z</Geometry>
+    <Geometry x:Key="CheckNO_Geom">M20 6.91L17.09 4L12 9.09L6.91 4L4 6.91L9.09 12L4 17.09L6.91 20L12 14.91L17.09 20L20 17.09L14.91 12L20 6.91Z</Geometry>
+
+    <Viewbox x:Key="CheckOK" Width="24" Height="24">
+        <Canvas Width="24" Height="24">
+            <Path Data="{DynamicResource CheckOK_Geom}" Fill="Black" />
+        </Canvas>
+    </Viewbox>
+
+    <Viewbox x:Key="CheckNO" Width="24" Height="24">
+        <Canvas Width="24" Height="24">
+            <Path Data="{DynamicResource CheckNO_Geom}" Fill="Black" />
+        </Canvas>
+    </Viewbox>
+    
+</ResourceDictionary>
\ No newline at end of file

WPF/Model/Calculate.cs 350(+350 -0)

diff --git a/WPF/Model/Calculate.cs b/WPF/Model/Calculate.cs
new file mode 100644
index 0000000..dc9ae1b
--- /dev/null
+++ b/WPF/Model/Calculate.cs
@@ -0,0 +1,350 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using HyperGraphModel;
+using TheoremAuto = HyperGraphModel.Theorem.TheoremAuto;
+
+namespace WPF.Model
+{
+    public static class Calculate
+    {
+        public static HyperGraph Graph { get; private set; } = new HyperGraph(new Matrix<int>());
+
+        public static void CreateGraph(int Edges, int SameVert, List<int> Verticies)
+        {
+            var vert = Verticies.Sum(x => x - SameVert) + SameVert;
+            var matrix = new Matrix<int>(vert, Edges);
+
+            //  заполнение ребер отдельными вершинами
+            for (int j = 0, i = 0; j < Verticies.Count; j++)
+            {
+                int k = 0;
+                while (Verticies[j] - SameVert > k)
+                {
+                    matrix[i++, j] = 1;
+                    k++;
+                }
+            }
+            //  заполнение ребер общими вершинами
+            for (int i = vert - SameVert; i < vert; i++)
+                for (int j = 0; j < matrix.countColumn; j++)
+                    matrix[i, j] = 1;
+
+            Graph = new HyperGraph(matrix);
+        }
+
+        public static TheoremAuto TheoremSecond()
+        {
+            try
+            {
+                if (Graph == null)
+                    throw new Exception("Гипер граф не существует");
+
+                var result = Theorem.TheoremAutomorphism(Graph);
+                ExampleTheorema(Graph, output);
+
+                return result;
+            }
+            catch (Exception e)
+            {
+                return new TheoremAuto
+                {
+                    AutomorphismNodes = null,
+                    isSatisfyTheorem = false,
+                    CountAutomorphism = 0,
+                    GraphWithoutAutoEdges = null
+                };
+            }
+        }
+
+        public static TheoremAuto TheoremThird()
+        {
+            try
+            {
+                if (Graph == null)
+                    throw new Exception("Гипер граф не существует");
+
+                var result = Theorem.TheoremAutomorphismForEqualNumberOfVertices(Graph);
+                ExampleTheoremaThird(Graph, output);
+
+                return result;
+            }
+            catch (Exception e)
+            {
+                return new TheoremAuto
+                {
+                    AutomorphismNodes = null,
+                    isSatisfyTheorem = false,
+                    CountAutomorphism = 0,
+                    GraphWithoutAutoEdges = null
+                };
+            }
+        }
+
+        #region Private методы
+
+        //  Все перестановки графа вывести в файл
+        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("Текущее ребро включает вершины:");
+                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
+            output.WriteLine("Согласно теореме 2: " + result.isSatisfyTheorem);
+            //  Если да, то вывести
+            if (result.isSatisfyTheorem)
+            {
+                //  Вывод вершин и числа автоморфизмов в файл
+                output.WriteLine("Общие вершины автоморфизмов: ");
+                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\nКоличество автоморфизмов: " + result.CountAutomorphism + "\r\n");
+
+                //  Вывести перестановки в файл
+                ExampleAllTranspos(result.GraphWithoutAutoEdges, output);
+            }
+            //  Уничтожить временный граф
+            result.GraphWithoutAutoEdges.Dispose();
+        }
+
+        static void ExampleTheoremaThird(HyperGraph Graph, System.IO.StreamWriter output)
+        {
+            //  Подсчет количества и получение гипер-графа без общих вершин
+            var result = Theorem.TheoremAutomorphismForEqualNumberOfVertices(Graph);
+
+            //  Выполняется ли условие согласно теореме 3
+            output.WriteLine("Согласно теореме 3: " + result.isSatisfyTheorem);
+            //  Если да, то вывести
+            if (result.isSatisfyTheorem)
+            {
+                //  Вывод вершин и числа автоморфизмов в файл
+                output.WriteLine("Общие вершины автоморфизмов: ");
+                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\nКоличество автоморфизмов: " + result.CountAutomorphism + "\r\n");
+
+                //  Получаю гипер-граф, автоморфизмы которого нужно получить
+                //  Это гипер-граф, из которого удалены общие для всех ребер вершины
+                HyperGraph graph = new HyperGraph(result.GraphWithoutAutoEdges);
+
+                //  Список со всеми автоморфизмами
+                List<string> automorphism = new List<string>();
+
+                //  Трехмерный список, содержащий для каждого ребра (aka 'список ребер') список всех возможных транспозиций (aka перестановки, число которых n!) всех вершин данного ребра (а вершины также заключены в список)
+                //  т.е. обращение comboVertInEdges[0] - список всех возможных перестановок 0-ого гипер-ребра графа
+                //  comboVertInEdges[0][1] - список вершин, входящих в 2-ю (по очередности с 0) перестановку вершин 0-ого ребра
+                //  comboVertInEdges[4] - список всех возможных перестановок 4-ого гипер-ребра графа....
+                //  Этот список заполняется один раз сразу для всех ребер, т.к. содержимое ребер (вершин) неизменно
+                List<List<List<string>>> comboVertInEdges = new List<List<List<string>>>();
+
+                //  Двумерный список - список всех возможных перестановок n-ого ребра
+                List<List<string>> vertInEdge;
+
+                //  Количество перестановок n-ого ребра, одинаково для всех ребер (т.к. мощность каждого ребра равна)
+                int size = 0;
+
+                //  Перебор всех ребер гипер-графа для заполнения трехмерного списка
+                for (int i = 0; i < graph.HyperEdge.Count; i++)
+                {
+                    //  Получаем текущую перестановку
+                    vertInEdge = Combinatorics<string>.Transposition(graph.HyperEdge[i]);
+                    //  Добавляем 0-ю перестановку, которую не учитывает алгоритм
+                    vertInEdge.Insert(0, graph.HyperEdge[i]);
+                    //  Помещаем все перестановки ребра в общий список
+                    comboVertInEdges.Add(vertInEdge);
+                    //  Запоминаем значение на будущее
+                    size = vertInEdge.Count;
+                }
+
+                //  Получив все перестановки каждого из ребер, нужно сформировать автоморфизмы гипер-графа
+                //  Учитывая порядок ребер 0,1,2,3,...,n (где n - количество ребер) и то, что для каждого ребра существует X перестановок
+                //  существует X^n комбинаций перестановок гипер-графа
+                //  
+                //  Если два ребра по 3 вершины, то количество перестановок = 3!= 6 и есть 6*6 комбинаций этих перестановок
+                //  Если 3 ребра по 8 вершин, то количество перестановок = 8! и есть 8! * 8! * 8! = (8!)^3 комбинаций этих перестановок
+                //
+                //  В качестве аргументов передаются n='количество комбинаций' и m='количество ребер'
+                //  Результат - двумерный список, где каждый список содержит последовательность вида
+                //  0 0 0 (для трех ребер), что предполагает комбинацию 0-х перестановок каждого ребра
+                //  0 0 1 - комбинация 0-й перестановки 0-ого и 1-ого ребра И 1-й перестановки 2-ого ребра
+                //  0 0 2 - комбинация 0-й перестановки 0-ого и 1-ого ребра И 2-й перестановки 2-ого ребра
+                //  0 1 0 - комбинация 0-й перестановки 0-ого ребра; 1-й перестановки 1-ого ребра; 0-й перестановки 2-ого ребра
+                //  ...
+                var combination = Combinatorics<int>.combinationWithReplays(size, graph.HyperEdge.Count);
+
+
+                //  Однако, выше приведенные комбинации работают лишь с перестановками непосредственно вершин, сохраняя позиции ребер
+                //  Порядок (1-е ребро)-(2-е ребро)-(3-е ребро) остается неизменным. Меняется лишь 'порядок' внутри ребер
+                //  Чтобы добавить движение в плоскости ребер, нужно найти все возможные перестановки (без повторений) ребер
+                //  И применить это условие к выше приведенным результатам
+
+                //  Подготовка массива для создания перестановок ребер
+                List<int> tmp = new List<int>();
+                for (int i = 0; i < graph.HyperEdge.Count; i++)
+                    tmp.Add(i);
+
+                //  Список перестановок ребер
+                //  Вида:
+                //  0 1 2 (для трех ребер)
+                //  0 2 1
+                //  1 0 2
+                //  1 2 0
+                //  2 0 1
+                //  2 1 0 = 3! = 6 штук              
+                var comboEdges = Combinatorics<int>.Transposition(tmp);
+                comboEdges.Insert(0, tmp);
+
+                //  т.е. сначала мы выбираем комбинации перестановок вершин ребра, учитывая 0-ю перестановку ребер
+                //  потом выбираем комбинации перестановок вершин ребра, учитывая 1-ю перестановку ребер
+                //  то же самое, учитывая 2-ю перестановку ребер
+
+                List<string> edge;  //  Одно конкретное ребро из графа
+                string fullString = "", edgeString; //  Строковые представления
+
+                //  Перебор всех перестановок последовательностей ребер
+                for (int k = 0; k < comboEdges.Count; k++)
+                {
+                    //  Для k-й перестановки ребер перебираем все возможные комбинации перестановок вершин
+                    for (int i = 0; i < combination.Count; i++)
+                    {
+                        //  Строковое представление одного автоморфизма
+                        fullString = "";
+                        //  Для k-й перестановки ребер и для i-й комбинации перестановок вершин
+                        //  Должны перебрать все гипер-ребра
+                        for (int j = 0; j < combination[i].Count; j++)
+                        {
+                            //  Строковое представление одного гипер-ребра
+                            edgeString = "(";
+
+                            //  edge - это упорядоченный список вершин определенной перестановки определенного гипер-ребра
+                            //  comboVertInEdges - трехмерный список, где первые [] отвечают за номер гипер-ребра
+                            //  аргумент [ comboEdges[k][j] ] говорит, что нужно получить j-й номер гипер-ребра из k-й перестановки гипер-ребер
+                            //  т.е. итератор j осуществляет обработку всех гипер-ребер конкретного автоморфизма, 
+                            //     а итератор k указывает, в какой последовательности нужно перебирать гипер-ребра (0-1-2 или 0-2-1 или 2-0-1 или ...)
+                            //  
+                            //  аргумент [ combination[i][j] ] говорит, что при обращении к определенному гипер-ребру нужно получить номер некоторой из возможных комбинаций вершин данного гипер-ребра
+                            //  где итератор i отвечает за номер комбинации (от 0 до (8!)^3, если 3 ребра по 8 вершин)
+                            //    а итератор j отвечает за номер перестановки данного гипер-ребра (от 0 до мощности ребер)
+                            edge = comboVertInEdges[comboEdges[k][j]][combination[i][j]];
+
+                            //  Получив конкретное гипер-ребро, перебираем его вершины
+                            foreach (var vert in edge)
+                                edgeString += vert + '-';   //  Записываем в строку
+                                                            //  Добавляем в общую строку данного автоморфизма
+                            fullString += edgeString.Remove(edgeString.Length - 1, 1) + ") ";
+                        }
+                        //  Записываем строковый вид автоморфизма в общий список
+                        automorphism.Add(fullString);
+                    }
+                }
+
+                //  Вывод
+                for (int i = 0; i < automorphism.Count; i++)
+                    output.WriteLine(i + 1 + ") : " + automorphism[i]);
+            }
+        }
+
+        #endregion
+
+    }
+}
diff --git a/WPF/Model/EnumTheorem.cs b/WPF/Model/EnumTheorem.cs
index c0c8f7c..6f04c4f 100644
--- a/WPF/Model/EnumTheorem.cs
+++ b/WPF/Model/EnumTheorem.cs
@@ -8,9 +8,11 @@ namespace WPF.Model
 {
     public enum EnumTheorem
     {
-        [Description("Первая теорема")]
-        First = 1,
         [Description("Вторая теорема")]
         Second = 2,
+        [Description("Третья теорема")]
+        Third = 3,
+        [Description("Четвертая теорема")]
+        Forth = 4,
     }
 }
diff --git a/WPF/View/MainWindow.xaml b/WPF/View/MainWindow.xaml
index 33330b2..e251923 100644
--- a/WPF/View/MainWindow.xaml
+++ b/WPF/View/MainWindow.xaml
@@ -18,8 +18,8 @@
         AllowsTransparency="True"
         Loaded="Window_Loaded"
         Title="{Binding TitleText}" 
-        Height="450" Width="800"
-        MinHeight="370" MinWidth="630"
+        Height="215" Width="725"
+        MinHeight="215" MinWidth="725"
         BorderBrush="#FF494957"
         BorderThickness="1">
     <Window.Resources>
@@ -39,7 +39,7 @@
             </Setter>
         </Style>
 
-        <Style TargetType="{x:Type xctk:DecimalUpDown}" BasedOn="{StaticResource {x:Type xctk:DecimalUpDown}}">
+        <Style TargetType="{x:Type xctk:UIntegerUpDown}" BasedOn="{StaticResource {x:Type xctk:UIntegerUpDown}}">
             <Setter Property="FontSize" Value="18"/>
             <Setter Property="Width" Value="50"/>
             <Setter Property="Margin" Value="2"/>
@@ -74,7 +74,7 @@
             </StackPanel>
         </Grid>
 
-        <Grid Grid.Row="1" Background="{StaticResource WindowBackground}">
+        <Grid Grid.Row="1" Background="{StaticResource WindowBackground}" Margin="2">
 
             <Grid.RowDefinitions>
                 <RowDefinition Height="Auto"/>
@@ -93,29 +93,29 @@
             <ComboBox Grid.Row="0" Grid.Column="0" Style="{StaticResource ComboBoxStyle}" ItemsSource="{Binding EnumTheorems}" SelectedItem="{Binding SelectedTheorem}" Width="Auto">
                 <ComboBox.ItemTemplate>
                     <DataTemplate>
-                        <TextBlock Text="{Binding Converter={StaticResource EnumToDescriptionConverter}}"/>
+                        <TextBlock Text="{Binding Converter={StaticResource EnumToDescriptionConverter}}" Style="{StaticResource WhiteCaptionTextStyle}"/>
                     </DataTemplate>
                 </ComboBox.ItemTemplate>
             </ComboBox>
 
-            <TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding EdgesText}" Margin="2" Style="{StaticResource WhiteCaptionTextStyle}" ToolTipService.InitialShowDelay="1000">
+            <TextBlock Grid.Row="1" Grid.Column="0" Text="{Binding EdgesText}" Margin="2" Style="{StaticResource WhiteCaptionTextStyle}" ToolTipService.InitialShowDelay="1000">
                 <TextBlock.ToolTip>
                     <TextBlock Text="{Binding EdgesTextTooltip}" Foreground="GhostWhite" Margin="1"/>
                 </TextBlock.ToolTip>
             </TextBlock>
-            <xctk:DecimalUpDown Grid.Row="1" Grid.Column="2" HorizontalAlignment="Left" Value="{Binding EdgesNum}" Minimum="{Binding MinValue}" Maximum="{Binding MaxValue}"/>
+            <xctk:UIntegerUpDown Grid.Row="1" Grid.Column="1" HorizontalAlignment="Left" Value="{Binding EdgesNum}" Minimum="{Binding MinValue}" Maximum="{Binding MaxValue}"/>
 
-            <TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding SameVertText}" Margin="2" Style="{StaticResource WhiteCaptionTextStyle}" ToolTipService.InitialShowDelay="1000">
+            <TextBlock Grid.Row="2" Grid.Column="0" Text="{Binding SameVertText}" Margin="2" Style="{StaticResource WhiteCaptionTextStyle}" ToolTipService.InitialShowDelay="1000">
                 <TextBlock.ToolTip>
                     <TextBlock Text="{Binding SameVertTextTooltip}" Foreground="GhostWhite" Margin="1"/>
                 </TextBlock.ToolTip>
             </TextBlock>
-            <xctk:DecimalUpDown Grid.Row="2" Grid.Column="2" HorizontalAlignment="Left" Value="{Binding SameVertNum}" Minimum="{Binding MinValue}" Maximum="{Binding MaxValue}"/>
+            <xctk:UIntegerUpDown Grid.Row="2" Grid.Column="1" HorizontalAlignment="Left" Value="{Binding SameVertNum}" Minimum="{Binding MinValue}" Maximum="{Binding MaxValue}"/>
 
-            <Grid Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="3" Visibility="{Binding VisibilityVerticies}">
+            <Grid Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="4" Visibility="{Binding VisibilityVerticies}">
                 <Grid.ColumnDefinitions>
                     <ColumnDefinition Width="Auto"/>
-                    <ColumnDefinition Width="*"/>
+                    <ColumnDefinition Width="54*"/>
                 </Grid.ColumnDefinitions>
                 <Grid.RowDefinitions>
                     <RowDefinition Height="Auto"/>
@@ -134,7 +134,7 @@
                     </TextBlock.ToolTip>
                 </TextBlock>
 
-                <ScrollViewer Grid.Row="0" Grid.Column="1" Grid.RowSpan="2" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Hidden">
+                <ScrollViewer Grid.Row="0" Grid.Column="1" Grid.RowSpan="2" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Hidden" MinWidth="540">
                     <ItemsControl ItemsSource="{Binding Verticies}">
                         <ItemsControl.ItemsPanel>
                             <ItemsPanelTemplate>
@@ -143,14 +143,14 @@
                         </ItemsControl.ItemsPanel>
                         <ItemsControl.ItemTemplate>
                             <DataTemplate>
-                                <Grid Margin="0">
+                                <Grid Margin="0" MaxWidth="54">
                                     <Grid.RowDefinitions>
                                         <RowDefinition Height="Auto"/>
                                         <RowDefinition Height="Auto"/>
                                     </Grid.RowDefinitions>
 
                                     <TextBlock Grid.Row="0" Text="{Binding VertText}" Margin="2" Style="{StaticResource WhiteCaptionTextStyle}" HorizontalAlignment="Center"/>
-                                    <xctk:DecimalUpDown Grid.Row="1" Value="{Binding Value}" Minimum="{Binding MinValue}" Maximum="{Binding Source={x:Static viewmodel:MainViewModel.MaxValue}}"/>
+                                    <xctk:UIntegerUpDown Grid.Row="1" Value="{Binding Value}" Minimum="{Binding MinValue}" Maximum="{Binding Source={x:Static viewmodel:MainViewModel.MaxValue}}"/>
 
                                 </Grid>
                             </DataTemplate>
@@ -159,6 +159,65 @@
                 </ScrollViewer>
 
             </Grid>
+
+            <StackPanel Grid.Row="0" Grid.Column="2" Grid.RowSpan="3" Orientation="Vertical" Width="125" Margin="5,0,5,0">
+                <Button Margin="0,0,0,1" Command="{Binding CalculateCommand}">
+                    <TextBlock Text="Выполнить расчет" TextWrapping="WrapWithOverflow" TextAlignment="Center"/>
+                </Button>
+
+                <Button Margin="0,1,0,0" Command="{Binding SaveResultCommand}">
+                    <TextBlock Text="Сохранить перестановки" TextWrapping="WrapWithOverflow" TextAlignment="Center"/>
+                </Button>
+            </StackPanel>
+
+            <Grid Grid.Row="0" Grid.Column="3" Grid.RowSpan="3">
+                <Grid.ColumnDefinitions>
+                    <ColumnDefinition Width="Auto"/>
+                    <ColumnDefinition Width="Auto"/>
+                </Grid.ColumnDefinitions>
+                <Grid.RowDefinitions>
+                    <RowDefinition Height="Auto"/>
+                    <RowDefinition Height="Auto"/>
+                </Grid.RowDefinitions>
+
+                <TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding TheoremOKText}" Margin="2" Style="{StaticResource WhiteCaptionTextStyle}" ToolTipService.InitialShowDelay="1000">
+                    <TextBlock.ToolTip>
+                        <TextBlock Text="{Binding TheoremOKTooltip}" Foreground="GhostWhite" Margin="1"/>
+                    </TextBlock.ToolTip>
+                </TextBlock>
+
+                <Rectangle Grid.Row="0" Grid.Column="1" Height="24" Width="24" Margin="5 0">
+                    <Rectangle.Style>
+                        <Style TargetType="Rectangle">
+                            <Setter Property="OpacityMask">
+                                <Setter.Value>
+                                    <VisualBrush Stretch="Fill" Visual="{StaticResource CheckNO}" />
+                                </Setter.Value>
+                            </Setter>
+                            <Setter Property="Fill" Value="Red"/>
+
+                            <Style.Triggers>
+                                <DataTrigger Binding="{Binding IsTheoremCorrect}" Value="True">
+                                    <Setter Property="OpacityMask">
+                                        <Setter.Value>
+                                            <VisualBrush Stretch="Fill" Visual="{StaticResource CheckOK}" />
+                                        </Setter.Value>
+                                    </Setter>
+                                    <Setter Property="Fill" Value="Green"/>
+                                </DataTrigger>
+                            </Style.Triggers>
+                        </Style>
+                    </Rectangle.Style>
+                </Rectangle>
+
+                <TextBlock Grid.Row="1" Grid.Column="0" Text="{Binding AutomorphismText}" Margin="2" Style="{StaticResource WhiteCaptionTextStyle}" ToolTipService.InitialShowDelay="1000">
+                    <TextBlock.ToolTip>
+                        <TextBlock Text="{Binding AutomorphismTooltip}" Foreground="GhostWhite" Margin="1"/>
+                    </TextBlock.ToolTip>
+                </TextBlock>
+                <TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding AutomorphismCount}" Margin="5 0" VerticalAlignment="Bottom" TextAlignment="Center" FontWeight="Bold" FontSize="18" Foreground="{StaticResource Yellow}" MinWidth="100"/>
+
+            </Grid>
             
             
 
diff --git a/WPF/ViewModel/MainViewModel.cs b/WPF/ViewModel/MainViewModel.cs
index 7f5ec1e..e833ced 100644
--- a/WPF/ViewModel/MainViewModel.cs
+++ b/WPF/ViewModel/MainViewModel.cs
@@ -8,6 +8,8 @@ using System.IO;
 using System.Linq;
 using System.Threading.Tasks;
 using Visibility = System.Windows.Visibility;
+using TheoremAuto = HyperGraphModel.Theorem.TheoremAuto;
+using static WPF.Model.Calculate;
 
 namespace WPF.ViewModel
 {
@@ -15,18 +17,20 @@ namespace WPF.ViewModel
     {
         public MainViewModel() : base()
         {
-            //Items = new ObservableCollection<ItemViewModel>();
-            //System.Windows.Data.BindingOperations.EnableCollectionSynchronization(Items, _lock);
-            //CreatePanel = new CreatingViewModel(this);
-            //IsAllDataHide = true;
-
             Verticies = new ObservableCollection<VertViewModel>();
             EnumTheorems = Enum.GetValues(typeof(EnumTheorem)).Cast<EnumTheorem>().ToList();
             SelectedTheorem = EnumTheorems.First();
+            EdgesNum = 1;
+            SameVertNum = 1;
+            IsTheoremCorrect = false;
+            AutomorphismCount = 0;
+
+            CalculateCommand = new RelayCommand(OnCalculate);
+            SaveResultCommand = new RelayCommand(OnSaveResult);
 
             //AddItemCommand = new RelayCommand<ItemViewModel>(OnAddItem, item => Items.FirstOrDefault(e => e.Value == item.Value) == null);
             //RemoveItemCommand = new RelayCommand<ItemViewModel>(OnRemoveItem, item => !item.Readonly);
-            //OpenFileCommand = new RelayCommand(OnOpenFile);
+
             //SwitchDataVisibleCommand = new RelayCommand(OnSwitchDataVisible);
             //ClearSearchCommand = new RelayCommand(OnClearSearch);
         }
@@ -45,14 +49,13 @@ namespace WPF.ViewModel
             {
                 _selectedTheorem = value;
                 OnPropertyChanged(() => SelectedTheorem);
-                // do smth
             }
 
             get => _selectedTheorem;
         }
 
-        private decimal _edgesNum;
-        public decimal EdgesNum
+        private int _edgesNum;
+        public int EdgesNum
         {
             get => _edgesNum;
             set
@@ -64,8 +67,8 @@ namespace WPF.ViewModel
             }
         }
 
-        private decimal _sameVertNum;
-        public decimal SameVertNum
+        private int _sameVertNum;
+        public int SameVertNum
         {
             get => _sameVertNum;
             set
@@ -87,6 +90,8 @@ namespace WPF.ViewModel
 
         public ObservableCollection<VertViewModel> Verticies { get; }
 
+        public string TitleText { get => "Расчет гиперграфов"; }
+
         public string EdgesText { get => "Количество ребер"; }
         public string EdgesTextTooltip { get => "Подсказка. Количество ребер"; }
 
@@ -98,7 +103,34 @@ namespace WPF.ViewModel
 
         public string VerticiesValueText { get => "Число вершин"; }
         public string VerticiesValueTooltip { get => "Подсказка. Число вершин в каждом ребре"; }
-        public string TitleText { get => "Расчет гиперграфов"; }
+
+        public string TheoremOKText { get => "Удовлетворяет теореме"; }
+        public string TheoremOKTooltip { get => "Подсказка. Удовлетворяет теореме"; }
+
+        public string AutomorphismText { get => "Число автоморфизмов"; }
+        public string AutomorphismTooltip { get => "Подсказка. Число автоморфизмов"; }
+
+        private bool _isTheoremCorrect;
+        public bool IsTheoremCorrect
+        {
+            get => _isTheoremCorrect;
+            set
+            {
+                _isTheoremCorrect = value;
+                OnPropertyChanged(() => IsTheoremCorrect);
+            }
+        }
+
+        private long _automorphismCount;
+        public long AutomorphismCount
+        {
+            get => _automorphismCount;
+            set
+            {
+                _automorphismCount = value;
+                OnPropertyChanged(() => AutomorphismCount);
+            }
+        }
 
         #endregion
 
@@ -123,7 +155,7 @@ namespace WPF.ViewModel
                     Verticies.Clear();
                 else
                 {
-                    var skip = Verticies.Skip((int)EdgesNum).ToList();
+                    var skip = Verticies.Skip(EdgesNum).ToList();
                     foreach (var vert in skip)
                     {
                         Verticies.Remove(vert);
@@ -142,21 +174,55 @@ namespace WPF.ViewModel
             }
         }
 
+
+        public RelayCommand CalculateCommand { get; }
+        private void OnCalculate()
+        {
+            CreateGraph(EdgesNum, SameVertNum, Verticies.Select(x => x.Value).ToList());
+            TheoremAuto result = default;
+            switch (SelectedTheorem)
+            {
+                case EnumTheorem.Second:
+                    {
+                        result = TheoremSecond();
+                        break;
+                    }
+                case EnumTheorem.Third:
+                    {
+                        result = TheoremThird();
+                        break;
+                    }
+                case EnumTheorem.Forth:
+                    {
+
+                        break;
+                    }
+            }
+            IsTheoremCorrect = result.isSatisfyTheorem;
+            AutomorphismCount = result.CountAutomorphism;
+        }
+
+        public RelayCommand SaveResultCommand { get; }
+        private void OnSaveResult()
+        {
+
+        }
+
         #endregion
 
     }
 
     public class VertViewModel : BaseViewModel
     {
-        public VertViewModel(decimal startValue, string text)
+        public VertViewModel(int startValue, string text)
         {
             Value = startValue;
             MinValue = startValue;
             VertText = text;
         }
 
-        private decimal _value;
-        public decimal Value
+        private int _value;
+        public int Value
         {
             get => _value;
             set
@@ -166,8 +232,8 @@ namespace WPF.ViewModel
             }
         }
 
-        private decimal _minValue;
-        public decimal MinValue
+        private int _minValue;
+        public int MinValue
         {
             get => _minValue;
             set

WPF/WPF.csproj 5(+5 -0)

diff --git a/WPF/WPF.csproj b/WPF/WPF.csproj
index b112602..ac80020 100644
--- a/WPF/WPF.csproj
+++ b/WPF/WPF.csproj
@@ -96,6 +96,10 @@
       <Generator>MSBuild:Compile</Generator>
       <SubType>Designer</SubType>
     </Page>
+    <Page Include="Common\WPF\Icons\Check.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
     <Page Include="Common\WPF\Icons\Copy.xaml">
       <Generator>MSBuild:Compile</Generator>
       <SubType>Designer</SubType>
@@ -275,6 +279,7 @@
     <Compile Include="Common\WPF\NotifyPropertyChangedHelper.cs" />
     <Compile Include="Common\WPF\ObservableCollectionAdv.cs" />
     <Compile Include="Common\WPF\RelayCommand.cs" />
+    <Compile Include="Model\Calculate.cs" />
     <Compile Include="Model\EnumTheorem.cs" />
     <Compile Include="ViewModel\MainViewModel.cs" />
     <Compile Include="View\MainWindow.xaml.cs">