HyperGraph
Changes
HyperGraph/HyperGraph.cs 36(+36 -0)
HyperGraph/HyperGraph.csproj 1(+1 -0)
HyperGraph/Matrix.cs 2(+1 -1)
HyperGraph/Program.cs 61(+54 -7)
HyperGraph/Theorem.cs 96(+96 -0)
Details
HyperGraph/HyperGraph.cs 36(+36 -0)
diff --git a/HyperGraph/HyperGraph.cs b/HyperGraph/HyperGraph.cs
index 43e9a94..7b8f552 100644
--- a/HyperGraph/HyperGraph.cs
+++ b/HyperGraph/HyperGraph.cs
@@ -26,5 +26,41 @@ namespace HyperGraph
}
}
}
+
+ // Конструктор копирования
+ public HyperGraph(HyperGraph graph)
+ {
+ HyperEdge = new List<List<string>>();
+
+ foreach (var edge in graph.HyperEdge)
+ {
+ HyperEdge.Add(new List<string>());
+ foreach (var elem in edge)
+ HyperEdge.Last().Add(elem);
+ }
+ Console.WriteLine();
+ }
+
+ // При уничтожении
+ ~HyperGraph()
+ {
+ this.Dispose();
+ }
+
+ // Очистка памяти
+ public void Dispose()
+ {
+ if (HyperEdge != null)
+ {
+ for (int i = 0; i < HyperEdge.Count; i++)
+ HyperEdge[i] = null;
+ HyperEdge = null;
+ }
+ // Так делать не хорошо.
+ // Принудительный вызов сборщика мусора после удаления ссылок на списки данных.
+ // Очистит теперь неиспользуемую память.
+ GC.Collect();
+ GC.WaitForPendingFinalizers();
+ }
}
}
HyperGraph/HyperGraph.csproj 1(+1 -0)
diff --git a/HyperGraph/HyperGraph.csproj b/HyperGraph/HyperGraph.csproj
index 37d2194..670d2f4 100644
--- a/HyperGraph/HyperGraph.csproj
+++ b/HyperGraph/HyperGraph.csproj
@@ -46,6 +46,7 @@
<Compile Include="Matrix.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Theorem.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
HyperGraph/Matrix.cs 2(+1 -1)
diff --git a/HyperGraph/Matrix.cs b/HyperGraph/Matrix.cs
index 51065fa..34fd42d 100644
--- a/HyperGraph/Matrix.cs
+++ b/HyperGraph/Matrix.cs
@@ -186,7 +186,7 @@ namespace HyperGraph
{
string temp = r0w.Split(' ')[j];
T tmp = ConvertValue<T,string>(temp);
- matrix.matrix[i][j] = tmp;
+ matrix[i,j] = tmp;
}
}
}
HyperGraph/Program.cs 61(+54 -7)
diff --git a/HyperGraph/Program.cs b/HyperGraph/Program.cs
index 0118ca8..93a2467 100644
--- a/HyperGraph/Program.cs
+++ b/HyperGraph/Program.cs
@@ -17,15 +17,46 @@ namespace HyperGraph
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
+ */
+
static void Main(string[] args)
- {
+ {
+ Matrix<int> u = new Matrix<int>(4);
+
System.IO.StreamReader input = new System.IO.StreamReader("D:\\input.txt");
System.IO.StreamWriter output = new System.IO.StreamWriter("D:\\output.txt");
// Экземпляр гипер-графа, созданный на основе загружаемой матрицы инцидентности
- // 6 - кол-во строк, 7 - кол-во столбцов
- HyperGraph graph = new HyperGraph(Matrix<int>.LoadFromStream(input, 6, 7));
+ // 11 - кол-во строк, 3 - кол-во столбцов
+ HyperGraph graph = new HyperGraph(Matrix<int>.LoadFromStream(input, 11, 3));
+
+
+ // Все перестановки гипер-графа
+ //ExampleAllTranspos(graph, input, output);
+ // Вычислить количество автоморфизмов графа и вывести перестановки
+ ExampleTheorema(graph, output);
+
+ input.Close(); output.Close();
+ Console.WriteLine("Completed. Press any key");
+ Console.ReadKey();
+ }
+
+ // Все перестановки графа вывести в файл
+ static void ExampleAllTranspos(HyperGraph graph, System.IO.StreamWriter output)
+ {
// Массив (лист) всех возможных перестановок одного множества (гипер-ребра)
List<List<string>> transpos;
@@ -51,17 +82,33 @@ namespace HyperGraph
// Алгоритм перестановок не учитывает начальную, а начинает со следующей
for (int g = 0; g < transpos.Count; g++)
{
- output.Write("{0}: ", g+2);
+ output.Write("{0}: ", g + 2);
for (int f = 0; f < transpos[g].Count; f++)
output.Write("{0} ", transpos[g][f]);
output.WriteLine("\n\t-----------");
}
output.WriteLine();
}
+ }
- input.Close(); output.Close();
- Console.WriteLine("Completed. Press any key");
- Console.ReadKey();
+ // Найти общие вершины для всех гипер-ребер, подсчитать количество автоморфизмов гипер-графа и вывести все перестановки оставшихся ребер
+ static void ExampleTheorema(HyperGraph graph, System.IO.StreamWriter output)
+ {
+ // Получить результат вычислений
+ var result = Theorem.TheoremAutomorphism(graph);
+ // Вывод числа автоморфизмов в консоль
+ Console.WriteLine("Count of automorphism: " + result.CountAutomorphism);
+
+ // Вывод вершин и числа автоморфизмов в файл
+ output.Write("Automorphism with nodes: ");
+ foreach (var node in result.AutomorphismNodes)
+ output.Write(node + " ");
+ output.WriteLine("\nCount of automorphism: " + result.CountAutomorphism + "\n");
+
+ // Вывести перестановки в файл
+ ExampleAllTranspos(result.GraphWithoutAutoEdges, output);
+ // Уничтожить временный граф
+ result.GraphWithoutAutoEdges.Dispose();
}
}
}
HyperGraph/Theorem.cs 96(+96 -0)
diff --git a/HyperGraph/Theorem.cs b/HyperGraph/Theorem.cs
new file mode 100644
index 0000000..af311a6
--- /dev/null
+++ b/HyperGraph/Theorem.cs
@@ -0,0 +1,96 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace HyperGraph
+{
+ class Theorem
+ {
+ // Структура для результурующих данных
+ public struct TheoremAuto
+ {
+ // Число автоморфизмов
+ public Int64 CountAutomorphism;
+ // Список общих вершин
+ public List<string> AutomorphismNodes;
+ // Гипер-граф, содержащий гипер-ребра без общих вершин
+ public HyperGraph GraphWithoutAutoEdges;
+ }
+
+ public static TheoremAuto TheoremAutomorphism(HyperGraph Graph)
+ {
+ // Копирую гипер-граф, чтобы не изменять исходный
+ HyperGraph graph = new HyperGraph(Graph);
+ // Число автоморфизмов
+ Int64 count;
+
+ // Список вершин 0-ого гипер-ребра
+ List<string> intersect = new List<string>(graph.HyperEdge[0]);
+
+ // Находим пересечение множеств вершин гипер-ребер каждого с каждым
+ for (int i = 1; i < graph.HyperEdge.Count; i++)
+ {
+ var res = intersect.Select(j => j.ToString()).Intersect(graph.HyperEdge[i]);
+ // Сохраняем резудьтат пересечения для дальнейшей операции
+ intersect = new List<string>();
+ foreach (var item in res)
+ intersect.Add(item);
+ }
+ // В списке intersect расположены общие для всех гипер-ребер вершины
+
+ // Удаляем из каждого гипер-ребра все общие вершины
+ foreach (var edge in graph.HyperEdge)
+ foreach (var elem in intersect)
+ edge.RemoveAll(s => s.Equals(elem));
+
+ // Согласно формуле, подсчитываем количество автоморфизмов
+ count = Factorial(intersect.Count); // !k, где k = количество общих вершин
+ foreach (var edge in graph.HyperEdge)
+ count *= Factorial(edge.Count); // *(n - k)!, где n = количество вершин в исходном гипер-ребер,
+ // а (n-k) = количество вершин в новом гипер-графе без общих вершин
+
+ // Вовращаемое значение в виде структуры
+ return new TheoremAuto
+ {
+ CountAutomorphism = count,
+ AutomorphismNodes = intersect,
+ GraphWithoutAutoEdges = graph
+ };
+ }
+
+
+ private static Int64 Factorial(int input)
+ {
+ // Предрассчитанные значения
+ switch (input)
+ {
+ case 1: return 1;
+ case 2: return 2;
+ case 3: return 6;
+ case 4: return 24;
+ case 5: return 120;
+ case 6: return 720;
+ case 7: return 5040;
+ default:
+ break;
+ }
+ int x;
+ Int64 fact = 1;
+ try
+ {
+ // Вдруг выйдем за пределы максимального значения
+ for (x = input; x > 1; x--)
+ fact *= x;
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("\n" + e.Message);
+ Console.ReadKey();
+ return -1;
+ }
+ return fact;
+ }
+ }
+}
\ No newline at end of file