<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Full</id>
	<title>Алговики - Вклад [ru]</title>
	<link rel="self" type="application/atom+xml" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Full"/>
	<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/ru/%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/Full"/>
	<updated>2026-10-22T23:28:03Z</updated>
	<subtitle>Вклад</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25087</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25087"/>
		<updated>2017-12-12T18:10:36Z</updated>

		<summary type="html">&lt;p&gt;Full: /* Ресурс параллелизма алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&amp;lt;br&amp;gt;&lt;br /&gt;
Автор статьи: Ефремов С.С. (группа 419)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром алгоритма является последовательность множеств  &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;. Вычисляется на основе соответствующих &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt;. Построение &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt; занимает несущественную часть времени.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Каждое множество &amp;lt;math&amp;gt; M_i (i = 2 \ldots n) &amp;lt;/math&amp;gt; вычисляется из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; путем добавления в каждый элемент (частичная перестановка, представленная вектором целых чисел) из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; всех возможных оставшихся чисел, которых нет в соответствующем элементе.&lt;br /&gt;
&lt;br /&gt;
Для этого удобно использовать 2 не фиксированных по количеству строк двумерных массива размера t на n (t может увеличиваться), хранящих частичные отображения, такого вида: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
a_{11} &amp;amp; a_{12} &amp;amp; \ldots &amp;amp;a_{1i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
a_{21} &amp;amp; a_{22} &amp;amp; \ldots &amp;amp;a_{2i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
a_{k1} &amp;amp; a_{k2} &amp;amp; \ldots &amp;amp;a_{ki} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
? - эти значения не известны и заполняются постепенно.&lt;br /&gt;
&lt;br /&gt;
Один массив для &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt;, другой для вычисления из предыдущего &amp;lt;math&amp;gt; M_i &amp;lt;/math&amp;gt;.&lt;br /&gt;
Из каждой строки множества &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; (первый массив), в соответствие с алгоритмом, получается &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; новых строк длины i, которые записываются во второй массив (расширяется, если нужно).&lt;br /&gt;
&lt;br /&gt;
После этого, второй массив копируется в первый и запускается цикл по всем векторам. Вектор исключается из массива, если &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; равен какому-либо числу в данном векторе или вектор с &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; является частичной перестановкой, не удовлетворяющей критерию;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Схема реализации представлена на языке C++&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#define GRAPH_SIZE 300&lt;br /&gt;
#define ROW_ARR_SIZE 10000 &lt;br /&gt;
#define COL_ARR_SIZE GRAPH_SIZE&lt;br /&gt;
&lt;br /&gt;
const int N = GRAPH_SIZE;&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; Mi(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; M&#039;i(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
unsigned char **matrix;&lt;br /&gt;
&lt;br /&gt;
struct_M&#039;i make_M&#039;i(Mi) {&lt;br /&gt;
    struct_M&#039;i M&#039;i;&lt;br /&gt;
    for (auto x: Mi) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
            if (check_h(x) &amp;amp;&amp;amp; !eq(x, i)) {&lt;br /&gt;
                M&#039;i.push_back(x.add(i));&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return M&#039;i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct_Mi make_Mi(M&#039;i) {&lt;br /&gt;
    struct_Mi Mi;&lt;br /&gt;
    for (auto x: M&#039;i) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
           Mi.push_back(x.add(i));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return Mi;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    //заполнение матрицы смежности&lt;br /&gt;
    init_automorphisms(matrix);&lt;br /&gt;
&lt;br /&gt;
    //распараллеливание&lt;br /&gt;
    switch(process) {&lt;br /&gt;
    case 0:&lt;br /&gt;
        begin = 0;&lt;br /&gt;
        end = stop_0;&lt;br /&gt;
    case 1:&lt;br /&gt;
        begin = start_1;&lt;br /&gt;
        end = stop_1;&lt;br /&gt;
    ...&lt;br /&gt;
    case N:&lt;br /&gt;
        begin = start_n;&lt;br /&gt;
        end = M_0.size();&lt;br /&gt;
&lt;br /&gt;
    //основной цикл&lt;br /&gt;
    for (i = begin; i &amp;lt; end; ++i) {&lt;br /&gt;
        Mi = make_Mi(M&#039;i-1);&lt;br /&gt;
        M&#039;i = make_M&#039;i(Mi);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //сохранение результата (вывод автоморфизмов)&lt;br /&gt;
    final_automorphism(M&#039;i);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Сложность всего алгоритма представляет собой сумму сложностей вычисления &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Количество элементов в каждом множестве (с вероятностью близкой к единице):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |M&#039;_{k}| \thickapprox \frac{n!}{(n-k-2)!~2^{(k)^2}} \thickapprox \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Можно оценить: &amp;lt;math&amp;gt; |M&#039;_k| = \frac{n(n-1)\ldots(n-k-1)}{2^{(k)^2}} \le \frac{n^{k}}{2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Количество операций сравнения для подсчета всех множеств:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \sum_{k = 1}^{n} \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} \times (n - k)(2k + 1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оценка (были учтены точка стабилизации и точка максимума последовательности множеств):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; n \times \frac{n^{(5/7) \ln(n)}}{2^{((5/7)\ln(n))^2}}\times n(2(\frac{5}{7}\ln(n)) + 1)\times \log_2(n) = O(n^2(\frac{e}{2})^{\ln(n)^2} \ln(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сложность экспоненциальная.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[глоссарий#Граф алгоритма|Граф алгоритма]]&amp;lt;ref&amp;gt;Воеводин В.В.  Математические основы параллельных вычислений// М.: Изд. Моск. ун-та, 1991. 345 с.&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Воеводин В.В., Воеводин Вл.В. Параллельные вычисления. – СПб.: БХВ - Петербург, 2002. – 608 с.&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Фролов А.В.. Принципы построения и описание языка Сигма. Препринт ОВМ АН N 236. М.: ОВМ АН СССР, 1989.&amp;lt;/ref&amp;gt; для &amp;lt;math&amp;gt;n = 4&amp;lt;/math&amp;gt; (при росте &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; изменения графа будут аналогичны, а отклонения не существенны:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:Граф_автоморфизмов.png|thumb|center|1100px|Рисунок 1. Граф алгоритма. CHECK - проверка по критерию.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
При больших &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; ширина ярусов будет расти до яруса под номером &amp;lt;math&amp;gt;\lceil\frac{5}{7}\log_2(n) - 1\rceil&amp;lt;/math&amp;gt;, после начнет убывать.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для поиска автоморфизмов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; итерационным алгоритмом в параллельном варианте требуется выполнить:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; ярусов сравнений (количество сравнений &amp;lt;math&amp;gt; k = 1 \ldots n: \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} \times (n - k)(2k + 1) &amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте ЯПФ, таким образом, алгоритм имеет сложность &amp;lt;math&amp;gt; O(n) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
При классификации по ширине ЯПФ его сложность &amp;lt;math&amp;gt; O(n(\frac{e}{2})^{\ln(n)^2} \ln(n))) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;) графа .&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; – любые, но в данной статье рассматриваются из множества {0,1}.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;, представленное матрицей (элементы &amp;lt;math&amp;gt;g^s_n&amp;lt;/math&amp;gt; - полученные автоморфизмы).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;l \times n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt; количество всевозможных автоморфизмов для данного графа.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых параметров запуска реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [4 : 128] с шагом &amp;lt;math&amp;gt; 2^n&amp;lt;/math&amp;gt; (точки отображены с шагом 4, усреднив результаты);&lt;br /&gt;
*	размер матрицы [300 : 1000].&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон алгоритма:&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 17,44%;&lt;br /&gt;
*	максимальная эффективность реализации 88,73%.&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики производительности и эффективности выбранной реализации поиска автоморфизмов графов в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:График_производительности_поиска_автоморфизмов.jpg|thumb|center|700px|Рисунок 2. Параллельная реализация алгоритма поиска автоморфизмов. Изменение производительности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
[[file:График_эффективности.jpg|thumb|center|700px|Рисунок 3. Параллельная реализация алгоритма поиска автоморфизмов. Изменение эффективности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
&lt;br /&gt;
Оценки масштабируемости выбранной реализации:&lt;br /&gt;
*	По числу процессов: -0,00837.&lt;br /&gt;
*	По размеру задачи: 0,04612. &lt;br /&gt;
*	По двум направлениям: 0,00253.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Информация о реализациях данного алгоритма не найдена. При анализе алгоритма было разработано 2 программы: &amp;lt;br/&amp;gt; &lt;br /&gt;
&lt;br /&gt;
:1) приложение с графическим интерфейсом, написанное на &#039;&#039;&#039;Qt&#039;&#039;&#039;&lt;br /&gt;
:::* не поддерживает распараллеливание&lt;br /&gt;
:::* справляется с графами размера до 500 вершин&lt;br /&gt;
:::* удобный анализ графов&lt;br /&gt;
:::* помимо нахождения автоморфизмов, решает задачи изоморфизма и гомоморфизма графов&lt;br /&gt;
:2) программа на языки &#039;&#039;&#039;C++&#039;&#039;&#039; с поддержкой &#039;&#039;&#039;OpenMPI&#039;&#039;&#039;&lt;br /&gt;
:::* поддерживает распараллеливание средствами OpenMPI&lt;br /&gt;
:::* помимо нахождения автоморфизмов, сохраняет много информации для анализа графов с большим количеством вершин&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25078</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25078"/>
		<updated>2017-12-10T20:54:17Z</updated>

		<summary type="html">&lt;p&gt;Full: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&amp;lt;br&amp;gt;&lt;br /&gt;
Автор статьи: Ефремов С.С. (группа 419)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром алгоритма является последовательность множеств  &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;. Вычисляется на основе соответствующих &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt;. Построение &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt; занимает несущественную часть времени.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Каждое множество &amp;lt;math&amp;gt; M_i (i = 2 \ldots n) &amp;lt;/math&amp;gt; вычисляется из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; путем добавления в каждый элемент (частичная перестановка, представленная вектором целых чисел) из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; всех возможных оставшихся чисел, которых нет в соответствующем элементе.&lt;br /&gt;
&lt;br /&gt;
Для этого удобно использовать 2 не фиксированных по количеству строк двумерных массива размера t на n (t может увеличиваться), хранящих частичные отображения, такого вида: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
a_{11} &amp;amp; a_{12} &amp;amp; \ldots &amp;amp;a_{1i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
a_{21} &amp;amp; a_{22} &amp;amp; \ldots &amp;amp;a_{2i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
a_{k1} &amp;amp; a_{k2} &amp;amp; \ldots &amp;amp;a_{ki} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
? - эти значения не известны и заполняются постепенно.&lt;br /&gt;
&lt;br /&gt;
Один массив для &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt;, другой для вычисления из предыдущего &amp;lt;math&amp;gt; M_i &amp;lt;/math&amp;gt;.&lt;br /&gt;
Из каждой строки множества &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; (первый массив), в соответствие с алгоритмом, получается &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; новых строк длины i, которые записываются во второй массив (расширяется, если нужно).&lt;br /&gt;
&lt;br /&gt;
После этого, второй массив копируется в первый и запускается цикл по всем векторам. Вектор исключается из массива, если &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; равен какому-либо числу в данном векторе или вектор с &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; является частичной перестановкой, не удовлетворяющей критерию;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Схема реализации представлена на языке C++&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#define GRAPH_SIZE 300&lt;br /&gt;
#define ROW_ARR_SIZE 10000 &lt;br /&gt;
#define COL_ARR_SIZE GRAPH_SIZE&lt;br /&gt;
&lt;br /&gt;
const int N = GRAPH_SIZE;&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; Mi(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; M&#039;i(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
unsigned char **matrix;&lt;br /&gt;
&lt;br /&gt;
struct_M&#039;i make_M&#039;i(Mi) {&lt;br /&gt;
    struct_M&#039;i M&#039;i;&lt;br /&gt;
    for (auto x: Mi) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
            if (check_h(x) &amp;amp;&amp;amp; !eq(x, i)) {&lt;br /&gt;
                M&#039;i.push_back(x.add(i));&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return M&#039;i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct_Mi make_Mi(M&#039;i) {&lt;br /&gt;
    struct_Mi Mi;&lt;br /&gt;
    for (auto x: M&#039;i) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
           Mi.push_back(x.add(i));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return Mi;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    //заполнение матрицы смежности&lt;br /&gt;
    init_automorphisms(matrix);&lt;br /&gt;
&lt;br /&gt;
    //распараллеливание&lt;br /&gt;
    switch(process) {&lt;br /&gt;
    case 0:&lt;br /&gt;
        begin = 0;&lt;br /&gt;
        end = stop_0;&lt;br /&gt;
    case 1:&lt;br /&gt;
        begin = start_1;&lt;br /&gt;
        end = stop_1;&lt;br /&gt;
    ...&lt;br /&gt;
    case N:&lt;br /&gt;
        begin = start_n;&lt;br /&gt;
        end = M_0.size();&lt;br /&gt;
&lt;br /&gt;
    //основной цикл&lt;br /&gt;
    for (i = begin; i &amp;lt; end; ++i) {&lt;br /&gt;
        Mi = make_Mi(M&#039;i-1);&lt;br /&gt;
        M&#039;i = make_M&#039;i(Mi);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //сохранение результата (вывод автоморфизмов)&lt;br /&gt;
    final_automorphism(M&#039;i);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Сложность всего алгоритма представляет собой сумму сложностей вычисления &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Количество элементов в каждом множестве (с вероятностью близкой к единице):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |M&#039;_{k}| \thickapprox \frac{n!}{(n-k-2)!~2^{(k)^2}} \thickapprox \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Можно оценить: &amp;lt;math&amp;gt; |M&#039;_k| = \frac{n(n-1)\ldots(n-k-1)}{2^{(k)^2}} \le \frac{n^{k}}{2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Количество операций сравнения для подсчета всех множеств:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \sum_{k = 1}^{n} \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} \times (n - k)(2k + 1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оценка (были учтены точка стабилизации и точка максимума последовательности множеств):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; n \times \frac{n^{(5/7) \ln(n)}}{2^{((5/7)\ln(n))^2}}\times n(2(\frac{5}{7}\ln(n)) + 1)\times \log_2(n) = O(n^2(\frac{e}{2})^{\ln(n)^2} \ln(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сложность экспоненциальная.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[глоссарий#Граф алгоритма|Граф алгоритма]]&amp;lt;ref&amp;gt;Воеводин В.В.  Математические основы параллельных вычислений// М.: Изд. Моск. ун-та, 1991. 345 с.&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Воеводин В.В., Воеводин Вл.В. Параллельные вычисления. – СПб.: БХВ - Петербург, 2002. – 608 с.&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Фролов А.В.. Принципы построения и описание языка Сигма. Препринт ОВМ АН N 236. М.: ОВМ АН СССР, 1989.&amp;lt;/ref&amp;gt; для &amp;lt;math&amp;gt;n = 4&amp;lt;/math&amp;gt; (при росте &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; изменения графа будут аналогичны, а отклонения не существенны:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:Граф_автоморфизмов.png|thumb|center|1100px|Рисунок 1. Граф алгоритма. CHECK - проверка по критерию.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
При больших &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; ширина ярусов будет расти до яруса под номером &amp;lt;math&amp;gt;\lceil\frac{5}{7}\log_2(n) - 1\rceil&amp;lt;/math&amp;gt;, после начнет убывать.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для поиска автоморфизмов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; итерационным алгоритмом в параллельном варианте требуется выполнить:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; ярусов сравнений (количество сравнений &amp;lt;math&amp;gt; k = 1 \ldots n: \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} \times (n - k)(2k + 1) &amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте ЯПФ, таким образом, алогоритм имеет сложностью &amp;lt;math&amp;gt; O(n) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
При классификации по ширине ЯПФ его сложность &amp;lt;math&amp;gt; O(n(\frac{e}{2})^{\ln(n)^2} \ln(n))) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;) графа .&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; – любые, но в данной статье рассматриваются из множества {0,1}.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;, представленное матрицей (элементы &amp;lt;math&amp;gt;g^s_n&amp;lt;/math&amp;gt; - полученные автоморфизмы).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;l \times n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt; количество всевозможных автоморфизмов для данного графа.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых параметров запуска реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [4 : 128] с шагом &amp;lt;math&amp;gt; 2^n&amp;lt;/math&amp;gt; (точки отображены с шагом 4, усреднив результаты);&lt;br /&gt;
*	размер матрицы [300 : 1000].&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон алгоритма:&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 17,44%;&lt;br /&gt;
*	максимальная эффективность реализации 88,73%.&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики производительности и эффективности выбранной реализации поиска автоморфизмов графов в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:График_производительности_поиска_автоморфизмов.jpg|thumb|center|700px|Рисунок 2. Параллельная реализация алгоритма поиска автоморфизмов. Изменение производительности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
[[file:График_эффективности.jpg|thumb|center|700px|Рисунок 3. Параллельная реализация алгоритма поиска автоморфизмов. Изменение эффективности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
&lt;br /&gt;
Оценки масштабируемости выбранной реализации:&lt;br /&gt;
*	По числу процессов: -0,00837.&lt;br /&gt;
*	По размеру задачи: 0,04612. &lt;br /&gt;
*	По двум направлениям: 0,00253.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Информация о реализациях данного алгоритма не найдена. При анализе алгоритма было разработано 2 программы: &amp;lt;br/&amp;gt; &lt;br /&gt;
&lt;br /&gt;
:1) приложение с графическим интерфейсом, написанное на &#039;&#039;&#039;Qt&#039;&#039;&#039;&lt;br /&gt;
:::* не поддерживает распараллеливание&lt;br /&gt;
:::* справляется с графами размера до 500 вершин&lt;br /&gt;
:::* удобный анализ графов&lt;br /&gt;
:::* помимо нахождения автоморфизмов, решает задачи изоморфизма и гомоморфизма графов&lt;br /&gt;
:2) программа на языки &#039;&#039;&#039;C++&#039;&#039;&#039; с поддержкой &#039;&#039;&#039;OpenMPI&#039;&#039;&#039;&lt;br /&gt;
:::* поддерживает распараллеливание средствами OpenMPI&lt;br /&gt;
:::* помимо нахождения автоморфизмов, сохраняет много информации для анализа графов с большим количеством вершин&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25077</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25077"/>
		<updated>2017-12-10T20:39:33Z</updated>

		<summary type="html">&lt;p&gt;Full: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&amp;lt;br&amp;gt;&lt;br /&gt;
Автор статьи: Ефремов С.С. (группа 419)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром алгоритма является последовательность множеств  &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;. Вычисляется на основе соответствующих &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt;. Построение &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt; занимает несущественную часть времени.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Каждое множество &amp;lt;math&amp;gt; M_i (i = 2 \ldots n) &amp;lt;/math&amp;gt; вычисляется из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; путем добавления в каждый элемент (частичная перестановка, представленная вектором целых чисел) из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; всех возможных оставшихся чисел, которых нет в соответствующем элементе.&lt;br /&gt;
&lt;br /&gt;
Для этого удобно использовать 2 не фиксированных по количеству строк двумерных массива размера t на n (t может увеличиваться), хранящих частичные отображения, такого вида: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
a_{11} &amp;amp; a_{12} &amp;amp; \ldots &amp;amp;a_{1i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
a_{21} &amp;amp; a_{22} &amp;amp; \ldots &amp;amp;a_{2i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
a_{k1} &amp;amp; a_{k2} &amp;amp; \ldots &amp;amp;a_{ki} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
? - эти значения не известны и заполняются постепенно.&lt;br /&gt;
&lt;br /&gt;
Один массив для &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt;, другой для вычисления из предыдущего &amp;lt;math&amp;gt; M_i &amp;lt;/math&amp;gt;.&lt;br /&gt;
Из каждой строки множества &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; (первый массив), в соответствие с алгоритмом, получается &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; новых строк длины i, которые записываются во второй массив (расширяется, если нужно).&lt;br /&gt;
&lt;br /&gt;
После этого, второй массив копируется в первый и запускается цикл по всем векторам. Вектор исключается из массива, если &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; равен какому-либо числу в данном векторе или вектор с &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; является частичной перестановкой, не удовлетворяющей критерию;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Схема реализации представлена на языке C++&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#define GRAPH_SIZE 300&lt;br /&gt;
#define ROW_ARR_SIZE 10000 &lt;br /&gt;
#define COL_ARR_SIZE GRAPH_SIZE&lt;br /&gt;
&lt;br /&gt;
const int N = GRAPH_SIZE;&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; Mi(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; M&#039;i(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
unsigned char **matrix;&lt;br /&gt;
&lt;br /&gt;
struct_M&#039;i make_M&#039;i(Mi) {&lt;br /&gt;
    struct_M&#039;i M&#039;i;&lt;br /&gt;
    for (auto x: Mi) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
            if (check_h(x) &amp;amp;&amp;amp; !eq(x, i)) {&lt;br /&gt;
                M&#039;i.push_back(x.add(i));&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return M&#039;i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct_Mi make_Mi(M&#039;i) {&lt;br /&gt;
    struct_Mi Mi;&lt;br /&gt;
    for (auto x: M&#039;i) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
           Mi.push_back(x.add(i));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return Mi;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    //заполнение матрицы смежности&lt;br /&gt;
    init_automorphisms(matrix);&lt;br /&gt;
&lt;br /&gt;
    //распараллеливание&lt;br /&gt;
    switch(process) {&lt;br /&gt;
    case 0:&lt;br /&gt;
        begin = 0;&lt;br /&gt;
        end = stop_0;&lt;br /&gt;
    case 1:&lt;br /&gt;
        begin = start_1;&lt;br /&gt;
        end = stop_1;&lt;br /&gt;
    ...&lt;br /&gt;
    case N:&lt;br /&gt;
        begin = start_n;&lt;br /&gt;
        end = M_0.size();&lt;br /&gt;
&lt;br /&gt;
    //основной цикл&lt;br /&gt;
    for (i = begin; i &amp;lt; end; ++i) {&lt;br /&gt;
        Mi = make_Mi(M&#039;i-1);&lt;br /&gt;
        M&#039;i = make_M&#039;i(Mi);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //сохранение результата (вывод автоморфизмов)&lt;br /&gt;
    final_automorphism(M&#039;i);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Сложность всего алгоритма представляет собой сумму сложностей вычисления &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Количество элементов в каждом множестве (с вероятностью близкой к единице):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |M&#039;_{k}| \thickapprox \frac{n!}{(n-k-2)!~2^{(k)^2}} \thickapprox \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Можно оценить: &amp;lt;math&amp;gt; |M&#039;_k| = \frac{n(n-1)\ldots(n-k-1)}{2^{(k)^2}} \le \frac{n^{k}}{2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Количество операций сравнения для подсчета всех множеств:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \sum_{k = 1}^{n} \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} \times (n - k)(2k + 1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оценка (были учтены точка стабилизации и точка максимума последовательности множеств):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; n \times \frac{n^{(5/7) \ln(n)}}{2^{((5/7)\ln(n))^2}}\times n(2(\frac{5}{7}\ln(n)) + 1)\times \log_2(n) = O(n^2(\frac{e}{2})^{\ln(n)^2} \ln(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сложность экспоненциальная.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[глоссарий#Граф алгоритма|Граф алгоритма]]&amp;lt;ref&amp;gt;Воеводин В.В.  Математические основы параллельных вычислений// М.: Изд. Моск. ун-та, 1991. 345 с.&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Воеводин В.В., Воеводин Вл.В. Параллельные вычисления. – СПб.: БХВ - Петербург, 2002. – 608 с.&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Фролов А.В.. Принципы построения и описание языка Сигма. Препринт ОВМ АН N 236. М.: ОВМ АН СССР, 1989.&amp;lt;/ref&amp;gt; для &amp;lt;math&amp;gt;n = 4&amp;lt;/math&amp;gt; (при росте &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; изменения графа будут аналогичны, а отклонения не существенны:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:Граф_автоморфизмов.png|thumb|center|1100px|Рисунок 1. Граф алгоритма. CHECK - проверка по критерию.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
При больших &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; ширина ярусов будет расти до яруса под номером &amp;lt;math&amp;gt;\lceil\frac{5}{7}\log_2(n) - 1\rceil&amp;lt;/math&amp;gt;, после начнет убывать.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для поиска автоморфизмов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; итерационным алгоритмом в параллельном варианте требуется выполнить:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; ярусов сравнений (количество сравнений &amp;lt;math&amp;gt; k = 1 \ldots n: \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} \times (n - k)(2k + 1) &amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте ЯПФ, таким образом, алогоритм имеет сложностью &amp;lt;math&amp;gt; O(n) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
При классификации по ширине ЯПФ его сложность &amp;lt;math&amp;gt; O(n(\frac{e}{2})^{\ln(n)^2} \ln(n))) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;) графа .&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; – любые, но в данной статье рассматриваются из множества {0,1}.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;, представленное матрицей (элементы &amp;lt;math&amp;gt;g^s_n&amp;lt;/math&amp;gt; - полученные автоморфизмы).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;l \times n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt; количество всевозможных автоморфизмов для данного графа.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых параметров запуска реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [4 : 128] с шагом &amp;lt;math&amp;gt; 2^n&amp;lt;/math&amp;gt; (точки отображены с шагом 4, усреднив результаты);&lt;br /&gt;
*	размер матрицы [300 : 1000].&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон алгоритма:&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 17,44%;&lt;br /&gt;
*	максимальная эффективность реализации 88,73%.&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики производительности и эффективности выбранной реализации поиска автоморфизмов графов в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:График_производительности_поиска_автоморфизмов.jpg|thumb|center|700px|Рисунок 2. Параллельная реализация алгоритма поиска автоморфизмов. Изменение производительности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
[[file:График_эффективности.jpg|thumb|center|700px|Рисунок 3. Параллельная реализация алгоритма поиска автоморфизмов. Изменение эффективности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
&lt;br /&gt;
Оценки масштабируемости выбранной реализации:&lt;br /&gt;
*	По числу процессов: -0,000593.&lt;br /&gt;
*	По размеру задачи: 0,06017. &lt;br /&gt;
*	По двум направлениям: 0,000403.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Информация о реализациях данного алгоритма не найдена. При анализе алгоритма было разработано 2 программы: &amp;lt;br/&amp;gt; &lt;br /&gt;
&lt;br /&gt;
:1) приложение с графическим интерфейсом, написанное на &#039;&#039;&#039;Qt&#039;&#039;&#039;&lt;br /&gt;
:::* не поддерживает распараллеливание&lt;br /&gt;
:::* справляется с графами размера до 500 вершин&lt;br /&gt;
:::* удобный анализ графов&lt;br /&gt;
:::* помимо нахождения автоморфизмов, решает задачи изоморфизма и гомоморфизма графов&lt;br /&gt;
:2) программа на языки &#039;&#039;&#039;C++&#039;&#039;&#039; с поддержкой &#039;&#039;&#039;OpenMPI&#039;&#039;&#039;&lt;br /&gt;
:::* поддерживает распараллеливание средствами OpenMPI&lt;br /&gt;
:::* помимо нахождения автоморфизмов, сохраняет много информации для анализа графов с большим количеством вершин&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25076</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25076"/>
		<updated>2017-12-10T20:32:37Z</updated>

		<summary type="html">&lt;p&gt;Full: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&amp;lt;br&amp;gt;&lt;br /&gt;
Автор статьи: Ефремов С.С. (группа 419)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром алгоритма является последовательность множеств  &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;. Вычисляется на основе соответствующих &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt;. Построение &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt; занимает несущественную часть времени.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Каждое множество &amp;lt;math&amp;gt; M_i (i = 2 \ldots n) &amp;lt;/math&amp;gt; вычисляется из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; путем добавления в каждый элемент (частичная перестановка, представленная вектором целых чисел) из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; всех возможных оставшихся чисел, которых нет в соответствующем элементе.&lt;br /&gt;
&lt;br /&gt;
Для этого удобно использовать 2 не фиксированных по количеству строк двумерных массива размера t на n (t может увеличиваться), хранящих частичные отображения, такого вида: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
a_{11} &amp;amp; a_{12} &amp;amp; \ldots &amp;amp;a_{1i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
a_{21} &amp;amp; a_{22} &amp;amp; \ldots &amp;amp;a_{2i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
a_{k1} &amp;amp; a_{k2} &amp;amp; \ldots &amp;amp;a_{ki} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
? - эти значения не известны и заполняются постепенно.&lt;br /&gt;
&lt;br /&gt;
Один массив для &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt;, другой для вычисления из предыдущего &amp;lt;math&amp;gt; M_i &amp;lt;/math&amp;gt;.&lt;br /&gt;
Из каждой строки множества &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; (первый массив), в соответствие с алгоритмом, получается &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; новых строк длины i, которые записываются во второй массив (расширяется, если нужно).&lt;br /&gt;
&lt;br /&gt;
После этого, второй массив копируется в первый и запускается цикл по всем векторам. Вектор исключается из массива, если &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; равен какому-либо числу в данном векторе или вектор с &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; является частичной перестановкой, не удовлетворяющей критерию;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Схема реализации представлена на языке C++&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#define GRAPH_SIZE 300&lt;br /&gt;
#define ROW_ARR_SIZE 10000 &lt;br /&gt;
#define COL_ARR_SIZE GRAPH_SIZE&lt;br /&gt;
&lt;br /&gt;
const int N = GRAPH_SIZE;&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; Mi(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; M&#039;i(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
unsigned char **matrix;&lt;br /&gt;
&lt;br /&gt;
struct_M&#039;i make_M&#039;i(Mi) {&lt;br /&gt;
    struct_M&#039;i M&#039;i;&lt;br /&gt;
    for (auto x: Mi) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
            if (check_h(x) &amp;amp;&amp;amp; !eq(x, i)) {&lt;br /&gt;
                M&#039;i.push_back(x.add(i));&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return M&#039;i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct_Mi make_Mi(M&#039;i) {&lt;br /&gt;
    struct_Mi Mi;&lt;br /&gt;
    for (auto x: M&#039;i) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
           Mi.push_back(x.add(i));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return Mi;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    //заполнение матрицы смежности&lt;br /&gt;
    init_automorphisms(matrix);&lt;br /&gt;
&lt;br /&gt;
    //распараллеливание&lt;br /&gt;
    switch(process) {&lt;br /&gt;
    case 0:&lt;br /&gt;
        begin = 0;&lt;br /&gt;
        end = stop_0;&lt;br /&gt;
    case 1:&lt;br /&gt;
        begin = start_1;&lt;br /&gt;
        end = stop_1;&lt;br /&gt;
    ...&lt;br /&gt;
    case N:&lt;br /&gt;
        begin = start_n;&lt;br /&gt;
        end = M_0.size();&lt;br /&gt;
&lt;br /&gt;
    //основной цикл&lt;br /&gt;
    for (i = begin; i &amp;lt; end; ++i) {&lt;br /&gt;
        Mi = make_Mi(M&#039;i-1);&lt;br /&gt;
        M&#039;i = make_M&#039;i(Mi);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //сохранение результата (вывод автоморфизмов)&lt;br /&gt;
    final_automorphism(M&#039;i);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Сложность всего алгоритма представляет собой сумму сложностей вычисления &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Количество элементов в каждом множестве (с вероятностью близкой к единице):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |M&#039;_{k}| \thickapprox \frac{n!}{(n-k-2)!~2^{(k)^2}} \thickapprox \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Можно оценить: &amp;lt;math&amp;gt; |M&#039;_k| = \frac{n(n-1)\ldots(n-k-1)}{2^{(k)^2}} \le \frac{n^{k}}{2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Количество операций сравнения для подсчета всех множеств:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \sum_{k = 1}^{n} \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} \times (n - k)(2k + 1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оценка (были учтены точка стабилизации и точка максимума последовательности множеств):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; n \times \frac{n^{(5/7) \ln(n)}}{2^{((5/7)\ln(n))^2}}\times n(2(\frac{5}{7}\ln(n)) + 1)\times \log_2(n) = O(n^2(\frac{e}{2})^{\ln(n)^2} \ln(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сложность экспоненциальная.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[глоссарий#Граф алгоритма|Граф алгоритма]]&amp;lt;ref&amp;gt;Воеводин В.В.  Математические основы параллельных вычислений// М.: Изд. Моск. ун-та, 1991. 345 с.&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Воеводин В.В., Воеводин Вл.В. Параллельные вычисления. – СПб.: БХВ - Петербург, 2002. – 608 с.&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Фролов А.В.. Принципы построения и описание языка Сигма. Препринт ОВМ АН N 236. М.: ОВМ АН СССР, 1989.&amp;lt;/ref&amp;gt; для &amp;lt;math&amp;gt;n = 4&amp;lt;/math&amp;gt; (при росте &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; изменения графа будут аналогичны, а отклонения не существенны:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:Граф_автоморфизмов.png|thumb|center|1100px|Рисунок 1. Граф алгоритма. CHECK - проверка по критерию.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
При больших &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; ширина ярусов будет расти до яруса под номером &amp;lt;math&amp;gt;\lceil\frac{5}{7}\log_2(n) - 1\rceil&amp;lt;/math&amp;gt;, после начнет убывать.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для поиска автоморфизмов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; итерационным алгоритмом в параллельном варианте требуется выполнить:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; ярусов сравнений (количество сравнений &amp;lt;math&amp;gt; k = 1 \ldots n: \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} \times (n - k)(2k + 1) &amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте ЯПФ, таким образом, алогоритм имеет сложностью &amp;lt;math&amp;gt; O(n) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
При классификации по ширине ЯПФ его сложность &amp;lt;math&amp;gt; O(n(\frac{e}{2})^{\ln(n)^2} \ln(n))) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;) графа .&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; – любые, но в данной статье рассматриваются из множества {0,1}.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;, представленное матрицей (элементы &amp;lt;math&amp;gt;g^s_n&amp;lt;/math&amp;gt; - полученные автоморфизмы).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;l \times n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt; количество всевозможных автоморфизмов для данного графа.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [4 : 128] с шагом &amp;lt;math&amp;gt; 2^n&amp;lt;/math&amp;gt; (точки отображены с шагом 4, усреднив результаты);&lt;br /&gt;
*	размер матрицы [300 : 1000].&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон алгоритма:&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 17,44%;&lt;br /&gt;
*	максимальная эффективность реализации 88,73%.&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики производительности и эффективности выбранной реализации поиска автоморфизмов графов в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:График_производительности_поиска_автоморфизмов.jpg|thumb|center|700px|Рисунок 2. Параллельная реализация алгоритма поиска автоморфизмов. Изменение производительности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
[[file:График_эффективности.jpg|thumb|center|700px|Рисунок 3. Параллельная реализация алгоритма поиска автоморфизмов. Изменение эффективности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
&lt;br /&gt;
Оценки масштабируемости выбранной реализации:&lt;br /&gt;
*	По числу процессов: -0,000593.&lt;br /&gt;
*	По размеру задачи: 0,06017. &lt;br /&gt;
*	По двум направлениям: 0,000403.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Информация о реализациях данного алгоритма не найдена. При анализе алгоритма было разработано 2 программы: &amp;lt;br/&amp;gt; &lt;br /&gt;
&lt;br /&gt;
:1) приложение с графическим интерфейсом, написанное на &#039;&#039;&#039;Qt&#039;&#039;&#039;&lt;br /&gt;
:::* не поддерживает распараллеливание&lt;br /&gt;
:::* справляется с графами размера до 500 вершин&lt;br /&gt;
:::* удобный анализ графов&lt;br /&gt;
:::* помимо нахождения автоморфизмов, решает задачи изоморфизма и гомоморфизма графов&lt;br /&gt;
:2) программа на языки &#039;&#039;&#039;C++&#039;&#039;&#039; с поддержкой &#039;&#039;&#039;OpenMPI&#039;&#039;&#039;&lt;br /&gt;
:::* поддерживает распараллеливание средствами OpenMPI&lt;br /&gt;
:::* помимо нахождения автоморфизмов, сохраняет много информации для анализа графов с большим количеством вершин&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25075</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25075"/>
		<updated>2017-12-10T20:31:16Z</updated>

		<summary type="html">&lt;p&gt;Full: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&amp;lt;br&amp;gt;&lt;br /&gt;
Автор статьи: Ефремов С.С. (группа 419)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром алгоритма является последовательность множеств  &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;. Вычисляется на основе соответствующих &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt;. Построение &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt; занимает несущественную часть времени.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Каждое множество &amp;lt;math&amp;gt; M_i (i = 2 \ldots n) &amp;lt;/math&amp;gt; вычисляется из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; путем добавления в каждый элемент (частичная перестановка, представленная вектором целых чисел) из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; всех возможных оставшихся чисел, которых нет в соответствующем элементе.&lt;br /&gt;
&lt;br /&gt;
Для этого удобно использовать 2 не фиксированных по количеству строк двумерных массива размера t на n (t может увеличиваться), хранящих частичные отображения, такого вида: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
a_{11} &amp;amp; a_{12} &amp;amp; \ldots &amp;amp;a_{1i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
a_{21} &amp;amp; a_{22} &amp;amp; \ldots &amp;amp;a_{2i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
a_{k1} &amp;amp; a_{k2} &amp;amp; \ldots &amp;amp;a_{ki} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
? - эти значения не известны и заполняются постепенно.&lt;br /&gt;
&lt;br /&gt;
Один массив для &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt;, другой для вычисления из предыдущего &amp;lt;math&amp;gt; M_i &amp;lt;/math&amp;gt;.&lt;br /&gt;
Из каждой строки множества &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; (первый массив), в соответствие с алгоритмом, получается &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; новых строк длины i, которые записываются во второй массив (расширяется, если нужно).&lt;br /&gt;
&lt;br /&gt;
После этого, второй массив копируется в первый и запускается цикл по всем векторам. Вектор исключается из массива, если &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; равен какому-либо числу в данном векторе или вектор с &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; является частичной перестановкой, не удовлетворяющей критерию;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Схема реализации представлена на языке C++&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#define GRAPH_SIZE 300&lt;br /&gt;
#define ROW_ARR_SIZE 10000 &lt;br /&gt;
#define COL_ARR_SIZE GRAPH_SIZE&lt;br /&gt;
&lt;br /&gt;
const int N = GRAPH_SIZE;&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; Mi(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; M&#039;i(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
unsigned char **matrix;&lt;br /&gt;
&lt;br /&gt;
struct_M&#039;i make_M&#039;i(Mi) {&lt;br /&gt;
    struct_M&#039;i M&#039;i;&lt;br /&gt;
    for (auto x: Mi) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
            if (check_h(x) &amp;amp;&amp;amp; !eq(x, i)) {&lt;br /&gt;
                M&#039;i.push_back(x.add(i));&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return M&#039;i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct_Mi make_Mi(M&#039;i) {&lt;br /&gt;
    struct_Mi Mi;&lt;br /&gt;
    for (auto x: M&#039;i) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
           Mi.push_back(x.add(i));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return Mi;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    //заполнение матрицы смежности&lt;br /&gt;
    init_automorphisms(matrix);&lt;br /&gt;
&lt;br /&gt;
    //распараллеливание&lt;br /&gt;
    switch(process) {&lt;br /&gt;
    case 0:&lt;br /&gt;
        begin = 0;&lt;br /&gt;
        end = stop_0;&lt;br /&gt;
    case 1:&lt;br /&gt;
        begin = start_1;&lt;br /&gt;
        end = stop_1;&lt;br /&gt;
    ...&lt;br /&gt;
    case N:&lt;br /&gt;
        begin = start_n;&lt;br /&gt;
        end = M_0.size();&lt;br /&gt;
&lt;br /&gt;
    //основной цикл&lt;br /&gt;
    for (i = begin; i &amp;lt; end; ++i) {&lt;br /&gt;
        Mi = make_Mi(M&#039;i-1);&lt;br /&gt;
        M&#039;i = make_M&#039;i(Mi);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //сохранение результата (вывод автоморфизмов)&lt;br /&gt;
    final_automorphism(M&#039;i);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Сложность всего алгоритма представляет собой сумму сложностей вычисления &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Количество элементов в каждом множестве (с вероятностью близкой к единице):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |M&#039;_{k}| \thickapprox \frac{n!}{(n-k-2)!~2^{(k)^2}} \thickapprox \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Можно оценить: &amp;lt;math&amp;gt; |M&#039;_k| = \frac{n(n-1)\ldots(n-k-1)}{2^{(k)^2}} \le \frac{n^{k}}{2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Количество операций сравнения для подсчета всех множеств:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \sum_{k = 1}^{n} \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} \times (n - k)(2k + 1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оценка (были учтены точка стабилизации и точка максимума последовательности множеств):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; n \times \frac{n^{(5/7) \ln(n)}}{2^{((5/7)\ln(n))^2}}\times n(2(\frac{5}{7}\ln(n)) + 1)\times \log_2(n) = O(n^2(\frac{e}{2})^{\ln(n)^2} \ln(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сложность экспоненциальная.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[глоссарий#Граф алгоритма|Граф алгоритма]]&amp;lt;ref&amp;gt;Воеводин В.В.  Математические основы параллельных вычислений// М.: Изд. Моск. ун-та, 1991. 345 с.&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Воеводин В.В., Воеводин Вл.В. Параллельные вычисления. – СПб.: БХВ - Петербург, 2002. – 608 с.&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Фролов А.В.. Принципы построения и описание языка Сигма. Препринт ОВМ АН N 236. М.: ОВМ АН СССР, 1989.&amp;lt;/ref&amp;gt; для &amp;lt;math&amp;gt;n = 4&amp;lt;/math&amp;gt; (при росте &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; изменения графа будут аналогичны, а отклонения не существенны:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:Граф_автоморфизмов.png|thumb|center|1100px|Рисунок 1. Граф алгоритма. CHECK - проверка по критерию.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
При больших &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; ширина ярусов будет расти до яруса под номером &amp;lt;math&amp;gt;\lceil\frac{5}{7}\log_2(n) - 1\rceil&amp;lt;/math&amp;gt;, после начнет убывать.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для поиска автоморфизмов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; итерационным алгоритмом в параллельном варианте требуется выполнить:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; ярусов сравнений (количество сравнений &amp;lt;math&amp;gt; k = 1 \ldots n: \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} \times (n - k)(2k + 1) &amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте ЯПФ, таким образом, алогоритм имеет сложностью &amp;lt;math&amp;gt; O(n) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
При классификации по ширине ЯПФ его сложность &amp;lt;math&amp;gt; O(n(\frac{e}{2})^{\ln(n)^2} \ln(n))) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;) графа .&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; – любые, но в данной статье рассматриваются из множества {0,1}.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;, представленное матрицей (элементы &amp;lt;math&amp;gt;g^s_n&amp;lt;/math&amp;gt; - полученные автоморфизмы).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;l \times n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt; количество всевозможных автоморфизмов для данного графа.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [4 : 128] с шагом &amp;lt;math&amp;gt; 2^n&amp;lt;/math&amp;gt; (точки отображены с шагом 4, усреднив результаты);&lt;br /&gt;
*	размер матрицы [300 : 1000].&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон алгоритма:&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 17,44%;&lt;br /&gt;
*	максимальная эффективность реализации 88,73%.&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики производительности и эффективности выбранной реализации поиска автоморфизмов графов в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:График_производительности_поиска_автоморфизмов.jpg|thumb|center|700px|Рисунок 2. Параллельная реализация алгоритма поиска автоморфизмов. Изменение производительности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
[[file:График эффективности|thumb|center|700px|Рисунок 3. Параллельная реализация алгоритма поиска автоморфизмов. Изменение эффективности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
&lt;br /&gt;
Оценки масштабируемости выбранной реализации:&lt;br /&gt;
*	По числу процессов: -0,000593.&lt;br /&gt;
*	По размеру задачи: 0,06017. &lt;br /&gt;
*	По двум направлениям: 0,000403.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Информация о реализациях данного алгоритма не найдена. При анализе алгоритма было разработано 2 программы: &amp;lt;br/&amp;gt; &lt;br /&gt;
&lt;br /&gt;
:1) приложение с графическим интерфейсом, написанное на &#039;&#039;&#039;Qt&#039;&#039;&#039;&lt;br /&gt;
:::* не поддерживает распараллеливание&lt;br /&gt;
:::* справляется с графами размера до 500 вершин&lt;br /&gt;
:::* удобный анализ графов&lt;br /&gt;
:::* помимо нахождения автоморфизмов, решает задачи изоморфизма и гомоморфизма графов&lt;br /&gt;
:2) программа на языки &#039;&#039;&#039;C++&#039;&#039;&#039; с поддержкой &#039;&#039;&#039;OpenMPI&#039;&#039;&#039;&lt;br /&gt;
:::* поддерживает распараллеливание средствами OpenMPI&lt;br /&gt;
:::* помимо нахождения автоморфизмов, сохраняет много информации для анализа графов с большим количеством вершин&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25074</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25074"/>
		<updated>2017-12-10T16:13:26Z</updated>

		<summary type="html">&lt;p&gt;Full: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&amp;lt;br&amp;gt;&lt;br /&gt;
Автор статьи: Ефремов С.С. (группа 419)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром алгоритма является последовательность множеств  &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;. Вычисляется на основе соответствующих &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt;. Построение &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt; занимает несущественную часть времени.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Каждое множество &amp;lt;math&amp;gt; M_i (i = 2 \ldots n) &amp;lt;/math&amp;gt; вычисляется из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; путем добавления в каждый элемент (частичная перестановка, представленная вектором целых чисел) из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; всех возможных оставшихся чисел, которых нет в соответствующем элементе.&lt;br /&gt;
&lt;br /&gt;
Для этого удобно использовать 2 не фиксированных по количеству строк двумерных массива размера t на n (t может увеличиваться), хранящих частичные отображения, такого вида: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
a_{11} &amp;amp; a_{12} &amp;amp; \ldots &amp;amp;a_{1i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
a_{21} &amp;amp; a_{22} &amp;amp; \ldots &amp;amp;a_{2i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
a_{k1} &amp;amp; a_{k2} &amp;amp; \ldots &amp;amp;a_{ki} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
? - эти значения не известны и заполняются постепенно.&lt;br /&gt;
&lt;br /&gt;
Один массив для &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt;, другой для вычисления из предыдущего &amp;lt;math&amp;gt; M_i &amp;lt;/math&amp;gt;.&lt;br /&gt;
Из каждой строки множества &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; (первый массив), в соответствие с алгоритмом, получается &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; новых строк длины i, которые записываются во второй массив (расширяется, если нужно).&lt;br /&gt;
&lt;br /&gt;
После этого, второй массив копируется в первый и запускается цикл по всем векторам. Вектор исключается из массива, если &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; равен какому-либо числу в данном векторе или вектор с &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; является частичной перестановкой, не удовлетворяющей критерию;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Схема реализации представлена на языке C++&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#define GRAPH_SIZE 300&lt;br /&gt;
#define ROW_ARR_SIZE 10000 &lt;br /&gt;
#define COL_ARR_SIZE GRAPH_SIZE&lt;br /&gt;
&lt;br /&gt;
const int N = GRAPH_SIZE;&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; Mi(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; M&#039;i(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
unsigned char **matrix;&lt;br /&gt;
&lt;br /&gt;
struct_M&#039;i make_M&#039;i(Mi) {&lt;br /&gt;
    struct_M&#039;i M&#039;i;&lt;br /&gt;
    for (auto x: Mi) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
            if (check_h(x) &amp;amp;&amp;amp; !eq(x, i)) {&lt;br /&gt;
                M&#039;i.push_back(x.add(i));&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return M&#039;i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct_Mi make_Mi(M&#039;i) {&lt;br /&gt;
    struct_Mi Mi;&lt;br /&gt;
    for (auto x: M&#039;i) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
           Mi.push_back(x.add(i));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return Mi;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    //заполнение матрицы смежности&lt;br /&gt;
    init_automorphisms(matrix);&lt;br /&gt;
&lt;br /&gt;
    //распараллеливание&lt;br /&gt;
    switch(process) {&lt;br /&gt;
    case 0:&lt;br /&gt;
        begin = 0;&lt;br /&gt;
        end = stop_0;&lt;br /&gt;
    case 1:&lt;br /&gt;
        begin = start_1;&lt;br /&gt;
        end = stop_1;&lt;br /&gt;
    ...&lt;br /&gt;
    case N:&lt;br /&gt;
        begin = start_n;&lt;br /&gt;
        end = M_0.size();&lt;br /&gt;
&lt;br /&gt;
    //основной цикл&lt;br /&gt;
    for (i = begin; i &amp;lt; end; ++i) {&lt;br /&gt;
        Mi = make_Mi(M&#039;i-1);&lt;br /&gt;
        M&#039;i = make_M&#039;i(Mi);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //сохранение результата (вывод автоморфизмов)&lt;br /&gt;
    final_automorphism(M&#039;i);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Сложность всего алгоритма представляет собой сумму сложностей вычисления &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Количество элементов в каждом множестве (с вероятностью близкой к единице):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |M&#039;_{k}| \thickapprox \frac{n!}{(n-k-2)!~2^{(k)^2}} \thickapprox \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Можно оценить: &amp;lt;math&amp;gt; |M&#039;_k| = \frac{n(n-1)\ldots(n-k-1)}{2^{(k)^2}} \le \frac{n^{k}}{2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Количество операций сравнения для подсчета всех множеств:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \sum_{k = 1}^{n} \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} \times (n - k)(2k + 1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оценка (были учтены точка стабилизации и точка максимума последовательности множеств):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; n \times \frac{n^{(5/7) \ln(n)}}{2^{((5/7)\ln(n))^2}}\times n(2(\frac{5}{7}\ln(n)) + 1)\times \log_2(n) = O(n^2(\frac{e}{2})^{\ln(n)^2} \ln(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сложность экспоненциальная.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[глоссарий#Граф алгоритма|Граф алгоритма]]&amp;lt;ref&amp;gt;Воеводин В.В.  Математические основы параллельных вычислений// М.: Изд. Моск. ун-та, 1991. 345 с.&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Воеводин В.В., Воеводин Вл.В. Параллельные вычисления. – СПб.: БХВ - Петербург, 2002. – 608 с.&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Фролов А.В.. Принципы построения и описание языка Сигма. Препринт ОВМ АН N 236. М.: ОВМ АН СССР, 1989.&amp;lt;/ref&amp;gt; для &amp;lt;math&amp;gt;n = 4&amp;lt;/math&amp;gt; (при росте &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; изменения графа будут аналогичны, а отклонения не существенны:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:Граф_автоморфизмов.png|thumb|center|1100px|Рисунок 1. Граф алгоритма. CHECK - проверка по критерию.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
При больших &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; ширина ярусов будет расти до яруса под номером &amp;lt;math&amp;gt;\lceil\frac{5}{7}\log_2(n) - 1\rceil&amp;lt;/math&amp;gt;, после начнет убывать.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для поиска автоморфизмов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; итерационным алгоритмом в параллельном варианте требуется выполнить:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; ярусов сравнений (количество сравнений &amp;lt;math&amp;gt; k = 1 \ldots n: \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} \times (n - k)(2k + 1) &amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте ЯПФ, таким образом, алогоритм имеет сложностью &amp;lt;math&amp;gt; O(n) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
При классификации по ширине ЯПФ его сложность &amp;lt;math&amp;gt; O(n(\frac{e}{2})^{\ln(n)^2} \ln(n))) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;) графа .&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; – любые, но в данной статье рассматриваются из множества {0,1}.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;, представленное матрицей (элементы &amp;lt;math&amp;gt;g^s_n&amp;lt;/math&amp;gt; - полученные автоморфизмы).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;l \times n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt; количество всевозможных автоморфизмов для данного графа.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [4 : 128] с шагом &amp;lt;math&amp;gt; 2^n&amp;lt;/math&amp;gt; (точки отображены с шагом 4, усреднив результаты);&lt;br /&gt;
*	размер матрицы [300 : 1000].&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон алгоритма:&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации ???%;&lt;br /&gt;
*	максимальная эффективность реализации ???%.&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики производительности и эффективности выбранной реализации поиска автоморфизмов графов в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:График_производительности_поиска_автоморфизмов.jpg|thumb|center|700px|Рисунок 2. Параллельная реализация алгоритма поиска автоморфизмов. Изменение производительности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
[[file:.png|thumb|center|700px|Рисунок 3. Параллельная реализация алгоритма поиска автоморфизмов. Изменение эффективности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
&lt;br /&gt;
Оценки масштабируемости выбранной реализации:&lt;br /&gt;
*	По числу процессов: -0,000593.&lt;br /&gt;
*	По размеру задачи: 0,06017. &lt;br /&gt;
*	По двум направлениям: 0,000403.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Информация о реализациях данного алгоритма не найдена. При анализе алгоритма было разработано 2 программы: &amp;lt;br/&amp;gt; &lt;br /&gt;
&lt;br /&gt;
:1) приложение с графическим интерфейсом, написанное на &#039;&#039;&#039;Qt&#039;&#039;&#039;&lt;br /&gt;
:::* не поддерживает распараллеливание&lt;br /&gt;
:::* справляется с графами размера до 500 вершин&lt;br /&gt;
:::* удобный анализ графов&lt;br /&gt;
:::* помимо нахождения автоморфизмов, решает задачи изоморфизма и гомоморфизма графов&lt;br /&gt;
:2) программа на языки &#039;&#039;&#039;C++&#039;&#039;&#039; с поддержкой &#039;&#039;&#039;OpenMPI&#039;&#039;&#039;&lt;br /&gt;
:::* поддерживает распараллеливание средствами OpenMPI&lt;br /&gt;
:::* помимо нахождения автоморфизмов, сохраняет много информации для анализа графов с большим количеством вершин&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25073</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25073"/>
		<updated>2017-12-10T16:06:45Z</updated>

		<summary type="html">&lt;p&gt;Full: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&amp;lt;br&amp;gt;&lt;br /&gt;
Автор статьи: Ефремов С.С. (группа 419)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром алгоритма является последовательность множеств  &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;. Вычисляется на основе соответствующих &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt;. Построение &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt; занимает несущественную часть времени.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Каждое множество &amp;lt;math&amp;gt; M_i (i = 2 \ldots n) &amp;lt;/math&amp;gt; вычисляется из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; путем добавления в каждый элемент (частичная перестановка, представленная вектором целых чисел) из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; всех возможных оставшихся чисел, которых нет в соответствующем элементе.&lt;br /&gt;
&lt;br /&gt;
Для этого удобно использовать 2 не фиксированных по количеству строк двумерных массива размера t на n (t может увеличиваться), хранящих частичные отображения, такого вида: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
a_{11} &amp;amp; a_{12} &amp;amp; \ldots &amp;amp;a_{1i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
a_{21} &amp;amp; a_{22} &amp;amp; \ldots &amp;amp;a_{2i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
a_{k1} &amp;amp; a_{k2} &amp;amp; \ldots &amp;amp;a_{ki} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
? - эти значения не известны и заполняются постепенно.&lt;br /&gt;
&lt;br /&gt;
Один массив для &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt;, другой для вычисления из предыдущего &amp;lt;math&amp;gt; M_i &amp;lt;/math&amp;gt;.&lt;br /&gt;
Из каждой строки множества &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; (первый массив), в соответствие с алгоритмом, получается &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; новых строк длины i, которые записываются во второй массив (расширяется, если нужно).&lt;br /&gt;
&lt;br /&gt;
После этого, второй массив копируется в первый и запускается цикл по всем векторам. Вектор исключается из массива, если &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; равен какому-либо числу в данном векторе или вектор с &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; является частичной перестановкой, не удовлетворяющей критерию;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Схема реализации представлена на языке C++&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#define GRAPH_SIZE 300&lt;br /&gt;
#define ROW_ARR_SIZE 10000 &lt;br /&gt;
#define COL_ARR_SIZE GRAPH_SIZE&lt;br /&gt;
&lt;br /&gt;
const int N = GRAPH_SIZE;&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; Mi(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; M&#039;i(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
unsigned char **matrix;&lt;br /&gt;
&lt;br /&gt;
struct_M&#039;i make_M&#039;i(Mi) {&lt;br /&gt;
    struct_M&#039;i M&#039;i;&lt;br /&gt;
    for (auto x: Mi) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
            if (check_h(x) &amp;amp;&amp;amp; !eq(x, i)) {&lt;br /&gt;
                M&#039;i.push_back(x.add(i));&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return M&#039;i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct_Mi make_Mi(M&#039;i) {&lt;br /&gt;
    struct_Mi Mi;&lt;br /&gt;
    for (auto x: M&#039;i) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
           Mi.push_back(x.add(i));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return Mi;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    //заполнение матрицы смежности&lt;br /&gt;
    init_automorphisms(matrix);&lt;br /&gt;
&lt;br /&gt;
    //распараллеливание&lt;br /&gt;
    switch(process) {&lt;br /&gt;
    case 0:&lt;br /&gt;
        begin = 0;&lt;br /&gt;
        end = stop_0;&lt;br /&gt;
    case 1:&lt;br /&gt;
        begin = start_1;&lt;br /&gt;
        end = stop_1;&lt;br /&gt;
    ...&lt;br /&gt;
    case N:&lt;br /&gt;
        begin = start_n;&lt;br /&gt;
        end = M_0.size();&lt;br /&gt;
&lt;br /&gt;
    //основной цикл&lt;br /&gt;
    for (i = begin; i &amp;lt; end; ++i) {&lt;br /&gt;
        Mi = make_Mi(M&#039;i-1);&lt;br /&gt;
        M&#039;i = make_M&#039;i(Mi);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //сохранение результата (вывод автоморфизмов)&lt;br /&gt;
    final_automorphism(M&#039;i);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Сложность всего алгоритма представляет собой сумму сложностей вычисления &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Количество элементов в каждом множестве (с вероятностью близкой к единице):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |M&#039;_{k}| \thickapprox \frac{n!}{(n-k-2)!~2^{(k)^2}} \thickapprox \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Можно оценить: &amp;lt;math&amp;gt; |M&#039;_k| = \frac{n(n-1)\ldots(n-k-1)}{2^{(k)^2}} \le \frac{n^{k}}{2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Количество операций сравнения для подсчета всех множеств:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \sum_{k = 1}^{n} \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} \times (n - k)(2k + 1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оценка (были учтены точка стабилизации и точка максимума последовательности множеств):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; n \times \frac{n^{(5/7) \ln(n)}}{2^{((5/7)\ln(n))^2}}\times n(2(\frac{5}{7}\ln(n)) + 1)\times \log_2(n) = O(n^2(\frac{e}{2})^{\ln(n)^2} \ln(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сложность экспоненциальная.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[глоссарий#Граф алгоритма|Граф алгоритма]]&amp;lt;ref&amp;gt;Воеводин В.В.  Математические основы параллельных вычислений// М.: Изд. Моск. ун-та, 1991. 345 с.&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Воеводин В.В., Воеводин Вл.В. Параллельные вычисления. – СПб.: БХВ - Петербург, 2002. – 608 с.&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Фролов А.В.. Принципы построения и описание языка Сигма. Препринт ОВМ АН N 236. М.: ОВМ АН СССР, 1989.&amp;lt;/ref&amp;gt; для &amp;lt;math&amp;gt;n = 4&amp;lt;/math&amp;gt; (при росте &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; изменения графа будут аналогичны, а отклонения не существенны:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:Граф_автоморфизмов.png|thumb|center|1100px|Рисунок 1. Граф алгоритма. CHECK - проверка по критерию.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
При больших &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; ширина ярусов будет расти до яруса под номером &amp;lt;math&amp;gt;\lceil\frac{5}{7}\log_2(n) - 1\rceil&amp;lt;/math&amp;gt;, после начнет убывать.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для поиска автоморфизмов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; итерационным алгоритмом в параллельном варианте требуется выполнить:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; ярусов сравнений (количество сравнений &amp;lt;math&amp;gt; k = 1 \ldots n: \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} \times (n - k)(2k + 1) &amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте ЯПФ, таким образом, алогоритм имеет сложностью &amp;lt;math&amp;gt; O(n) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
При классификации по ширине ЯПФ его сложность &amp;lt;math&amp;gt; O(n(\frac{e}{2})^{\ln(n)^2} \ln(n))) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;) графа .&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; – любые, но в данной статье рассматриваются из множества {0,1}.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;, представленное матрицей (элементы &amp;lt;math&amp;gt;g^s_n&amp;lt;/math&amp;gt; - полученные автоморфизмы).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;l \times n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt; количество всевозможных автоморфизмов для данного графа.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [4 : 128] с шагом &amp;lt;math&amp;gt; 2^n&amp;lt;/math&amp;gt; (точки отображены с шагом 4, усреднив результаты);&lt;br /&gt;
*	размер матрицы [300 : 1000].&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон алгоритма:&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0,11%;&lt;br /&gt;
*	максимальная эффективность реализации 2,65%.&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики производительности и эффективности выбранной реализации поиска автоморфизмов графов в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:.png|thumb|center|700px|Рисунок 1. Параллельная реализация алгоритма поиска автоморфизмов. Изменение производительности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
[[file:.png|thumb|center|700px|Рисунок 2. Параллельная реализация алгоритма поиска автоморфизмов. Изменение эффективности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
&lt;br /&gt;
Оценки масштабируемости выбранной реализации:&lt;br /&gt;
*	По числу процессов: -0,000593. При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска уменьшается, однако в целом уменьшение не очень быстрое. Малая интенсивность изменения объясняется крайне низкой общей эффективностью работы приложения с максимумом в 2,65%, и значение эффективности на рассмотренной области значений быстро доходит до десятых долей процента. Это свидетельствует о том, что на большей части области значений нет интенсивного снижения эффективности. Это объясняется также тем, что с ростом [[Глоссарий#Вычислительная сложность|вычислительной сложности]] падение эффективности становится не таким быстрым. Уменьшение эффективности на рассмотренной области работы параллельной программы объясняется быстрым ростом накладных расходов на организацию параллельного выполнения. С ростом вычислительной сложности задачи эффективность снижается так же быстро, но при больших значениях числа процессов. Это подтверждает предположение о том, что накладные расходы начинают сильно превалировать над вычислениями.&lt;br /&gt;
*	По размеру задачи: 0,06017. При увеличении размера задачи эффективность возрастает. Эффективность возрастает тем быстрее, чем большее число процессов используется для выполнения. Это подтверждает предположение о том, что размер задачи сильно влияет на эффективность выполнения приложения. Оценка показывает, что с ростом размера задачи эффективность на рассмотренной области значений параметров запуска сильно увеличивается. Также, учитывая разницу максимальной и минимальной эффективности в 2,5%, можно сделать вывод, что рост эффективности при увеличении размера задачи наблюдается на большей части рассмотренной области значений.&lt;br /&gt;
*	По двум направлениям: 0,000403. При рассмотрении увеличения как вычислительной сложности, так и числа процессов на всей рассмотренной области значений эффективность увеличивается, однако скорость увеличения эффективности небольшая. В совокупности с тем фактом, что разница между максимальной и минимальной эффективностью на рассмотренной области значений параметров небольшая, эффективность с увеличением масштабов возрастает, но медленно и с небольшими перепадами.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Информация о реализациях данного алгоритма не найдена. При анализе алгоритма было разработано 2 программы: &amp;lt;br/&amp;gt; &lt;br /&gt;
&lt;br /&gt;
:1) приложение с графическим интерфейсом, написанное на &#039;&#039;&#039;Qt&#039;&#039;&#039;&lt;br /&gt;
:::* не поддерживает распараллеливание&lt;br /&gt;
:::* справляется с графами размера до 500 вершин&lt;br /&gt;
:::* удобный анализ графов&lt;br /&gt;
:::* помимо нахождения автоморфизмов, решает задачи изоморфизма и гомоморфизма графов&lt;br /&gt;
:2) программа на языки &#039;&#039;&#039;C++&#039;&#039;&#039; с поддержкой &#039;&#039;&#039;OpenMPI&#039;&#039;&#039;&lt;br /&gt;
:::* поддерживает распараллеливание средствами OpenMPI&lt;br /&gt;
:::* помимо нахождения автоморфизмов, сохраняет много информации для анализа графов с большим количеством вершин&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25072</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25072"/>
		<updated>2017-12-10T16:05:48Z</updated>

		<summary type="html">&lt;p&gt;Full: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&amp;lt;br&amp;gt;&lt;br /&gt;
Автор статьи: Ефремов С.С. (группа 419)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром алгоритма является последовательность множеств  &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;. Вычисляется на основе соответствующих &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt;. Построение &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt; занимает несущественную часть времени.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Каждое множество &amp;lt;math&amp;gt; M_i (i = 2 \ldots n) &amp;lt;/math&amp;gt; вычисляется из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; путем добавления в каждый элемент (частичная перестановка, представленная вектором целых чисел) из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; всех возможных оставшихся чисел, которых нет в соответствующем элементе.&lt;br /&gt;
&lt;br /&gt;
Для этого удобно использовать 2 не фиксированных по количеству строк двумерных массива размера t на n (t может увеличиваться), хранящих частичные отображения, такого вида: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
a_{11} &amp;amp; a_{12} &amp;amp; \ldots &amp;amp;a_{1i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
a_{21} &amp;amp; a_{22} &amp;amp; \ldots &amp;amp;a_{2i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
a_{k1} &amp;amp; a_{k2} &amp;amp; \ldots &amp;amp;a_{ki} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
? - эти значения не известны и заполняются постепенно.&lt;br /&gt;
&lt;br /&gt;
Один массив для &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt;, другой для вычисления из предыдущего &amp;lt;math&amp;gt; M_i &amp;lt;/math&amp;gt;.&lt;br /&gt;
Из каждой строки множества &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; (первый массив), в соответствие с алгоритмом, получается &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; новых строк длины i, которые записываются во второй массив (расширяется, если нужно).&lt;br /&gt;
&lt;br /&gt;
После этого, второй массив копируется в первый и запускается цикл по всем векторам. Вектор исключается из массива, если &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; равен какому-либо числу в данном векторе или вектор с &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; является частичной перестановкой, не удовлетворяющей критерию;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Схема реализации представлена на языке C++&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#define GRAPH_SIZE 300&lt;br /&gt;
#define ROW_ARR_SIZE 10000 &lt;br /&gt;
#define COL_ARR_SIZE GRAPH_SIZE&lt;br /&gt;
&lt;br /&gt;
const int N = GRAPH_SIZE;&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; Mi(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; M&#039;i(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
unsigned char **matrix;&lt;br /&gt;
&lt;br /&gt;
struct_M&#039;i make_M&#039;i(Mi) {&lt;br /&gt;
    struct_M&#039;i M&#039;i;&lt;br /&gt;
    for (auto x: Mi) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
            if (check_h(x) &amp;amp;&amp;amp; !eq(x, i)) {&lt;br /&gt;
                M&#039;i.push_back(x.add(i));&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return M&#039;i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct_Mi make_Mi(M&#039;i) {&lt;br /&gt;
    struct_Mi Mi;&lt;br /&gt;
    for (auto x: M&#039;i) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
           Mi.push_back(x.add(i));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return Mi;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    //заполнение матрицы смежности&lt;br /&gt;
    init_automorphisms(matrix);&lt;br /&gt;
&lt;br /&gt;
    //распараллеливание&lt;br /&gt;
    switch(process) {&lt;br /&gt;
    case 0:&lt;br /&gt;
        begin = 0;&lt;br /&gt;
        end = stop_0;&lt;br /&gt;
    case 1:&lt;br /&gt;
        begin = start_1;&lt;br /&gt;
        end = stop_1;&lt;br /&gt;
    ...&lt;br /&gt;
    case N:&lt;br /&gt;
        begin = start_n;&lt;br /&gt;
        end = M_0.size();&lt;br /&gt;
&lt;br /&gt;
    //основной цикл&lt;br /&gt;
    for (i = begin; i &amp;lt; end; ++i) {&lt;br /&gt;
        Mi = make_Mi(M&#039;i-1);&lt;br /&gt;
        M&#039;i = make_M&#039;i(Mi);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //сохранение результата (вывод автоморфизмов)&lt;br /&gt;
    final_automorphism(M&#039;i);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Сложность всего алгоритма представляет собой сумму сложностей вычисления &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Количество элементов в каждом множестве (с вероятностью близкой к единице):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |M&#039;_{k}| \thickapprox \frac{n!}{(n-k-2)!~2^{(k)^2}} \thickapprox \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Можно оценить: &amp;lt;math&amp;gt; |M&#039;_k| = \frac{n(n-1)\ldots(n-k-1)}{2^{(k)^2}} \le \frac{n^{k}}{2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Количество операций сравнения для подсчета всех множеств:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \sum_{k = 1}^{n} \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} \times (n - k)(2k + 1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оценка (были учтены точка стабилизации и точка максимума последовательности множеств):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; n \times \frac{n^{(5/7) \ln(n)}}{2^{((5/7)\ln(n))^2}}\times n(2(\frac{5}{7}\ln(n)) + 1)\times \log_2(n) = O(n^2(\frac{e}{2})^{\ln(n)^2} \ln(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сложность экспоненциальная.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[глоссарий#Граф алгоритма|Граф алгоритма]]&amp;lt;ref&amp;gt;Воеводин В.В.  Математические основы параллельных вычислений// М.: Изд. Моск. ун-та, 1991. 345 с.&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Воеводин В.В., Воеводин Вл.В. Параллельные вычисления. – СПб.: БХВ - Петербург, 2002. – 608 с.&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Фролов А.В.. Принципы построения и описание языка Сигма. Препринт ОВМ АН N 236. М.: ОВМ АН СССР, 1989.&amp;lt;/ref&amp;gt; для &amp;lt;math&amp;gt;n = 4&amp;lt;/math&amp;gt; (при росте &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; изменения графа будут аналогичны, а отклонения не существенны:&lt;br /&gt;
&lt;br /&gt;
[[file:Граф_автоморфизмов.png|thumb|center|1100px|Рисунок 1. Граф алгоритма. CHECK - проверка по критерию.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
При больших &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; ширина ярусов будет расти до яруса под номером &amp;lt;math&amp;gt;\lceil\frac{5}{7}\log_2(n)\rceil&amp;lt;/math&amp;gt;, после начнет убывать.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для поиска автоморфизмов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; итерационным алгоритмом в параллельном варианте требуется выполнить:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; ярусов сравнений (количество сравнений &amp;lt;math&amp;gt; k = 1 \ldots n: \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} \times (n - k)(2k + 1) &amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте ЯПФ, таким образом, алогоритм имеет сложностью &amp;lt;math&amp;gt; O(n) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
При классификации по ширине ЯПФ его сложность &amp;lt;math&amp;gt; O(n(\frac{e}{2})^{\ln(n)^2} \ln(n))) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;) графа .&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; – любые, но в данной статье рассматриваются из множества {0,1}.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;, представленное матрицей (элементы &amp;lt;math&amp;gt;g^s_n&amp;lt;/math&amp;gt; - полученные автоморфизмы).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;l \times n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt; количество всевозможных автоморфизмов для данного графа.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [4 : 128] с шагом &amp;lt;math&amp;gt; 2^n&amp;lt;/math&amp;gt; (точки отображены с шагом 4, усреднив результаты);&lt;br /&gt;
*	размер матрицы [300 : 1000].&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон алгоритма:&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0,11%;&lt;br /&gt;
*	максимальная эффективность реализации 2,65%.&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики производительности и эффективности выбранной реализации поиска автоморфизмов графов в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:.png|thumb|center|700px|Рисунок 1. Параллельная реализация алгоритма поиска автоморфизмов. Изменение производительности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
[[file:.png|thumb|center|700px|Рисунок 2. Параллельная реализация алгоритма поиска автоморфизмов. Изменение эффективности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
&lt;br /&gt;
Оценки масштабируемости выбранной реализации:&lt;br /&gt;
*	По числу процессов: -0,000593. При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска уменьшается, однако в целом уменьшение не очень быстрое. Малая интенсивность изменения объясняется крайне низкой общей эффективностью работы приложения с максимумом в 2,65%, и значение эффективности на рассмотренной области значений быстро доходит до десятых долей процента. Это свидетельствует о том, что на большей части области значений нет интенсивного снижения эффективности. Это объясняется также тем, что с ростом [[Глоссарий#Вычислительная сложность|вычислительной сложности]] падение эффективности становится не таким быстрым. Уменьшение эффективности на рассмотренной области работы параллельной программы объясняется быстрым ростом накладных расходов на организацию параллельного выполнения. С ростом вычислительной сложности задачи эффективность снижается так же быстро, но при больших значениях числа процессов. Это подтверждает предположение о том, что накладные расходы начинают сильно превалировать над вычислениями.&lt;br /&gt;
*	По размеру задачи: 0,06017. При увеличении размера задачи эффективность возрастает. Эффективность возрастает тем быстрее, чем большее число процессов используется для выполнения. Это подтверждает предположение о том, что размер задачи сильно влияет на эффективность выполнения приложения. Оценка показывает, что с ростом размера задачи эффективность на рассмотренной области значений параметров запуска сильно увеличивается. Также, учитывая разницу максимальной и минимальной эффективности в 2,5%, можно сделать вывод, что рост эффективности при увеличении размера задачи наблюдается на большей части рассмотренной области значений.&lt;br /&gt;
*	По двум направлениям: 0,000403. При рассмотрении увеличения как вычислительной сложности, так и числа процессов на всей рассмотренной области значений эффективность увеличивается, однако скорость увеличения эффективности небольшая. В совокупности с тем фактом, что разница между максимальной и минимальной эффективностью на рассмотренной области значений параметров небольшая, эффективность с увеличением масштабов возрастает, но медленно и с небольшими перепадами.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Информация о реализациях данного алгоритма не найдена. При анализе алгоритма было разработано 2 программы: &amp;lt;br/&amp;gt; &lt;br /&gt;
&lt;br /&gt;
:1) приложение с графическим интерфейсом, написанное на &#039;&#039;&#039;Qt&#039;&#039;&#039;&lt;br /&gt;
:::* не поддерживает распараллеливание&lt;br /&gt;
:::* справляется с графами размера до 500 вершин&lt;br /&gt;
:::* удобный анализ графов&lt;br /&gt;
:::* помимо нахождения автоморфизмов, решает задачи изоморфизма и гомоморфизма графов&lt;br /&gt;
:2) программа на языки &#039;&#039;&#039;C++&#039;&#039;&#039; с поддержкой &#039;&#039;&#039;OpenMPI&#039;&#039;&#039;&lt;br /&gt;
:::* поддерживает распараллеливание средствами OpenMPI&lt;br /&gt;
:::* помимо нахождения автоморфизмов, сохраняет много информации для анализа графов с большим количеством вершин&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25071</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25071"/>
		<updated>2017-12-10T15:32:39Z</updated>

		<summary type="html">&lt;p&gt;Full: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&amp;lt;br&amp;gt;&lt;br /&gt;
Автор статьи: Ефремов С.С. (группа 419)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром алгоритма является последовательность множеств  &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;. Вычисляется на основе соответствующих &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt;. Построение &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt; занимает несущественную часть времени.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Каждое множество &amp;lt;math&amp;gt; M_i (i = 2 \ldots n) &amp;lt;/math&amp;gt; вычисляется из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; путем добавления в каждый элемент (частичная перестановка, представленная вектором целых чисел) из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; всех возможных оставшихся чисел, которых нет в соответствующем элементе.&lt;br /&gt;
&lt;br /&gt;
Для этого удобно использовать 2 не фиксированных по количеству строк двумерных массива размера t на n (t может увеличиваться), хранящих частичные отображения, такого вида: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
a_{11} &amp;amp; a_{12} &amp;amp; \ldots &amp;amp;a_{1i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
a_{21} &amp;amp; a_{22} &amp;amp; \ldots &amp;amp;a_{2i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
a_{k1} &amp;amp; a_{k2} &amp;amp; \ldots &amp;amp;a_{ki} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
? - эти значения не известны и заполняются постепенно.&lt;br /&gt;
&lt;br /&gt;
Один массив для &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt;, другой для вычисления из предыдущего &amp;lt;math&amp;gt; M_i &amp;lt;/math&amp;gt;.&lt;br /&gt;
Из каждой строки множества &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; (первый массив), в соответствие с алгоритмом, получается &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; новых строк длины i, которые записываются во второй массив (расширяется, если нужно).&lt;br /&gt;
&lt;br /&gt;
После этого, второй массив копируется в первый и запускается цикл по всем векторам. Вектор исключается из массива, если &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; равен какому-либо числу в данном векторе или вектор с &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; является частичной перестановкой, не удовлетворяющей критерию;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Схема реализации представлена на языке C++&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#define GRAPH_SIZE 300&lt;br /&gt;
#define ROW_ARR_SIZE 10000 &lt;br /&gt;
#define COL_ARR_SIZE GRAPH_SIZE&lt;br /&gt;
&lt;br /&gt;
const int N = GRAPH_SIZE;&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; Mi(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; M&#039;i(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
unsigned char **matrix;&lt;br /&gt;
&lt;br /&gt;
struct_M&#039;i make_M&#039;i(Mi) {&lt;br /&gt;
    struct_M&#039;i M&#039;i;&lt;br /&gt;
    for (auto x: Mi) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
            if (check_h(x) &amp;amp;&amp;amp; !eq(x, i)) {&lt;br /&gt;
                M&#039;i.push_back(x.add(i));&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return M&#039;i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct_Mi make_Mi(M&#039;i) {&lt;br /&gt;
    struct_Mi Mi;&lt;br /&gt;
    for (auto x: M&#039;i) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
           Mi.push_back(x.add(i));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return Mi;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    //заполнение матрицы смежности&lt;br /&gt;
    init_automorphisms(matrix);&lt;br /&gt;
&lt;br /&gt;
    //распараллеливание&lt;br /&gt;
    switch(process) {&lt;br /&gt;
    case 0:&lt;br /&gt;
        begin = 0;&lt;br /&gt;
        end = stop_0;&lt;br /&gt;
    case 1:&lt;br /&gt;
        begin = start_1;&lt;br /&gt;
        end = stop_1;&lt;br /&gt;
    ...&lt;br /&gt;
    case N:&lt;br /&gt;
        begin = start_n;&lt;br /&gt;
        end = M_0.size();&lt;br /&gt;
&lt;br /&gt;
    //основной цикл&lt;br /&gt;
    for (i = begin; i &amp;lt; end; ++i) {&lt;br /&gt;
        Mi = make_Mi(M&#039;i-1);&lt;br /&gt;
        M&#039;i = make_M&#039;i(Mi);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //сохранение результата (вывод автоморфизмов)&lt;br /&gt;
    final_automorphism(M&#039;i);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Сложность всего алгоритма представляет собой сумму сложностей вычисления &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Количество элементов в каждом множестве (с вероятностью близкой к единице):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |M&#039;_{k}| \thickapprox \frac{n!}{(n-k-2)!~2^{(k)^2}} \thickapprox \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Можно оценить: &amp;lt;math&amp;gt; |M&#039;_k| = \frac{n(n-1)\ldots(n-k-1)}{2^{(k)^2}} \le \frac{n^{k}}{2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Количество операций сравнения для подсчета всех множеств:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \sum_{k = 1}^{n} \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} \times (n - k)(2k + 1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оценка (были учтены точка стабилизации и точка максимума последовательности множеств):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; n \times \frac{n^{(5/7) \ln(n)}}{2^{((5/7)\ln(n))^2}}\times n(2(\frac{5}{7}\ln(n)) + 1)\times \log_2(n) = O(n^2(\frac{e}{2})^{\ln(n)^2} \ln(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сложность экспоненциальная.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[глоссарий#Граф алгоритма|Граф алгоритма]]&amp;lt;ref&amp;gt;Воеводин В.В.  Математические основы параллельных вычислений// М.: Изд. Моск. ун-та, 1991. 345 с.&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Воеводин В.В., Воеводин Вл.В. Параллельные вычисления. – СПб.: БХВ - Петербург, 2002. – 608 с.&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Фролов А.В.. Принципы построения и описание языка Сигма. Препринт ОВМ АН N 236. М.: ОВМ АН СССР, 1989.&amp;lt;/ref&amp;gt; для &amp;lt;math&amp;gt;n = 4&amp;lt;/math&amp;gt; (при росте &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; изменения графа будут аналогичны, а отклонения не существенны:&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для поиска автоморфизмов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; итерационным алгоритмом в параллельном варианте требуется выполнить:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; ярусов сравнений (количество сравнений &amp;lt;math&amp;gt; k = 1 \ldots n: \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} \times (n - k)(2k + 1) &amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте ЯПФ, таким образом, алогоритм имеет сложностью &amp;lt;math&amp;gt; O(n) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
При классификации по ширине ЯПФ его сложность &amp;lt;math&amp;gt; O(n(\frac{e}{2})^{\ln(n)^2} \ln(n))) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;) графа .&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; – любые, но в данной статье рассматриваются из множества {0,1}.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;, представленное матрицей (элементы &amp;lt;math&amp;gt;g^s_n&amp;lt;/math&amp;gt; - полученные автоморфизмы).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;l \times n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt; количество всевозможных автоморфизмов для данного графа.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [4 : 128] с шагом &amp;lt;math&amp;gt; 2^n&amp;lt;/math&amp;gt; (точки отображены с шагом 4, усреднив результаты);&lt;br /&gt;
*	размер матрицы [300 : 1000].&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон алгоритма:&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0,11%;&lt;br /&gt;
*	максимальная эффективность реализации 2,65%.&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики производительности и эффективности выбранной реализации поиска автоморфизмов графов в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:.png|thumb|center|700px|Рисунок 1. Параллельная реализация алгоритма поиска автоморфизмов. Изменение производительности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
[[file:.png|thumb|center|700px|Рисунок 2. Параллельная реализация алгоритма поиска автоморфизмов. Изменение эффективности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
&lt;br /&gt;
Оценки масштабируемости выбранной реализации:&lt;br /&gt;
*	По числу процессов: -0,000593. При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска уменьшается, однако в целом уменьшение не очень быстрое. Малая интенсивность изменения объясняется крайне низкой общей эффективностью работы приложения с максимумом в 2,65%, и значение эффективности на рассмотренной области значений быстро доходит до десятых долей процента. Это свидетельствует о том, что на большей части области значений нет интенсивного снижения эффективности. Это объясняется также тем, что с ростом [[Глоссарий#Вычислительная сложность|вычислительной сложности]] падение эффективности становится не таким быстрым. Уменьшение эффективности на рассмотренной области работы параллельной программы объясняется быстрым ростом накладных расходов на организацию параллельного выполнения. С ростом вычислительной сложности задачи эффективность снижается так же быстро, но при больших значениях числа процессов. Это подтверждает предположение о том, что накладные расходы начинают сильно превалировать над вычислениями.&lt;br /&gt;
*	По размеру задачи: 0,06017. При увеличении размера задачи эффективность возрастает. Эффективность возрастает тем быстрее, чем большее число процессов используется для выполнения. Это подтверждает предположение о том, что размер задачи сильно влияет на эффективность выполнения приложения. Оценка показывает, что с ростом размера задачи эффективность на рассмотренной области значений параметров запуска сильно увеличивается. Также, учитывая разницу максимальной и минимальной эффективности в 2,5%, можно сделать вывод, что рост эффективности при увеличении размера задачи наблюдается на большей части рассмотренной области значений.&lt;br /&gt;
*	По двум направлениям: 0,000403. При рассмотрении увеличения как вычислительной сложности, так и числа процессов на всей рассмотренной области значений эффективность увеличивается, однако скорость увеличения эффективности небольшая. В совокупности с тем фактом, что разница между максимальной и минимальной эффективностью на рассмотренной области значений параметров небольшая, эффективность с увеличением масштабов возрастает, но медленно и с небольшими перепадами.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Информация о реализациях данного алгоритма не найдена. При анализе алгоритма было разработано 2 программы: &amp;lt;br/&amp;gt; &lt;br /&gt;
&lt;br /&gt;
:1) приложение с графическим интерфейсом, написанное на &#039;&#039;&#039;Qt&#039;&#039;&#039;&lt;br /&gt;
:::* не поддерживает распараллеливание&lt;br /&gt;
:::* справляется с графами размера до 500 вершин&lt;br /&gt;
:::* удобный анализ графов&lt;br /&gt;
:::* помимо нахождения автоморфизмов, решает задачи изоморфизма и гомоморфизма графов&lt;br /&gt;
:2) программа на языки &#039;&#039;&#039;C++&#039;&#039;&#039; с поддержкой &#039;&#039;&#039;OpenMPI&#039;&#039;&#039;&lt;br /&gt;
:::* поддерживает распараллеливание средствами OpenMPI&lt;br /&gt;
:::* помимо нахождения автоморфизмов, сохраняет много информации для анализа графов с большим количеством вершин&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25070</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25070"/>
		<updated>2017-12-10T15:31:59Z</updated>

		<summary type="html">&lt;p&gt;Full: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&amp;lt;br&amp;gt;&lt;br /&gt;
Автор статьи: Ефремов С.С. (группа 419)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром алгоритма является последовательность множеств  &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;. Вычисляется на основе соответствующих &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt;. Построение &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt; занимает несущественную часть времени.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Каждое множество &amp;lt;math&amp;gt; M_i (i = 2 \ldots n) &amp;lt;/math&amp;gt; вычисляется из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; путем добавления в каждый элемент (частичная перестановка, представленная вектором целых чисел) из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; всех возможных оставшихся чисел, которых нет в соответствующем элементе.&lt;br /&gt;
&lt;br /&gt;
Для этого удобно использовать 2 не фиксированных по количеству строк двумерных массива размера t на n (t может увеличиваться), хранящих частичные отображения, такого вида: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
a_{11} &amp;amp; a_{12} &amp;amp; \ldots &amp;amp;a_{1i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
a_{21} &amp;amp; a_{22} &amp;amp; \ldots &amp;amp;a_{2i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
a_{k1} &amp;amp; a_{k2} &amp;amp; \ldots &amp;amp;a_{ki} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
? - эти значения не известны и заполняются постепенно.&lt;br /&gt;
&lt;br /&gt;
Один массив для &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt;, другой для вычисления из предыдущего &amp;lt;math&amp;gt; M_i &amp;lt;/math&amp;gt;.&lt;br /&gt;
Из каждой строки множества &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; (первый массив), в соответствие с алгоритмом, получается &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; новых строк длины i, которые записываются во второй массив (расширяется, если нужно).&lt;br /&gt;
&lt;br /&gt;
После этого, второй массив копируется в первый и запускается цикл по всем векторам. Вектор исключается из массива, если &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; равен какому-либо числу в данном векторе или вектор с &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; является частичной перестановкой, не удовлетворяющей критерию;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Схема реализации представлена на языке C++&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#define GRAPH_SIZE 300&lt;br /&gt;
#define ROW_ARR_SIZE 10000 &lt;br /&gt;
#define COL_ARR_SIZE GRAPH_SIZE&lt;br /&gt;
&lt;br /&gt;
const int N = GRAPH_SIZE;&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; Mi(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; M&#039;i(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
unsigned char **matrix;&lt;br /&gt;
&lt;br /&gt;
struct_M&#039;i make_M&#039;i(Mi) {&lt;br /&gt;
    struct_M&#039;i M&#039;i;&lt;br /&gt;
    for (auto x: Mi) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
            if (check_h(x) &amp;amp;&amp;amp; !eq(x, i)) {&lt;br /&gt;
                M&#039;i.push_back(x.add(i));&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return M&#039;i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct_Mi make_Mi(M&#039;i) {&lt;br /&gt;
    struct_Mi Mi;&lt;br /&gt;
    for (auto x: M&#039;i) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
           Mi.push_back(x.add(i));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return Mi;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    //заполнение матрицы смежности&lt;br /&gt;
    init_automorphisms(matrix);&lt;br /&gt;
&lt;br /&gt;
    //распараллеливание&lt;br /&gt;
    switch(process) {&lt;br /&gt;
    case 0:&lt;br /&gt;
        begin = 0;&lt;br /&gt;
        end = stop_0;&lt;br /&gt;
    case 1:&lt;br /&gt;
        begin = start_1;&lt;br /&gt;
        end = stop_1;&lt;br /&gt;
    ...&lt;br /&gt;
    case N:&lt;br /&gt;
        begin = start_n;&lt;br /&gt;
        end = M_0.size();&lt;br /&gt;
&lt;br /&gt;
    //основной цикл&lt;br /&gt;
    for (i = begin; i &amp;lt; end; ++i) {&lt;br /&gt;
        Mi = make_Mi(M&#039;i-1);&lt;br /&gt;
        M&#039;i = make_M&#039;i(Mi);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //сохранение результата (вывод автоморфизмов)&lt;br /&gt;
    final_automorphism(M&#039;i);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Сложность всего алгоритма представляет собой сумму сложностей вычисления &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Количество элементов в каждом множестве (с вероятностью близкой к единице):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |M&#039;_{k}| \thickapprox \frac{n!}{(n-k-2)!~2^{(k)^2}} \thickapprox \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Можно оценить: &amp;lt;math&amp;gt; |M&#039;_k| = \frac{n(n-1)\ldots(n-k-1)}{2^{(k)^2}} \le \frac{n^{k}}{2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Количество операций сравнения для подсчета всех множеств:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \sum_{k = 1}^{n} \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} \times (n - k)(2k + 1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оценка (были учтены точка стабилизации и точка максимума последовательности множеств):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; n \times \frac{n^{(5/7) \ln(n)}}{2^{((5/7)\ln(n))^2}}\times n(2(\frac{5}{7}\ln(n)) + 1)\times \log_2(n) = O(n^2(\frac{e}{2})^{\ln(n)^2} \ln(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сложность экспоненциальная.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[глоссарий#Граф алгоритма|Граф алгоритма]]&amp;lt;ref&amp;gt;Воеводин В.В.  Математические основы параллельных вычислений// М.: Изд. Моск. ун-та, 1991. 345 с.&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Воеводин В.В., Воеводин Вл.В. Параллельные вычисления. – СПб.: БХВ - Петербург, 2002. – 608 с.&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Фролов А.В.. Принципы построения и описание языка Сигма. Препринт ОВМ АН N 236. М.: ОВМ АН СССР, 1989.&amp;lt;/ref&amp;gt; при &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; = 4 (при росте &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; изменения графа будут аналогичны, а отклонения не существенны:&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для поиска автоморфизмов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; итерационным алгоритмом в параллельном варианте требуется выполнить:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; ярусов сравнений (количество сравнений &amp;lt;math&amp;gt; k = 1 \ldots n: \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} \times (n - k)(2k + 1) &amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте ЯПФ, таким образом, алогоритм имеет сложностью &amp;lt;math&amp;gt; O(n) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
При классификации по ширине ЯПФ его сложность &amp;lt;math&amp;gt; O(n(\frac{e}{2})^{\ln(n)^2} \ln(n))) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;) графа .&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; – любые, но в данной статье рассматриваются из множества {0,1}.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;, представленное матрицей (элементы &amp;lt;math&amp;gt;g^s_n&amp;lt;/math&amp;gt; - полученные автоморфизмы).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;l \times n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt; количество всевозможных автоморфизмов для данного графа.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [4 : 128] с шагом &amp;lt;math&amp;gt; 2^n&amp;lt;/math&amp;gt; (точки отображены с шагом 4, усреднив результаты);&lt;br /&gt;
*	размер матрицы [300 : 1000].&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон алгоритма:&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0,11%;&lt;br /&gt;
*	максимальная эффективность реализации 2,65%.&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики производительности и эффективности выбранной реализации поиска автоморфизмов графов в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:.png|thumb|center|700px|Рисунок 1. Параллельная реализация алгоритма поиска автоморфизмов. Изменение производительности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
[[file:.png|thumb|center|700px|Рисунок 2. Параллельная реализация алгоритма поиска автоморфизмов. Изменение эффективности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
&lt;br /&gt;
Оценки масштабируемости выбранной реализации:&lt;br /&gt;
*	По числу процессов: -0,000593. При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска уменьшается, однако в целом уменьшение не очень быстрое. Малая интенсивность изменения объясняется крайне низкой общей эффективностью работы приложения с максимумом в 2,65%, и значение эффективности на рассмотренной области значений быстро доходит до десятых долей процента. Это свидетельствует о том, что на большей части области значений нет интенсивного снижения эффективности. Это объясняется также тем, что с ростом [[Глоссарий#Вычислительная сложность|вычислительной сложности]] падение эффективности становится не таким быстрым. Уменьшение эффективности на рассмотренной области работы параллельной программы объясняется быстрым ростом накладных расходов на организацию параллельного выполнения. С ростом вычислительной сложности задачи эффективность снижается так же быстро, но при больших значениях числа процессов. Это подтверждает предположение о том, что накладные расходы начинают сильно превалировать над вычислениями.&lt;br /&gt;
*	По размеру задачи: 0,06017. При увеличении размера задачи эффективность возрастает. Эффективность возрастает тем быстрее, чем большее число процессов используется для выполнения. Это подтверждает предположение о том, что размер задачи сильно влияет на эффективность выполнения приложения. Оценка показывает, что с ростом размера задачи эффективность на рассмотренной области значений параметров запуска сильно увеличивается. Также, учитывая разницу максимальной и минимальной эффективности в 2,5%, можно сделать вывод, что рост эффективности при увеличении размера задачи наблюдается на большей части рассмотренной области значений.&lt;br /&gt;
*	По двум направлениям: 0,000403. При рассмотрении увеличения как вычислительной сложности, так и числа процессов на всей рассмотренной области значений эффективность увеличивается, однако скорость увеличения эффективности небольшая. В совокупности с тем фактом, что разница между максимальной и минимальной эффективностью на рассмотренной области значений параметров небольшая, эффективность с увеличением масштабов возрастает, но медленно и с небольшими перепадами.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Информация о реализациях данного алгоритма не найдена. При анализе алгоритма было разработано 2 программы: &amp;lt;br/&amp;gt; &lt;br /&gt;
&lt;br /&gt;
:1) приложение с графическим интерфейсом, написанное на &#039;&#039;&#039;Qt&#039;&#039;&#039;&lt;br /&gt;
:::* не поддерживает распараллеливание&lt;br /&gt;
:::* справляется с графами размера до 500 вершин&lt;br /&gt;
:::* удобный анализ графов&lt;br /&gt;
:::* помимо нахождения автоморфизмов, решает задачи изоморфизма и гомоморфизма графов&lt;br /&gt;
:2) программа на языки &#039;&#039;&#039;C++&#039;&#039;&#039; с поддержкой &#039;&#039;&#039;OpenMPI&#039;&#039;&#039;&lt;br /&gt;
:::* поддерживает распараллеливание средствами OpenMPI&lt;br /&gt;
:::* помимо нахождения автоморфизмов, сохраняет много информации для анализа графов с большим количеством вершин&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25069</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25069"/>
		<updated>2017-12-10T15:31:22Z</updated>

		<summary type="html">&lt;p&gt;Full: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&amp;lt;br&amp;gt;&lt;br /&gt;
Автор статьи: Ефремов С.С. (группа 419)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром алгоритма является последовательность множеств  &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;. Вычисляется на основе соответствующих &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt;. Построение &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt; занимает несущественную часть времени.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Каждое множество &amp;lt;math&amp;gt; M_i (i = 2 \ldots n) &amp;lt;/math&amp;gt; вычисляется из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; путем добавления в каждый элемент (частичная перестановка, представленная вектором целых чисел) из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; всех возможных оставшихся чисел, которых нет в соответствующем элементе.&lt;br /&gt;
&lt;br /&gt;
Для этого удобно использовать 2 не фиксированных по количеству строк двумерных массива размера t на n (t может увеличиваться), хранящих частичные отображения, такого вида: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
a_{11} &amp;amp; a_{12} &amp;amp; \ldots &amp;amp;a_{1i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
a_{21} &amp;amp; a_{22} &amp;amp; \ldots &amp;amp;a_{2i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
a_{k1} &amp;amp; a_{k2} &amp;amp; \ldots &amp;amp;a_{ki} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
? - эти значения не известны и заполняются постепенно.&lt;br /&gt;
&lt;br /&gt;
Один массив для &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt;, другой для вычисления из предыдущего &amp;lt;math&amp;gt; M_i &amp;lt;/math&amp;gt;.&lt;br /&gt;
Из каждой строки множества &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; (первый массив), в соответствие с алгоритмом, получается &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; новых строк длины i, которые записываются во второй массив (расширяется, если нужно).&lt;br /&gt;
&lt;br /&gt;
После этого, второй массив копируется в первый и запускается цикл по всем векторам. Вектор исключается из массива, если &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; равен какому-либо числу в данном векторе или вектор с &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; является частичной перестановкой, не удовлетворяющей критерию;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Схема реализации представлена на языке C++&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#define GRAPH_SIZE 300&lt;br /&gt;
#define ROW_ARR_SIZE 10000 &lt;br /&gt;
#define COL_ARR_SIZE GRAPH_SIZE&lt;br /&gt;
&lt;br /&gt;
const int N = GRAPH_SIZE;&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; Mi(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; M&#039;i(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
unsigned char **matrix;&lt;br /&gt;
&lt;br /&gt;
struct_M&#039;i make_M&#039;i(Mi) {&lt;br /&gt;
    struct_M&#039;i M&#039;i;&lt;br /&gt;
    for (auto x: Mi) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
            if (check_h(x) &amp;amp;&amp;amp; !eq(x, i)) {&lt;br /&gt;
                M&#039;i.push_back(x.add(i));&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return M&#039;i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct_Mi make_Mi(M&#039;i) {&lt;br /&gt;
    struct_Mi Mi;&lt;br /&gt;
    for (auto x: M&#039;i) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
           Mi.push_back(x.add(i));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return Mi;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    //заполнение матрицы смежности&lt;br /&gt;
    init_automorphisms(matrix);&lt;br /&gt;
&lt;br /&gt;
    //распараллеливание&lt;br /&gt;
    switch(process) {&lt;br /&gt;
    case 0:&lt;br /&gt;
        begin = 0;&lt;br /&gt;
        end = stop_0;&lt;br /&gt;
    case 1:&lt;br /&gt;
        begin = start_1;&lt;br /&gt;
        end = stop_1;&lt;br /&gt;
    ...&lt;br /&gt;
    case N:&lt;br /&gt;
        begin = start_n;&lt;br /&gt;
        end = M_0.size();&lt;br /&gt;
&lt;br /&gt;
    //основной цикл&lt;br /&gt;
    for (i = begin; i &amp;lt; end; ++i) {&lt;br /&gt;
        Mi = make_Mi(M&#039;i-1);&lt;br /&gt;
        M&#039;i = make_M&#039;i(Mi);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //сохранение результата (вывод автоморфизмов)&lt;br /&gt;
    final_automorphism(M&#039;i);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Сложность всего алгоритма представляет собой сумму сложностей вычисления &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Количество элементов в каждом множестве (с вероятностью близкой к единице):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |M&#039;_{k}| \thickapprox \frac{n!}{(n-k-2)!~2^{(k)^2}} \thickapprox \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Можно оценить: &amp;lt;math&amp;gt; |M&#039;_k| = \frac{n(n-1)\ldots(n-k-1)}{2^{(k)^2}} \le \frac{n^{k}}{2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Количество операций сравнения для подсчета всех множеств:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \sum_{k = 1}^{n} \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} \times (n - k)(2k + 1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оценка (были учтены точка стабилизации и точка максимума последовательности множеств):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; n \times \frac{n^{(5/7) \ln(n)}}{2^{((5/7)\ln(n))^2}}\times n(2(\frac{5}{7}\ln(n)) + 1)\times \log_2(n) = O(n^2(\frac{e}{2})^{\ln(n)^2} \ln(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сложность экспоненциальная.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[глоссарий#Граф алгоритма|Граф алгоритма]]&amp;lt;ref&amp;gt;Воеводин В.В.  Математические основы параллельных вычислений// М.: Изд. Моск. ун-та, 1991. 345 с.&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Воеводин В.В., Воеводин Вл.В. Параллельные вычисления. – СПб.: БХВ - Петербург, 2002. – 608 с.&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Фролов А.В.. Принципы построения и описание языка Сигма. Препринт ОВМ АН N 236. М.: ОВМ АН СССР, 1989.&amp;lt;/ref&amp;gt; при &amp;lt;math&amp;gt; n = 4 (при росте &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; изменения графа будут аналогичны, а отклонения не существенны&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для поиска автоморфизмов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; итерационным алгоритмом в параллельном варианте требуется выполнить:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; ярусов сравнений (количество сравнений &amp;lt;math&amp;gt; k = 1 \ldots n: \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} \times (n - k)(2k + 1) &amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте ЯПФ, таким образом, алогоритм имеет сложностью &amp;lt;math&amp;gt; O(n) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
При классификации по ширине ЯПФ его сложность &amp;lt;math&amp;gt; O(n(\frac{e}{2})^{\ln(n)^2} \ln(n))) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;) графа .&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; – любые, но в данной статье рассматриваются из множества {0,1}.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;, представленное матрицей (элементы &amp;lt;math&amp;gt;g^s_n&amp;lt;/math&amp;gt; - полученные автоморфизмы).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;l \times n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt; количество всевозможных автоморфизмов для данного графа.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [4 : 128] с шагом &amp;lt;math&amp;gt; 2^n&amp;lt;/math&amp;gt; (точки отображены с шагом 4, усреднив результаты);&lt;br /&gt;
*	размер матрицы [300 : 1000].&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон алгоритма:&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0,11%;&lt;br /&gt;
*	максимальная эффективность реализации 2,65%.&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики производительности и эффективности выбранной реализации поиска автоморфизмов графов в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:.png|thumb|center|700px|Рисунок 1. Параллельная реализация алгоритма поиска автоморфизмов. Изменение производительности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
[[file:.png|thumb|center|700px|Рисунок 2. Параллельная реализация алгоритма поиска автоморфизмов. Изменение эффективности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
&lt;br /&gt;
Оценки масштабируемости выбранной реализации:&lt;br /&gt;
*	По числу процессов: -0,000593. При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска уменьшается, однако в целом уменьшение не очень быстрое. Малая интенсивность изменения объясняется крайне низкой общей эффективностью работы приложения с максимумом в 2,65%, и значение эффективности на рассмотренной области значений быстро доходит до десятых долей процента. Это свидетельствует о том, что на большей части области значений нет интенсивного снижения эффективности. Это объясняется также тем, что с ростом [[Глоссарий#Вычислительная сложность|вычислительной сложности]] падение эффективности становится не таким быстрым. Уменьшение эффективности на рассмотренной области работы параллельной программы объясняется быстрым ростом накладных расходов на организацию параллельного выполнения. С ростом вычислительной сложности задачи эффективность снижается так же быстро, но при больших значениях числа процессов. Это подтверждает предположение о том, что накладные расходы начинают сильно превалировать над вычислениями.&lt;br /&gt;
*	По размеру задачи: 0,06017. При увеличении размера задачи эффективность возрастает. Эффективность возрастает тем быстрее, чем большее число процессов используется для выполнения. Это подтверждает предположение о том, что размер задачи сильно влияет на эффективность выполнения приложения. Оценка показывает, что с ростом размера задачи эффективность на рассмотренной области значений параметров запуска сильно увеличивается. Также, учитывая разницу максимальной и минимальной эффективности в 2,5%, можно сделать вывод, что рост эффективности при увеличении размера задачи наблюдается на большей части рассмотренной области значений.&lt;br /&gt;
*	По двум направлениям: 0,000403. При рассмотрении увеличения как вычислительной сложности, так и числа процессов на всей рассмотренной области значений эффективность увеличивается, однако скорость увеличения эффективности небольшая. В совокупности с тем фактом, что разница между максимальной и минимальной эффективностью на рассмотренной области значений параметров небольшая, эффективность с увеличением масштабов возрастает, но медленно и с небольшими перепадами.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Информация о реализациях данного алгоритма не найдена. При анализе алгоритма было разработано 2 программы: &amp;lt;br/&amp;gt; &lt;br /&gt;
&lt;br /&gt;
:1) приложение с графическим интерфейсом, написанное на &#039;&#039;&#039;Qt&#039;&#039;&#039;&lt;br /&gt;
:::* не поддерживает распараллеливание&lt;br /&gt;
:::* справляется с графами размера до 500 вершин&lt;br /&gt;
:::* удобный анализ графов&lt;br /&gt;
:::* помимо нахождения автоморфизмов, решает задачи изоморфизма и гомоморфизма графов&lt;br /&gt;
:2) программа на языки &#039;&#039;&#039;C++&#039;&#039;&#039; с поддержкой &#039;&#039;&#039;OpenMPI&#039;&#039;&#039;&lt;br /&gt;
:::* поддерживает распараллеливание средствами OpenMPI&lt;br /&gt;
:::* помимо нахождения автоморфизмов, сохраняет много информации для анализа графов с большим количеством вершин&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25068</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25068"/>
		<updated>2017-12-10T11:51:46Z</updated>

		<summary type="html">&lt;p&gt;Full: /* Входные и выходные данные алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&amp;lt;br&amp;gt;&lt;br /&gt;
Автор статьи: Ефремов С.С. (группа 419)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром алгоритма является последовательность множеств  &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;. Вычисляется на основе соответствующих &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt;. Построение &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt; занимает несущественную часть времени.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Каждое множество &amp;lt;math&amp;gt; M_i (i = 2 \ldots n) &amp;lt;/math&amp;gt; вычисляется из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; путем добавления в каждый элемент (частичная перестановка, представленная вектором целых чисел) из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; всех возможных оставшихся чисел, которых нет в соответствующем элементе.&lt;br /&gt;
&lt;br /&gt;
Для этого удобно использовать 2 не фиксированных по количеству строк двумерных массива размера t на n (t может увеличиваться), хранящих частичные отображения, такого вида: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
a_{11} &amp;amp; a_{12} &amp;amp; \ldots &amp;amp;a_{1i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
a_{21} &amp;amp; a_{22} &amp;amp; \ldots &amp;amp;a_{2i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
a_{k1} &amp;amp; a_{k2} &amp;amp; \ldots &amp;amp;a_{ki} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
? - эти значения не известны и заполняются постепенно.&lt;br /&gt;
&lt;br /&gt;
Один массив для &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt;, другой для вычисления из предыдущего &amp;lt;math&amp;gt; M_i &amp;lt;/math&amp;gt;.&lt;br /&gt;
Из каждой строки множества &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; (первый массив), в соответствие с алгоритмом, получается &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; новых строк длины i, которые записываются во второй массив (расширяется, если нужно).&lt;br /&gt;
&lt;br /&gt;
После этого, второй массив копируется в первый и запускается цикл по всем векторам. Вектор исключается из массива, если &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; равен какому-либо числу в данном векторе или вектор с &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; является частичной перестановкой, не удовлетворяющей критерию;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Схема реализации представлена на языке C++&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#define GRAPH_SIZE 300&lt;br /&gt;
#define ROW_ARR_SIZE 10000 &lt;br /&gt;
#define COL_ARR_SIZE GRAPH_SIZE&lt;br /&gt;
&lt;br /&gt;
const int N = GRAPH_SIZE;&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; Mi(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; M&#039;i(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
unsigned char **matrix;&lt;br /&gt;
&lt;br /&gt;
struct_M&#039;i make_M&#039;i(Mi) {&lt;br /&gt;
    struct_M&#039;i M&#039;i;&lt;br /&gt;
    for (auto x: Mi) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
            if (check_h(x) &amp;amp;&amp;amp; !eq(x, i)) {&lt;br /&gt;
                M&#039;i.push_back(x.add(i));&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return M&#039;i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct_Mi make_Mi(M&#039;i) {&lt;br /&gt;
    struct_Mi Mi;&lt;br /&gt;
    for (auto x: M&#039;i) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
           Mi.push_back(x.add(i));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return Mi;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    //заполнение матрицы смежности&lt;br /&gt;
    init_automorphisms(matrix);&lt;br /&gt;
&lt;br /&gt;
    //распараллеливание&lt;br /&gt;
    switch(process) {&lt;br /&gt;
    case 0:&lt;br /&gt;
        begin = 0;&lt;br /&gt;
        end = stop_0;&lt;br /&gt;
    case 1:&lt;br /&gt;
        begin = start_1;&lt;br /&gt;
        end = stop_1;&lt;br /&gt;
    ...&lt;br /&gt;
    case N:&lt;br /&gt;
        begin = start_n;&lt;br /&gt;
        end = M_0.size();&lt;br /&gt;
&lt;br /&gt;
    //основной цикл&lt;br /&gt;
    for (i = begin; i &amp;lt; end; ++i) {&lt;br /&gt;
        Mi = make_Mi(M&#039;i-1);&lt;br /&gt;
        M&#039;i = make_M&#039;i(Mi);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //сохранение результата (вывод автоморфизмов)&lt;br /&gt;
    final_automorphism(M&#039;i);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Сложность всего алгоритма представляет собой сумму сложностей вычисления &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Количество элементов в каждом множестве (с вероятностью близкой к единице):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |M&#039;_{k}| \thickapprox \frac{n!}{(n-k-2)!~2^{(k)^2}} \thickapprox \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Можно оценить: &amp;lt;math&amp;gt; |M&#039;_k| = \frac{n(n-1)\ldots(n-k-1)}{2^{(k)^2}} \le \frac{n^{k}}{2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Количество операций сравнения для подсчета всех множеств:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \sum_{k = 1}^{n} \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} \times (n - k)(2k + 1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оценка (были учтены точка стабилизации и точка максимума последовательности множеств):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; n \times \frac{n^{(5/7) \ln(n)}}{2^{((5/7)\ln(n))^2}}\times n(2(\frac{5}{7}\ln(n)) + 1)\times \log_2(n) = O(n^2(\frac{e}{2})^{\ln(n)^2} \ln(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сложность экспоненциальная.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[глоссарий#Граф алгоритма|Граф алгоритма]]&amp;lt;ref&amp;gt;Воеводин В.В.  Математические основы параллельных вычислений// М.: Изд. Моск. ун-та, 1991. 345 с.&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Воеводин В.В., Воеводин Вл.В. Параллельные вычисления. – СПб.: БХВ - Петербург, 2002. – 608 с.&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Фролов А.В.. Принципы построения и описание языка Сигма. Препринт ОВМ АН N 236. М.: ОВМ АН СССР, 1989.&amp;lt;/ref&amp;gt; при &amp;lt;math&amp;gt; n = 5 &amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для поиска автоморфизмов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; итерационным алгоритмом в параллельном варианте требуется выполнить:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; ярусов сравнений (количество сравнений &amp;lt;math&amp;gt; k = 1 \ldots n: \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} \times (n - k)(2k + 1) &amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте ЯПФ, таким образом, алогоритм имеет сложностью &amp;lt;math&amp;gt; O(n) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
При классификации по ширине ЯПФ его сложность &amp;lt;math&amp;gt; O(n(\frac{e}{2})^{\ln(n)^2} \ln(n))) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;) графа .&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; – любые, но в данной статье рассматриваются из множества {0,1}.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;, представленное матрицей (элементы &amp;lt;math&amp;gt;g^s_n&amp;lt;/math&amp;gt; - полученные автоморфизмы).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;l \times n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt; количество всевозможных автоморфизмов для данного графа.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [4 : 128] с шагом &amp;lt;math&amp;gt; 2^n&amp;lt;/math&amp;gt; (точки отображены с шагом 4, усреднив результаты);&lt;br /&gt;
*	размер матрицы [300 : 1000].&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон алгоритма:&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0,11%;&lt;br /&gt;
*	максимальная эффективность реализации 2,65%.&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики производительности и эффективности выбранной реализации поиска автоморфизмов графов в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:.png|thumb|center|700px|Рисунок 1. Параллельная реализация алгоритма поиска автоморфизмов. Изменение производительности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
[[file:.png|thumb|center|700px|Рисунок 2. Параллельная реализация алгоритма поиска автоморфизмов. Изменение эффективности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
&lt;br /&gt;
Оценки масштабируемости выбранной реализации:&lt;br /&gt;
*	По числу процессов: -0,000593. При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска уменьшается, однако в целом уменьшение не очень быстрое. Малая интенсивность изменения объясняется крайне низкой общей эффективностью работы приложения с максимумом в 2,65%, и значение эффективности на рассмотренной области значений быстро доходит до десятых долей процента. Это свидетельствует о том, что на большей части области значений нет интенсивного снижения эффективности. Это объясняется также тем, что с ростом [[Глоссарий#Вычислительная сложность|вычислительной сложности]] падение эффективности становится не таким быстрым. Уменьшение эффективности на рассмотренной области работы параллельной программы объясняется быстрым ростом накладных расходов на организацию параллельного выполнения. С ростом вычислительной сложности задачи эффективность снижается так же быстро, но при больших значениях числа процессов. Это подтверждает предположение о том, что накладные расходы начинают сильно превалировать над вычислениями.&lt;br /&gt;
*	По размеру задачи: 0,06017. При увеличении размера задачи эффективность возрастает. Эффективность возрастает тем быстрее, чем большее число процессов используется для выполнения. Это подтверждает предположение о том, что размер задачи сильно влияет на эффективность выполнения приложения. Оценка показывает, что с ростом размера задачи эффективность на рассмотренной области значений параметров запуска сильно увеличивается. Также, учитывая разницу максимальной и минимальной эффективности в 2,5%, можно сделать вывод, что рост эффективности при увеличении размера задачи наблюдается на большей части рассмотренной области значений.&lt;br /&gt;
*	По двум направлениям: 0,000403. При рассмотрении увеличения как вычислительной сложности, так и числа процессов на всей рассмотренной области значений эффективность увеличивается, однако скорость увеличения эффективности небольшая. В совокупности с тем фактом, что разница между максимальной и минимальной эффективностью на рассмотренной области значений параметров небольшая, эффективность с увеличением масштабов возрастает, но медленно и с небольшими перепадами.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Информация о реализациях данного алгоритма не найдена. При анализе алгоритма было разработано 2 программы: &amp;lt;br/&amp;gt; &lt;br /&gt;
&lt;br /&gt;
:1) приложение с графическим интерфейсом, написанное на &#039;&#039;&#039;Qt&#039;&#039;&#039;&lt;br /&gt;
:::* не поддерживает распараллеливание&lt;br /&gt;
:::* справляется с графами размера до 500 вершин&lt;br /&gt;
:::* удобный анализ графов&lt;br /&gt;
:::* помимо нахождения автоморфизмов, решает задачи изоморфизма и гомоморфизма графов&lt;br /&gt;
:2) программа на языки &#039;&#039;&#039;C++&#039;&#039;&#039; с поддержкой &#039;&#039;&#039;OpenMPI&#039;&#039;&#039;&lt;br /&gt;
:::* поддерживает распараллеливание средствами OpenMPI&lt;br /&gt;
:::* помимо нахождения автоморфизмов, сохраняет много информации для анализа графов с большим количеством вершин&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25067</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25067"/>
		<updated>2017-12-10T11:39:56Z</updated>

		<summary type="html">&lt;p&gt;Full: /* Ресурс параллелизма алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&amp;lt;br&amp;gt;&lt;br /&gt;
Автор статьи: Ефремов С.С. (группа 419)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром алгоритма является последовательность множеств  &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;. Вычисляется на основе соответствующих &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt;. Построение &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt; занимает несущественную часть времени.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Каждое множество &amp;lt;math&amp;gt; M_i (i = 2 \ldots n) &amp;lt;/math&amp;gt; вычисляется из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; путем добавления в каждый элемент (частичная перестановка, представленная вектором целых чисел) из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; всех возможных оставшихся чисел, которых нет в соответствующем элементе.&lt;br /&gt;
&lt;br /&gt;
Для этого удобно использовать 2 не фиксированных по количеству строк двумерных массива размера t на n (t может увеличиваться), хранящих частичные отображения, такого вида: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
a_{11} &amp;amp; a_{12} &amp;amp; \ldots &amp;amp;a_{1i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
a_{21} &amp;amp; a_{22} &amp;amp; \ldots &amp;amp;a_{2i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
a_{k1} &amp;amp; a_{k2} &amp;amp; \ldots &amp;amp;a_{ki} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
? - эти значения не известны и заполняются постепенно.&lt;br /&gt;
&lt;br /&gt;
Один массив для &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt;, другой для вычисления из предыдущего &amp;lt;math&amp;gt; M_i &amp;lt;/math&amp;gt;.&lt;br /&gt;
Из каждой строки множества &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; (первый массив), в соответствие с алгоритмом, получается &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; новых строк длины i, которые записываются во второй массив (расширяется, если нужно).&lt;br /&gt;
&lt;br /&gt;
После этого, второй массив копируется в первый и запускается цикл по всем векторам. Вектор исключается из массива, если &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; равен какому-либо числу в данном векторе или вектор с &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; является частичной перестановкой, не удовлетворяющей критерию;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Схема реализации представлена на языке C++&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#define GRAPH_SIZE 300&lt;br /&gt;
#define ROW_ARR_SIZE 10000 &lt;br /&gt;
#define COL_ARR_SIZE GRAPH_SIZE&lt;br /&gt;
&lt;br /&gt;
const int N = GRAPH_SIZE;&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; Mi(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; M&#039;i(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
unsigned char **matrix;&lt;br /&gt;
&lt;br /&gt;
struct_M&#039;i make_M&#039;i(Mi) {&lt;br /&gt;
    struct_M&#039;i M&#039;i;&lt;br /&gt;
    for (auto x: Mi) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
            if (check_h(x) &amp;amp;&amp;amp; !eq(x, i)) {&lt;br /&gt;
                M&#039;i.push_back(x.add(i));&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return M&#039;i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct_Mi make_Mi(M&#039;i) {&lt;br /&gt;
    struct_Mi Mi;&lt;br /&gt;
    for (auto x: M&#039;i) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
           Mi.push_back(x.add(i));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return Mi;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    //заполнение матрицы смежности&lt;br /&gt;
    init_automorphisms(matrix);&lt;br /&gt;
&lt;br /&gt;
    //распараллеливание&lt;br /&gt;
    switch(process) {&lt;br /&gt;
    case 0:&lt;br /&gt;
        begin = 0;&lt;br /&gt;
        end = stop_0;&lt;br /&gt;
    case 1:&lt;br /&gt;
        begin = start_1;&lt;br /&gt;
        end = stop_1;&lt;br /&gt;
    ...&lt;br /&gt;
    case N:&lt;br /&gt;
        begin = start_n;&lt;br /&gt;
        end = M_0.size();&lt;br /&gt;
&lt;br /&gt;
    //основной цикл&lt;br /&gt;
    for (i = begin; i &amp;lt; end; ++i) {&lt;br /&gt;
        Mi = make_Mi(M&#039;i-1);&lt;br /&gt;
        M&#039;i = make_M&#039;i(Mi);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //сохранение результата (вывод автоморфизмов)&lt;br /&gt;
    final_automorphism(M&#039;i);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Сложность всего алгоритма представляет собой сумму сложностей вычисления &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Количество элементов в каждом множестве (с вероятностью близкой к единице):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |M&#039;_{k}| \thickapprox \frac{n!}{(n-k-2)!~2^{(k)^2}} \thickapprox \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Можно оценить: &amp;lt;math&amp;gt; |M&#039;_k| = \frac{n(n-1)\ldots(n-k-1)}{2^{(k)^2}} \le \frac{n^{k}}{2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Количество операций сравнения для подсчета всех множеств:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \sum_{k = 1}^{n} \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} \times (n - k)(2k + 1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оценка (были учтены точка стабилизации и точка максимума последовательности множеств):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; n \times \frac{n^{(5/7) \ln(n)}}{2^{((5/7)\ln(n))^2}}\times n(2(\frac{5}{7}\ln(n)) + 1)\times \log_2(n) = O(n^2(\frac{e}{2})^{\ln(n)^2} \ln(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сложность экспоненциальная.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[глоссарий#Граф алгоритма|Граф алгоритма]]&amp;lt;ref&amp;gt;Воеводин В.В.  Математические основы параллельных вычислений// М.: Изд. Моск. ун-та, 1991. 345 с.&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Воеводин В.В., Воеводин Вл.В. Параллельные вычисления. – СПб.: БХВ - Петербург, 2002. – 608 с.&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Фролов А.В.. Принципы построения и описание языка Сигма. Препринт ОВМ АН N 236. М.: ОВМ АН СССР, 1989.&amp;lt;/ref&amp;gt; при &amp;lt;math&amp;gt; n = 5 &amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для поиска автоморфизмов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; итерационным алгоритмом в параллельном варианте требуется выполнить:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; ярусов сравнений (количество сравнений &amp;lt;math&amp;gt; k = 1 \ldots n: \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} \times (n - k)(2k + 1) &amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте ЯПФ, таким образом, алогоритм имеет сложностью &amp;lt;math&amp;gt; O(n) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
При классификации по ширине ЯПФ его сложность &amp;lt;math&amp;gt; O(n(\frac{e}{2})^{\ln(n)^2} \ln(n))) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [4 : 128] с шагом &amp;lt;math&amp;gt; 2^n&amp;lt;/math&amp;gt; (точки отображены с шагом 4, усреднив результаты);&lt;br /&gt;
*	размер матрицы [300 : 1000].&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон алгоритма:&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0,11%;&lt;br /&gt;
*	максимальная эффективность реализации 2,65%.&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики производительности и эффективности выбранной реализации поиска автоморфизмов графов в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:.png|thumb|center|700px|Рисунок 1. Параллельная реализация алгоритма поиска автоморфизмов. Изменение производительности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
[[file:.png|thumb|center|700px|Рисунок 2. Параллельная реализация алгоритма поиска автоморфизмов. Изменение эффективности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
&lt;br /&gt;
Оценки масштабируемости выбранной реализации:&lt;br /&gt;
*	По числу процессов: -0,000593. При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска уменьшается, однако в целом уменьшение не очень быстрое. Малая интенсивность изменения объясняется крайне низкой общей эффективностью работы приложения с максимумом в 2,65%, и значение эффективности на рассмотренной области значений быстро доходит до десятых долей процента. Это свидетельствует о том, что на большей части области значений нет интенсивного снижения эффективности. Это объясняется также тем, что с ростом [[Глоссарий#Вычислительная сложность|вычислительной сложности]] падение эффективности становится не таким быстрым. Уменьшение эффективности на рассмотренной области работы параллельной программы объясняется быстрым ростом накладных расходов на организацию параллельного выполнения. С ростом вычислительной сложности задачи эффективность снижается так же быстро, но при больших значениях числа процессов. Это подтверждает предположение о том, что накладные расходы начинают сильно превалировать над вычислениями.&lt;br /&gt;
*	По размеру задачи: 0,06017. При увеличении размера задачи эффективность возрастает. Эффективность возрастает тем быстрее, чем большее число процессов используется для выполнения. Это подтверждает предположение о том, что размер задачи сильно влияет на эффективность выполнения приложения. Оценка показывает, что с ростом размера задачи эффективность на рассмотренной области значений параметров запуска сильно увеличивается. Также, учитывая разницу максимальной и минимальной эффективности в 2,5%, можно сделать вывод, что рост эффективности при увеличении размера задачи наблюдается на большей части рассмотренной области значений.&lt;br /&gt;
*	По двум направлениям: 0,000403. При рассмотрении увеличения как вычислительной сложности, так и числа процессов на всей рассмотренной области значений эффективность увеличивается, однако скорость увеличения эффективности небольшая. В совокупности с тем фактом, что разница между максимальной и минимальной эффективностью на рассмотренной области значений параметров небольшая, эффективность с увеличением масштабов возрастает, но медленно и с небольшими перепадами.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Информация о реализациях данного алгоритма не найдена. При анализе алгоритма было разработано 2 программы: &amp;lt;br/&amp;gt; &lt;br /&gt;
&lt;br /&gt;
:1) приложение с графическим интерфейсом, написанное на &#039;&#039;&#039;Qt&#039;&#039;&#039;&lt;br /&gt;
:::* не поддерживает распараллеливание&lt;br /&gt;
:::* справляется с графами размера до 500 вершин&lt;br /&gt;
:::* удобный анализ графов&lt;br /&gt;
:::* помимо нахождения автоморфизмов, решает задачи изоморфизма и гомоморфизма графов&lt;br /&gt;
:2) программа на языки &#039;&#039;&#039;C++&#039;&#039;&#039; с поддержкой &#039;&#039;&#039;OpenMPI&#039;&#039;&#039;&lt;br /&gt;
:::* поддерживает распараллеливание средствами OpenMPI&lt;br /&gt;
:::* помимо нахождения автоморфизмов, сохраняет много информации для анализа графов с большим количеством вершин&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25066</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25066"/>
		<updated>2017-12-10T11:37:12Z</updated>

		<summary type="html">&lt;p&gt;Full: /* Ресурс параллелизма алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&amp;lt;br&amp;gt;&lt;br /&gt;
Автор статьи: Ефремов С.С. (группа 419)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром алгоритма является последовательность множеств  &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;. Вычисляется на основе соответствующих &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt;. Построение &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt; занимает несущественную часть времени.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Каждое множество &amp;lt;math&amp;gt; M_i (i = 2 \ldots n) &amp;lt;/math&amp;gt; вычисляется из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; путем добавления в каждый элемент (частичная перестановка, представленная вектором целых чисел) из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; всех возможных оставшихся чисел, которых нет в соответствующем элементе.&lt;br /&gt;
&lt;br /&gt;
Для этого удобно использовать 2 не фиксированных по количеству строк двумерных массива размера t на n (t может увеличиваться), хранящих частичные отображения, такого вида: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
a_{11} &amp;amp; a_{12} &amp;amp; \ldots &amp;amp;a_{1i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
a_{21} &amp;amp; a_{22} &amp;amp; \ldots &amp;amp;a_{2i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
a_{k1} &amp;amp; a_{k2} &amp;amp; \ldots &amp;amp;a_{ki} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
? - эти значения не известны и заполняются постепенно.&lt;br /&gt;
&lt;br /&gt;
Один массив для &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt;, другой для вычисления из предыдущего &amp;lt;math&amp;gt; M_i &amp;lt;/math&amp;gt;.&lt;br /&gt;
Из каждой строки множества &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; (первый массив), в соответствие с алгоритмом, получается &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; новых строк длины i, которые записываются во второй массив (расширяется, если нужно).&lt;br /&gt;
&lt;br /&gt;
После этого, второй массив копируется в первый и запускается цикл по всем векторам. Вектор исключается из массива, если &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; равен какому-либо числу в данном векторе или вектор с &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; является частичной перестановкой, не удовлетворяющей критерию;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Схема реализации представлена на языке C++&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#define GRAPH_SIZE 300&lt;br /&gt;
#define ROW_ARR_SIZE 10000 &lt;br /&gt;
#define COL_ARR_SIZE GRAPH_SIZE&lt;br /&gt;
&lt;br /&gt;
const int N = GRAPH_SIZE;&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; Mi(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; M&#039;i(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
unsigned char **matrix;&lt;br /&gt;
&lt;br /&gt;
struct_M&#039;i make_M&#039;i(Mi) {&lt;br /&gt;
    struct_M&#039;i M&#039;i;&lt;br /&gt;
    for (auto x: Mi) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
            if (check_h(x) &amp;amp;&amp;amp; !eq(x, i)) {&lt;br /&gt;
                M&#039;i.push_back(x.add(i));&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return M&#039;i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct_Mi make_Mi(M&#039;i) {&lt;br /&gt;
    struct_Mi Mi;&lt;br /&gt;
    for (auto x: M&#039;i) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
           Mi.push_back(x.add(i));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return Mi;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    //заполнение матрицы смежности&lt;br /&gt;
    init_automorphisms(matrix);&lt;br /&gt;
&lt;br /&gt;
    //распараллеливание&lt;br /&gt;
    switch(process) {&lt;br /&gt;
    case 0:&lt;br /&gt;
        begin = 0;&lt;br /&gt;
        end = stop_0;&lt;br /&gt;
    case 1:&lt;br /&gt;
        begin = start_1;&lt;br /&gt;
        end = stop_1;&lt;br /&gt;
    ...&lt;br /&gt;
    case N:&lt;br /&gt;
        begin = start_n;&lt;br /&gt;
        end = M_0.size();&lt;br /&gt;
&lt;br /&gt;
    //основной цикл&lt;br /&gt;
    for (i = begin; i &amp;lt; end; ++i) {&lt;br /&gt;
        Mi = make_Mi(M&#039;i-1);&lt;br /&gt;
        M&#039;i = make_M&#039;i(Mi);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //сохранение результата (вывод автоморфизмов)&lt;br /&gt;
    final_automorphism(M&#039;i);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Сложность всего алгоритма представляет собой сумму сложностей вычисления &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Количество элементов в каждом множестве (с вероятностью близкой к единице):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |M&#039;_{k}| \thickapprox \frac{n!}{(n-k-2)!~2^{(k)^2}} \thickapprox \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Можно оценить: &amp;lt;math&amp;gt; |M&#039;_k| = \frac{n(n-1)\ldots(n-k-1)}{2^{(k)^2}} \le \frac{n^{k}}{2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Количество операций сравнения для подсчета всех множеств:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \sum_{k = 1}^{n} \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} \times (n - k)(2k + 1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оценка (были учтены точка стабилизации и точка максимума последовательности множеств):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; n \times \frac{n^{(5/7) \ln(n)}}{2^{((5/7)\ln(n))^2}}\times n(2(\frac{5}{7}\ln(n)) + 1)\times \log_2(n) = O(n^2(\frac{e}{2})^{\ln(n)^2} \ln(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сложность экспоненциальная.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[глоссарий#Граф алгоритма|Граф алгоритма]]&amp;lt;ref&amp;gt;Воеводин В.В.  Математические основы параллельных вычислений// М.: Изд. Моск. ун-та, 1991. 345 с.&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Воеводин В.В., Воеводин Вл.В. Параллельные вычисления. – СПб.: БХВ - Петербург, 2002. – 608 с.&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Фролов А.В.. Принципы построения и описание языка Сигма. Препринт ОВМ АН N 236. М.: ОВМ АН СССР, 1989.&amp;lt;/ref&amp;gt; при &amp;lt;math&amp;gt; n = 5 &amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для поиска автоморфизмов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; итерационным алгоритмом в параллельном варианте требуется выполнить:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; ярусов сравнений (количество сравнений &amp;lt;math&amp;gt; &amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте ЯПФ, таким образом, алогоритм имеет сложностью &amp;lt;math&amp;gt; O(n) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
При классификации по ширине ЯПФ его сложность &amp;lt;math&amp;gt; O(n(\frac{e}{2})^{\ln(n)^2} \ln(n))) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [4 : 128] с шагом &amp;lt;math&amp;gt; 2^n&amp;lt;/math&amp;gt; (точки отображены с шагом 4, усреднив результаты);&lt;br /&gt;
*	размер матрицы [300 : 1000].&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон алгоритма:&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0,11%;&lt;br /&gt;
*	максимальная эффективность реализации 2,65%.&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики производительности и эффективности выбранной реализации поиска автоморфизмов графов в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:.png|thumb|center|700px|Рисунок 1. Параллельная реализация алгоритма поиска автоморфизмов. Изменение производительности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
[[file:.png|thumb|center|700px|Рисунок 2. Параллельная реализация алгоритма поиска автоморфизмов. Изменение эффективности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
&lt;br /&gt;
Оценки масштабируемости выбранной реализации:&lt;br /&gt;
*	По числу процессов: -0,000593. При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска уменьшается, однако в целом уменьшение не очень быстрое. Малая интенсивность изменения объясняется крайне низкой общей эффективностью работы приложения с максимумом в 2,65%, и значение эффективности на рассмотренной области значений быстро доходит до десятых долей процента. Это свидетельствует о том, что на большей части области значений нет интенсивного снижения эффективности. Это объясняется также тем, что с ростом [[Глоссарий#Вычислительная сложность|вычислительной сложности]] падение эффективности становится не таким быстрым. Уменьшение эффективности на рассмотренной области работы параллельной программы объясняется быстрым ростом накладных расходов на организацию параллельного выполнения. С ростом вычислительной сложности задачи эффективность снижается так же быстро, но при больших значениях числа процессов. Это подтверждает предположение о том, что накладные расходы начинают сильно превалировать над вычислениями.&lt;br /&gt;
*	По размеру задачи: 0,06017. При увеличении размера задачи эффективность возрастает. Эффективность возрастает тем быстрее, чем большее число процессов используется для выполнения. Это подтверждает предположение о том, что размер задачи сильно влияет на эффективность выполнения приложения. Оценка показывает, что с ростом размера задачи эффективность на рассмотренной области значений параметров запуска сильно увеличивается. Также, учитывая разницу максимальной и минимальной эффективности в 2,5%, можно сделать вывод, что рост эффективности при увеличении размера задачи наблюдается на большей части рассмотренной области значений.&lt;br /&gt;
*	По двум направлениям: 0,000403. При рассмотрении увеличения как вычислительной сложности, так и числа процессов на всей рассмотренной области значений эффективность увеличивается, однако скорость увеличения эффективности небольшая. В совокупности с тем фактом, что разница между максимальной и минимальной эффективностью на рассмотренной области значений параметров небольшая, эффективность с увеличением масштабов возрастает, но медленно и с небольшими перепадами.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Информация о реализациях данного алгоритма не найдена. При анализе алгоритма было разработано 2 программы: &amp;lt;br/&amp;gt; &lt;br /&gt;
&lt;br /&gt;
:1) приложение с графическим интерфейсом, написанное на &#039;&#039;&#039;Qt&#039;&#039;&#039;&lt;br /&gt;
:::* не поддерживает распараллеливание&lt;br /&gt;
:::* справляется с графами размера до 500 вершин&lt;br /&gt;
:::* удобный анализ графов&lt;br /&gt;
:::* помимо нахождения автоморфизмов, решает задачи изоморфизма и гомоморфизма графов&lt;br /&gt;
:2) программа на языки &#039;&#039;&#039;C++&#039;&#039;&#039; с поддержкой &#039;&#039;&#039;OpenMPI&#039;&#039;&#039;&lt;br /&gt;
:::* поддерживает распараллеливание средствами OpenMPI&lt;br /&gt;
:::* помимо нахождения автоморфизмов, сохраняет много информации для анализа графов с большим количеством вершин&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25065</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25065"/>
		<updated>2017-12-10T11:36:46Z</updated>

		<summary type="html">&lt;p&gt;Full: /* Ресурс параллелизма алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&amp;lt;br&amp;gt;&lt;br /&gt;
Автор статьи: Ефремов С.С. (группа 419)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром алгоритма является последовательность множеств  &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;. Вычисляется на основе соответствующих &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt;. Построение &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt; занимает несущественную часть времени.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Каждое множество &amp;lt;math&amp;gt; M_i (i = 2 \ldots n) &amp;lt;/math&amp;gt; вычисляется из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; путем добавления в каждый элемент (частичная перестановка, представленная вектором целых чисел) из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; всех возможных оставшихся чисел, которых нет в соответствующем элементе.&lt;br /&gt;
&lt;br /&gt;
Для этого удобно использовать 2 не фиксированных по количеству строк двумерных массива размера t на n (t может увеличиваться), хранящих частичные отображения, такого вида: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
a_{11} &amp;amp; a_{12} &amp;amp; \ldots &amp;amp;a_{1i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
a_{21} &amp;amp; a_{22} &amp;amp; \ldots &amp;amp;a_{2i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
a_{k1} &amp;amp; a_{k2} &amp;amp; \ldots &amp;amp;a_{ki} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
? - эти значения не известны и заполняются постепенно.&lt;br /&gt;
&lt;br /&gt;
Один массив для &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt;, другой для вычисления из предыдущего &amp;lt;math&amp;gt; M_i &amp;lt;/math&amp;gt;.&lt;br /&gt;
Из каждой строки множества &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; (первый массив), в соответствие с алгоритмом, получается &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; новых строк длины i, которые записываются во второй массив (расширяется, если нужно).&lt;br /&gt;
&lt;br /&gt;
После этого, второй массив копируется в первый и запускается цикл по всем векторам. Вектор исключается из массива, если &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; равен какому-либо числу в данном векторе или вектор с &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; является частичной перестановкой, не удовлетворяющей критерию;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Схема реализации представлена на языке C++&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#define GRAPH_SIZE 300&lt;br /&gt;
#define ROW_ARR_SIZE 10000 &lt;br /&gt;
#define COL_ARR_SIZE GRAPH_SIZE&lt;br /&gt;
&lt;br /&gt;
const int N = GRAPH_SIZE;&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; Mi(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; M&#039;i(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
unsigned char **matrix;&lt;br /&gt;
&lt;br /&gt;
struct_M&#039;i make_M&#039;i(Mi) {&lt;br /&gt;
    struct_M&#039;i M&#039;i;&lt;br /&gt;
    for (auto x: Mi) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
            if (check_h(x) &amp;amp;&amp;amp; !eq(x, i)) {&lt;br /&gt;
                M&#039;i.push_back(x.add(i));&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return M&#039;i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct_Mi make_Mi(M&#039;i) {&lt;br /&gt;
    struct_Mi Mi;&lt;br /&gt;
    for (auto x: M&#039;i) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
           Mi.push_back(x.add(i));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return Mi;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    //заполнение матрицы смежности&lt;br /&gt;
    init_automorphisms(matrix);&lt;br /&gt;
&lt;br /&gt;
    //распараллеливание&lt;br /&gt;
    switch(process) {&lt;br /&gt;
    case 0:&lt;br /&gt;
        begin = 0;&lt;br /&gt;
        end = stop_0;&lt;br /&gt;
    case 1:&lt;br /&gt;
        begin = start_1;&lt;br /&gt;
        end = stop_1;&lt;br /&gt;
    ...&lt;br /&gt;
    case N:&lt;br /&gt;
        begin = start_n;&lt;br /&gt;
        end = M_0.size();&lt;br /&gt;
&lt;br /&gt;
    //основной цикл&lt;br /&gt;
    for (i = begin; i &amp;lt; end; ++i) {&lt;br /&gt;
        Mi = make_Mi(M&#039;i-1);&lt;br /&gt;
        M&#039;i = make_M&#039;i(Mi);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //сохранение результата (вывод автоморфизмов)&lt;br /&gt;
    final_automorphism(M&#039;i);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Сложность всего алгоритма представляет собой сумму сложностей вычисления &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Количество элементов в каждом множестве (с вероятностью близкой к единице):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |M&#039;_{k}| \thickapprox \frac{n!}{(n-k-2)!~2^{(k)^2}} \thickapprox \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Можно оценить: &amp;lt;math&amp;gt; |M&#039;_k| = \frac{n(n-1)\ldots(n-k-1)}{2^{(k)^2}} \le \frac{n^{k}}{2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Количество операций сравнения для подсчета всех множеств:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \sum_{k = 1}^{n} \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} \times (n - k)(2k + 1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оценка (были учтены точка стабилизации и точка максимума последовательности множеств):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; n \times \frac{n^{(5/7) \ln(n)}}{2^{((5/7)\ln(n))^2}}\times n(2(\frac{5}{7}\ln(n)) + 1)\times \log_2(n) = O(n^2(\frac{e}{2})^{\ln(n)^2} \ln(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сложность экспоненциальная.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[глоссарий#Граф алгоритма|Граф алгоритма]]&amp;lt;ref&amp;gt;Воеводин В.В.  Математические основы параллельных вычислений// М.: Изд. Моск. ун-та, 1991. 345 с.&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Воеводин В.В., Воеводин Вл.В. Параллельные вычисления. – СПб.: БХВ - Петербург, 2002. – 608 с.&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Фролов А.В.. Принципы построения и описание языка Сигма. Препринт ОВМ АН N 236. М.: ОВМ АН СССР, 1989.&amp;lt;/ref&amp;gt; при &amp;lt;math&amp;gt; n = 5 &amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для поиска автоморфизмов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; итерационным алгоритмом в параллельном варианте требуется выполнить:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; ярусов сравнений (количество сравнений &amp;lt;math&amp;gt; &amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте ЯПФ, таким образом, алогоритм имеет сложностью &amp;lt;math&amp;gt; O(n) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
При классификации по ширине ЯПФ его сложность &amp;lt;math&amp;gt; O(O(n(\frac{e}{2})^{\ln(n)^2} \ln(n))) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [4 : 128] с шагом &amp;lt;math&amp;gt; 2^n&amp;lt;/math&amp;gt; (точки отображены с шагом 4, усреднив результаты);&lt;br /&gt;
*	размер матрицы [300 : 1000].&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон алгоритма:&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0,11%;&lt;br /&gt;
*	максимальная эффективность реализации 2,65%.&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики производительности и эффективности выбранной реализации поиска автоморфизмов графов в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:.png|thumb|center|700px|Рисунок 1. Параллельная реализация алгоритма поиска автоморфизмов. Изменение производительности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
[[file:.png|thumb|center|700px|Рисунок 2. Параллельная реализация алгоритма поиска автоморфизмов. Изменение эффективности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
&lt;br /&gt;
Оценки масштабируемости выбранной реализации:&lt;br /&gt;
*	По числу процессов: -0,000593. При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска уменьшается, однако в целом уменьшение не очень быстрое. Малая интенсивность изменения объясняется крайне низкой общей эффективностью работы приложения с максимумом в 2,65%, и значение эффективности на рассмотренной области значений быстро доходит до десятых долей процента. Это свидетельствует о том, что на большей части области значений нет интенсивного снижения эффективности. Это объясняется также тем, что с ростом [[Глоссарий#Вычислительная сложность|вычислительной сложности]] падение эффективности становится не таким быстрым. Уменьшение эффективности на рассмотренной области работы параллельной программы объясняется быстрым ростом накладных расходов на организацию параллельного выполнения. С ростом вычислительной сложности задачи эффективность снижается так же быстро, но при больших значениях числа процессов. Это подтверждает предположение о том, что накладные расходы начинают сильно превалировать над вычислениями.&lt;br /&gt;
*	По размеру задачи: 0,06017. При увеличении размера задачи эффективность возрастает. Эффективность возрастает тем быстрее, чем большее число процессов используется для выполнения. Это подтверждает предположение о том, что размер задачи сильно влияет на эффективность выполнения приложения. Оценка показывает, что с ростом размера задачи эффективность на рассмотренной области значений параметров запуска сильно увеличивается. Также, учитывая разницу максимальной и минимальной эффективности в 2,5%, можно сделать вывод, что рост эффективности при увеличении размера задачи наблюдается на большей части рассмотренной области значений.&lt;br /&gt;
*	По двум направлениям: 0,000403. При рассмотрении увеличения как вычислительной сложности, так и числа процессов на всей рассмотренной области значений эффективность увеличивается, однако скорость увеличения эффективности небольшая. В совокупности с тем фактом, что разница между максимальной и минимальной эффективностью на рассмотренной области значений параметров небольшая, эффективность с увеличением масштабов возрастает, но медленно и с небольшими перепадами.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Информация о реализациях данного алгоритма не найдена. При анализе алгоритма было разработано 2 программы: &amp;lt;br/&amp;gt; &lt;br /&gt;
&lt;br /&gt;
:1) приложение с графическим интерфейсом, написанное на &#039;&#039;&#039;Qt&#039;&#039;&#039;&lt;br /&gt;
:::* не поддерживает распараллеливание&lt;br /&gt;
:::* справляется с графами размера до 500 вершин&lt;br /&gt;
:::* удобный анализ графов&lt;br /&gt;
:::* помимо нахождения автоморфизмов, решает задачи изоморфизма и гомоморфизма графов&lt;br /&gt;
:2) программа на языки &#039;&#039;&#039;C++&#039;&#039;&#039; с поддержкой &#039;&#039;&#039;OpenMPI&#039;&#039;&#039;&lt;br /&gt;
:::* поддерживает распараллеливание средствами OpenMPI&lt;br /&gt;
:::* помимо нахождения автоморфизмов, сохраняет много информации для анализа графов с большим количеством вершин&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25064</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25064"/>
		<updated>2017-12-09T14:59:25Z</updated>

		<summary type="html">&lt;p&gt;Full: /* Ресурс параллелизма алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&amp;lt;br&amp;gt;&lt;br /&gt;
Автор статьи: Ефремов С.С. (группа 419)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром алгоритма является последовательность множеств  &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;. Вычисляется на основе соответствующих &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt;. Построение &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt; занимает несущественную часть времени.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Каждое множество &amp;lt;math&amp;gt; M_i (i = 2 \ldots n) &amp;lt;/math&amp;gt; вычисляется из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; путем добавления в каждый элемент (частичная перестановка, представленная вектором целых чисел) из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; всех возможных оставшихся чисел, которых нет в соответствующем элементе.&lt;br /&gt;
&lt;br /&gt;
Для этого удобно использовать 2 не фиксированных по количеству строк двумерных массива размера t на n (t может увеличиваться), хранящих частичные отображения, такого вида: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
a_{11} &amp;amp; a_{12} &amp;amp; \ldots &amp;amp;a_{1i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
a_{21} &amp;amp; a_{22} &amp;amp; \ldots &amp;amp;a_{2i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
a_{k1} &amp;amp; a_{k2} &amp;amp; \ldots &amp;amp;a_{ki} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
? - эти значения не известны и заполняются постепенно.&lt;br /&gt;
&lt;br /&gt;
Один массив для &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt;, другой для вычисления из предыдущего &amp;lt;math&amp;gt; M_i &amp;lt;/math&amp;gt;.&lt;br /&gt;
Из каждой строки множества &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; (первый массив), в соответствие с алгоритмом, получается &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; новых строк длины i, которые записываются во второй массив (расширяется, если нужно).&lt;br /&gt;
&lt;br /&gt;
После этого, второй массив копируется в первый и запускается цикл по всем векторам. Вектор исключается из массива, если &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; равен какому-либо числу в данном векторе или вектор с &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; является частичной перестановкой, не удовлетворяющей критерию;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Схема реализации представлена на языке C++&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#define GRAPH_SIZE 300&lt;br /&gt;
#define ROW_ARR_SIZE 10000 &lt;br /&gt;
#define COL_ARR_SIZE GRAPH_SIZE&lt;br /&gt;
&lt;br /&gt;
const int N = GRAPH_SIZE;&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; Mi(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; M&#039;i(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
unsigned char **matrix;&lt;br /&gt;
&lt;br /&gt;
struct_M&#039;i make_M&#039;i(Mi) {&lt;br /&gt;
    struct_M&#039;i M&#039;i;&lt;br /&gt;
    for (auto x: Mi) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
            if (check_h(x) &amp;amp;&amp;amp; !eq(x, i)) {&lt;br /&gt;
                M&#039;i.push_back(x.add(i));&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return M&#039;i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct_Mi make_Mi(M&#039;i) {&lt;br /&gt;
    struct_Mi Mi;&lt;br /&gt;
    for (auto x: M&#039;i) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
           Mi.push_back(x.add(i));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return Mi;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    //заполнение матрицы смежности&lt;br /&gt;
    init_automorphisms(matrix);&lt;br /&gt;
&lt;br /&gt;
    //распараллеливание&lt;br /&gt;
    switch(process) {&lt;br /&gt;
    case 0:&lt;br /&gt;
        begin = 0;&lt;br /&gt;
        end = stop_0;&lt;br /&gt;
    case 1:&lt;br /&gt;
        begin = start_1;&lt;br /&gt;
        end = stop_1;&lt;br /&gt;
    ...&lt;br /&gt;
    case N:&lt;br /&gt;
        begin = start_n;&lt;br /&gt;
        end = M_0.size();&lt;br /&gt;
&lt;br /&gt;
    //основной цикл&lt;br /&gt;
    for (i = begin; i &amp;lt; end; ++i) {&lt;br /&gt;
        Mi = make_Mi(M&#039;i-1);&lt;br /&gt;
        M&#039;i = make_M&#039;i(Mi);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //сохранение результата (вывод автоморфизмов)&lt;br /&gt;
    final_automorphism(M&#039;i);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Сложность всего алгоритма представляет собой сумму сложностей вычисления &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Количество элементов в каждом множестве (с вероятностью близкой к единице):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |M&#039;_{k}| \thickapprox \frac{n!}{(n-k-2)!~2^{(k)^2}} \thickapprox \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Можно оценить: &amp;lt;math&amp;gt; |M&#039;_k| = \frac{n(n-1)\ldots(n-k-1)}{2^{(k)^2}} \le \frac{n^{k}}{2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Количество операций сравнения для подсчета всех множеств:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \sum_{k = 1}^{n} \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} \times (n - k)(2k + 1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оценка (были учтены точка стабилизации и точка максимума последовательности множеств):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; n \times \frac{n^{(5/7) \ln(n)}}{2^{((5/7)\ln(n))^2}}\times n(2(\frac{5}{7}\ln(n)) + 1)\times \log_2(n) = O(n^2(\frac{e}{2})^{\ln(n)^2} \ln(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сложность экспоненциальная.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[глоссарий#Граф алгоритма|Граф алгоритма]]&amp;lt;ref&amp;gt;Воеводин В.В.  Математические основы параллельных вычислений// М.: Изд. Моск. ун-та, 1991. 345 с.&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Воеводин В.В., Воеводин Вл.В. Параллельные вычисления. – СПб.: БХВ - Петербург, 2002. – 608 с.&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Фролов А.В.. Принципы построения и описание языка Сигма. Препринт ОВМ АН N 236. М.: ОВМ АН СССР, 1989.&amp;lt;/ref&amp;gt; при &amp;lt;math&amp;gt; n = 5 &amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для поиска автоморфизмов матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; итерационным алгоритмом в параллельном варианте требуется выполнить:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; ярусов сравнений (количество сравнений &amp;lt;math&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте ЯПФ, таким образом, алогоритм имеет сложностью &amp;lt;math&amp;gt; O(n) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
При классификации по ширине ЯПФ его сложность та же &amp;lt;math&amp;gt; O(n) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [4 : 128] с шагом &amp;lt;math&amp;gt; 2^n&amp;lt;/math&amp;gt; (точки отображены с шагом 4, усреднив результаты);&lt;br /&gt;
*	размер матрицы [300 : 1000].&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон алгоритма:&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0,11%;&lt;br /&gt;
*	максимальная эффективность реализации 2,65%.&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики производительности и эффективности выбранной реализации поиска автоморфизмов графов в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:.png|thumb|center|700px|Рисунок 1. Параллельная реализация алгоритма поиска автоморфизмов. Изменение производительности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
[[file:.png|thumb|center|700px|Рисунок 2. Параллельная реализация алгоритма поиска автоморфизмов. Изменение эффективности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
&lt;br /&gt;
Оценки масштабируемости выбранной реализации:&lt;br /&gt;
*	По числу процессов: -0,000593. При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска уменьшается, однако в целом уменьшение не очень быстрое. Малая интенсивность изменения объясняется крайне низкой общей эффективностью работы приложения с максимумом в 2,65%, и значение эффективности на рассмотренной области значений быстро доходит до десятых долей процента. Это свидетельствует о том, что на большей части области значений нет интенсивного снижения эффективности. Это объясняется также тем, что с ростом [[Глоссарий#Вычислительная сложность|вычислительной сложности]] падение эффективности становится не таким быстрым. Уменьшение эффективности на рассмотренной области работы параллельной программы объясняется быстрым ростом накладных расходов на организацию параллельного выполнения. С ростом вычислительной сложности задачи эффективность снижается так же быстро, но при больших значениях числа процессов. Это подтверждает предположение о том, что накладные расходы начинают сильно превалировать над вычислениями.&lt;br /&gt;
*	По размеру задачи: 0,06017. При увеличении размера задачи эффективность возрастает. Эффективность возрастает тем быстрее, чем большее число процессов используется для выполнения. Это подтверждает предположение о том, что размер задачи сильно влияет на эффективность выполнения приложения. Оценка показывает, что с ростом размера задачи эффективность на рассмотренной области значений параметров запуска сильно увеличивается. Также, учитывая разницу максимальной и минимальной эффективности в 2,5%, можно сделать вывод, что рост эффективности при увеличении размера задачи наблюдается на большей части рассмотренной области значений.&lt;br /&gt;
*	По двум направлениям: 0,000403. При рассмотрении увеличения как вычислительной сложности, так и числа процессов на всей рассмотренной области значений эффективность увеличивается, однако скорость увеличения эффективности небольшая. В совокупности с тем фактом, что разница между максимальной и минимальной эффективностью на рассмотренной области значений параметров небольшая, эффективность с увеличением масштабов возрастает, но медленно и с небольшими перепадами.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Информация о реализациях данного алгоритма не найдена. При анализе алгоритма было разработано 2 программы: &amp;lt;br/&amp;gt; &lt;br /&gt;
&lt;br /&gt;
:1) приложение с графическим интерфейсом, написанное на &#039;&#039;&#039;Qt&#039;&#039;&#039;&lt;br /&gt;
:::* не поддерживает распараллеливание&lt;br /&gt;
:::* справляется с графами размера до 500 вершин&lt;br /&gt;
:::* удобный анализ графов&lt;br /&gt;
:::* помимо нахождения автоморфизмов, решает задачи изоморфизма и гомоморфизма графов&lt;br /&gt;
:2) программа на языки &#039;&#039;&#039;C++&#039;&#039;&#039; с поддержкой &#039;&#039;&#039;OpenMPI&#039;&#039;&#039;&lt;br /&gt;
:::* поддерживает распараллеливание средствами OpenMPI&lt;br /&gt;
:::* помимо нахождения автоморфизмов, сохраняет много информации для анализа графов с большим количеством вершин&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25063</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25063"/>
		<updated>2017-12-09T14:10:18Z</updated>

		<summary type="html">&lt;p&gt;Full: /* Ресурс параллелизма алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&amp;lt;br&amp;gt;&lt;br /&gt;
Автор статьи: Ефремов С.С. (группа 419)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром алгоритма является последовательность множеств  &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;. Вычисляется на основе соответствующих &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt;. Построение &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt; занимает несущественную часть времени.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Каждое множество &amp;lt;math&amp;gt; M_i (i = 2 \ldots n) &amp;lt;/math&amp;gt; вычисляется из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; путем добавления в каждый элемент (частичная перестановка, представленная вектором целых чисел) из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; всех возможных оставшихся чисел, которых нет в соответствующем элементе.&lt;br /&gt;
&lt;br /&gt;
Для этого удобно использовать 2 не фиксированных по количеству строк двумерных массива размера t на n (t может увеличиваться), хранящих частичные отображения, такого вида: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
a_{11} &amp;amp; a_{12} &amp;amp; \ldots &amp;amp;a_{1i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
a_{21} &amp;amp; a_{22} &amp;amp; \ldots &amp;amp;a_{2i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
a_{k1} &amp;amp; a_{k2} &amp;amp; \ldots &amp;amp;a_{ki} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
? - эти значения не известны и заполняются постепенно.&lt;br /&gt;
&lt;br /&gt;
Один массив для &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt;, другой для вычисления из предыдущего &amp;lt;math&amp;gt; M_i &amp;lt;/math&amp;gt;.&lt;br /&gt;
Из каждой строки множества &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; (первый массив), в соответствие с алгоритмом, получается &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; новых строк длины i, которые записываются во второй массив (расширяется, если нужно).&lt;br /&gt;
&lt;br /&gt;
После этого, второй массив копируется в первый и запускается цикл по всем векторам. Вектор исключается из массива, если &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; равен какому-либо числу в данном векторе или вектор с &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; является частичной перестановкой, не удовлетворяющей критерию;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Схема реализации представлена на языке C++&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#define GRAPH_SIZE 300&lt;br /&gt;
#define ROW_ARR_SIZE 10000 &lt;br /&gt;
#define COL_ARR_SIZE GRAPH_SIZE&lt;br /&gt;
&lt;br /&gt;
const int N = GRAPH_SIZE;&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; Mi(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; M&#039;i(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
unsigned char **matrix;&lt;br /&gt;
&lt;br /&gt;
struct_M&#039;i make_M&#039;i(Mi) {&lt;br /&gt;
    struct_M&#039;i M&#039;i;&lt;br /&gt;
    for (auto x: Mi) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
            if (check_h(x) &amp;amp;&amp;amp; !eq(x, i)) {&lt;br /&gt;
                M&#039;i.push_back(x.add(i));&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return M&#039;i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct_Mi make_Mi(M&#039;i) {&lt;br /&gt;
    struct_Mi Mi;&lt;br /&gt;
    for (auto x: M&#039;i) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
           Mi.push_back(x.add(i));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return Mi;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    //заполнение матрицы смежности&lt;br /&gt;
    init_automorphisms(matrix);&lt;br /&gt;
&lt;br /&gt;
    //распараллеливание&lt;br /&gt;
    switch(process) {&lt;br /&gt;
    case 0:&lt;br /&gt;
        begin = 0;&lt;br /&gt;
        end = stop_0;&lt;br /&gt;
    case 1:&lt;br /&gt;
        begin = start_1;&lt;br /&gt;
        end = stop_1;&lt;br /&gt;
    ...&lt;br /&gt;
    case N:&lt;br /&gt;
        begin = start_n;&lt;br /&gt;
        end = M_0.size();&lt;br /&gt;
&lt;br /&gt;
    //основной цикл&lt;br /&gt;
    for (i = begin; i &amp;lt; end; ++i) {&lt;br /&gt;
        Mi = make_Mi(M&#039;i-1);&lt;br /&gt;
        M&#039;i = make_M&#039;i(Mi);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //сохранение результата (вывод автоморфизмов)&lt;br /&gt;
    final_automorphism(M&#039;i);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Сложность всего алгоритма представляет собой сумму сложностей вычисления &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Количество элементов в каждом множестве (с вероятностью близкой к единице):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |M&#039;_{k}| \thickapprox \frac{n!}{(n-k-2)!~2^{(k)^2}} \thickapprox \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Можно оценить: &amp;lt;math&amp;gt; |M&#039;_k| = \frac{n(n-1)\ldots(n-k-1)}{2^{(k)^2}} \le \frac{n^{k}}{2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Количество операций сравнения для подсчета всех множеств:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \sum_{k = 1}^{n} \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} \times (n - k)(2k + 1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оценка (были учтены точка стабилизации и точка максимума последовательности множеств):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; n \times \frac{n^{(5/7) \ln(n)}}{2^{((5/7)\ln(n))^2}}\times n(2(\frac{5}{7}\ln(n)) + 1)\times \log_2(n) = O(n^2(\frac{e}{2})^{\ln(n)^2} \ln(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сложность экспоненциальная.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[глоссарий#Граф алгоритма|Граф алгоритма]]&amp;lt;ref&amp;gt;Воеводин В.В.  Математические основы параллельных вычислений// М.: Изд. Моск. ун-та, 1991. 345 с.&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Воеводин В.В., Воеводин Вл.В. Параллельные вычисления. – СПб.: БХВ - Петербург, 2002. – 608 с.&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Фролов А.В.. Принципы построения и описание языка Сигма. Препринт ОВМ АН N 236. М.: ОВМ АН СССР, 1989.&amp;lt;/ref&amp;gt; при &amp;lt;math&amp;gt; n = 5 &amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
При классификации по высоте ЯПФ, таким образом, алогоритм имеет сложностью &amp;lt;math&amp;gt; O(n) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
При классификации по ширине ЯПФ его сложность та же &amp;lt;math&amp;gt; O(n) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [4 : 128] с шагом &amp;lt;math&amp;gt; 2^n&amp;lt;/math&amp;gt; (точки отображены с шагом 4, усреднив результаты);&lt;br /&gt;
*	размер матрицы [300 : 1000].&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон алгоритма:&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0,11%;&lt;br /&gt;
*	максимальная эффективность реализации 2,65%.&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики производительности и эффективности выбранной реализации поиска автоморфизмов графов в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:.png|thumb|center|700px|Рисунок 1. Параллельная реализация алгоритма поиска автоморфизмов. Изменение производительности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
[[file:.png|thumb|center|700px|Рисунок 2. Параллельная реализация алгоритма поиска автоморфизмов. Изменение эффективности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
&lt;br /&gt;
Оценки масштабируемости выбранной реализации:&lt;br /&gt;
*	По числу процессов: -0,000593. При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска уменьшается, однако в целом уменьшение не очень быстрое. Малая интенсивность изменения объясняется крайне низкой общей эффективностью работы приложения с максимумом в 2,65%, и значение эффективности на рассмотренной области значений быстро доходит до десятых долей процента. Это свидетельствует о том, что на большей части области значений нет интенсивного снижения эффективности. Это объясняется также тем, что с ростом [[Глоссарий#Вычислительная сложность|вычислительной сложности]] падение эффективности становится не таким быстрым. Уменьшение эффективности на рассмотренной области работы параллельной программы объясняется быстрым ростом накладных расходов на организацию параллельного выполнения. С ростом вычислительной сложности задачи эффективность снижается так же быстро, но при больших значениях числа процессов. Это подтверждает предположение о том, что накладные расходы начинают сильно превалировать над вычислениями.&lt;br /&gt;
*	По размеру задачи: 0,06017. При увеличении размера задачи эффективность возрастает. Эффективность возрастает тем быстрее, чем большее число процессов используется для выполнения. Это подтверждает предположение о том, что размер задачи сильно влияет на эффективность выполнения приложения. Оценка показывает, что с ростом размера задачи эффективность на рассмотренной области значений параметров запуска сильно увеличивается. Также, учитывая разницу максимальной и минимальной эффективности в 2,5%, можно сделать вывод, что рост эффективности при увеличении размера задачи наблюдается на большей части рассмотренной области значений.&lt;br /&gt;
*	По двум направлениям: 0,000403. При рассмотрении увеличения как вычислительной сложности, так и числа процессов на всей рассмотренной области значений эффективность увеличивается, однако скорость увеличения эффективности небольшая. В совокупности с тем фактом, что разница между максимальной и минимальной эффективностью на рассмотренной области значений параметров небольшая, эффективность с увеличением масштабов возрастает, но медленно и с небольшими перепадами.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Информация о реализациях данного алгоритма не найдена. При анализе алгоритма было разработано 2 программы: &amp;lt;br/&amp;gt; &lt;br /&gt;
&lt;br /&gt;
:1) приложение с графическим интерфейсом, написанное на &#039;&#039;&#039;Qt&#039;&#039;&#039;&lt;br /&gt;
:::* не поддерживает распараллеливание&lt;br /&gt;
:::* справляется с графами размера до 500 вершин&lt;br /&gt;
:::* удобный анализ графов&lt;br /&gt;
:::* помимо нахождения автоморфизмов, решает задачи изоморфизма и гомоморфизма графов&lt;br /&gt;
:2) программа на языки &#039;&#039;&#039;C++&#039;&#039;&#039; с поддержкой &#039;&#039;&#039;OpenMPI&#039;&#039;&#039;&lt;br /&gt;
:::* поддерживает распараллеливание средствами OpenMPI&lt;br /&gt;
:::* помимо нахождения автоморфизмов, сохраняет много информации для анализа графов с большим количеством вершин&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25062</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25062"/>
		<updated>2017-12-09T14:09:52Z</updated>

		<summary type="html">&lt;p&gt;Full: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&amp;lt;br&amp;gt;&lt;br /&gt;
Автор статьи: Ефремов С.С. (группа 419)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром алгоритма является последовательность множеств  &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;. Вычисляется на основе соответствующих &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt;. Построение &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt; занимает несущественную часть времени.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Каждое множество &amp;lt;math&amp;gt; M_i (i = 2 \ldots n) &amp;lt;/math&amp;gt; вычисляется из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; путем добавления в каждый элемент (частичная перестановка, представленная вектором целых чисел) из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; всех возможных оставшихся чисел, которых нет в соответствующем элементе.&lt;br /&gt;
&lt;br /&gt;
Для этого удобно использовать 2 не фиксированных по количеству строк двумерных массива размера t на n (t может увеличиваться), хранящих частичные отображения, такого вида: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
a_{11} &amp;amp; a_{12} &amp;amp; \ldots &amp;amp;a_{1i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
a_{21} &amp;amp; a_{22} &amp;amp; \ldots &amp;amp;a_{2i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
a_{k1} &amp;amp; a_{k2} &amp;amp; \ldots &amp;amp;a_{ki} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
? - эти значения не известны и заполняются постепенно.&lt;br /&gt;
&lt;br /&gt;
Один массив для &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt;, другой для вычисления из предыдущего &amp;lt;math&amp;gt; M_i &amp;lt;/math&amp;gt;.&lt;br /&gt;
Из каждой строки множества &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; (первый массив), в соответствие с алгоритмом, получается &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; новых строк длины i, которые записываются во второй массив (расширяется, если нужно).&lt;br /&gt;
&lt;br /&gt;
После этого, второй массив копируется в первый и запускается цикл по всем векторам. Вектор исключается из массива, если &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; равен какому-либо числу в данном векторе или вектор с &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; является частичной перестановкой, не удовлетворяющей критерию;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Схема реализации представлена на языке C++&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#define GRAPH_SIZE 300&lt;br /&gt;
#define ROW_ARR_SIZE 10000 &lt;br /&gt;
#define COL_ARR_SIZE GRAPH_SIZE&lt;br /&gt;
&lt;br /&gt;
const int N = GRAPH_SIZE;&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; Mi(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; M&#039;i(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
unsigned char **matrix;&lt;br /&gt;
&lt;br /&gt;
struct_M&#039;i make_M&#039;i(Mi) {&lt;br /&gt;
    struct_M&#039;i M&#039;i;&lt;br /&gt;
    for (auto x: Mi) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
            if (check_h(x) &amp;amp;&amp;amp; !eq(x, i)) {&lt;br /&gt;
                M&#039;i.push_back(x.add(i));&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return M&#039;i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct_Mi make_Mi(M&#039;i) {&lt;br /&gt;
    struct_Mi Mi;&lt;br /&gt;
    for (auto x: M&#039;i) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
           Mi.push_back(x.add(i));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return Mi;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    //заполнение матрицы смежности&lt;br /&gt;
    init_automorphisms(matrix);&lt;br /&gt;
&lt;br /&gt;
    //распараллеливание&lt;br /&gt;
    switch(process) {&lt;br /&gt;
    case 0:&lt;br /&gt;
        begin = 0;&lt;br /&gt;
        end = stop_0;&lt;br /&gt;
    case 1:&lt;br /&gt;
        begin = start_1;&lt;br /&gt;
        end = stop_1;&lt;br /&gt;
    ...&lt;br /&gt;
    case N:&lt;br /&gt;
        begin = start_n;&lt;br /&gt;
        end = M_0.size();&lt;br /&gt;
&lt;br /&gt;
    //основной цикл&lt;br /&gt;
    for (i = begin; i &amp;lt; end; ++i) {&lt;br /&gt;
        Mi = make_Mi(M&#039;i-1);&lt;br /&gt;
        M&#039;i = make_M&#039;i(Mi);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //сохранение результата (вывод автоморфизмов)&lt;br /&gt;
    final_automorphism(M&#039;i);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Сложность всего алгоритма представляет собой сумму сложностей вычисления &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Количество элементов в каждом множестве (с вероятностью близкой к единице):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |M&#039;_{k}| \thickapprox \frac{n!}{(n-k-2)!~2^{(k)^2}} \thickapprox \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Можно оценить: &amp;lt;math&amp;gt; |M&#039;_k| = \frac{n(n-1)\ldots(n-k-1)}{2^{(k)^2}} \le \frac{n^{k}}{2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Количество операций сравнения для подсчета всех множеств:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \sum_{k = 1}^{n} \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} \times (n - k)(2k + 1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оценка (были учтены точка стабилизации и точка максимума последовательности множеств):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; n \times \frac{n^{(5/7) \ln(n)}}{2^{((5/7)\ln(n))^2}}\times n(2(\frac{5}{7}\ln(n)) + 1)\times \log_2(n) = O(n^2(\frac{e}{2})^{\ln(n)^2} \ln(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сложность экспоненциальная.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
[[глоссарий#Граф алгоритма|Граф алгоритма]]&amp;lt;ref&amp;gt;Воеводин В.В.  Математические основы параллельных вычислений// М.: Изд. Моск. ун-та, 1991. 345 с.&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Воеводин В.В., Воеводин Вл.В. Параллельные вычисления. – СПб.: БХВ - Петербург, 2002. – 608 с.&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Фролов А.В.. Принципы построения и описание языка Сигма. Препринт ОВМ АН N 236. М.: ОВМ АН СССР, 1989.&amp;lt;/ref&amp;gt; при &amp;lt;math&amp;gt; n = 5 &amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [4 : 128] с шагом &amp;lt;math&amp;gt; 2^n&amp;lt;/math&amp;gt; (точки отображены с шагом 4, усреднив результаты);&lt;br /&gt;
*	размер матрицы [300 : 1000].&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон алгоритма:&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0,11%;&lt;br /&gt;
*	максимальная эффективность реализации 2,65%.&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики производительности и эффективности выбранной реализации поиска автоморфизмов графов в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:.png|thumb|center|700px|Рисунок 1. Параллельная реализация алгоритма поиска автоморфизмов. Изменение производительности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
[[file:.png|thumb|center|700px|Рисунок 2. Параллельная реализация алгоритма поиска автоморфизмов. Изменение эффективности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
&lt;br /&gt;
Оценки масштабируемости выбранной реализации:&lt;br /&gt;
*	По числу процессов: -0,000593. При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска уменьшается, однако в целом уменьшение не очень быстрое. Малая интенсивность изменения объясняется крайне низкой общей эффективностью работы приложения с максимумом в 2,65%, и значение эффективности на рассмотренной области значений быстро доходит до десятых долей процента. Это свидетельствует о том, что на большей части области значений нет интенсивного снижения эффективности. Это объясняется также тем, что с ростом [[Глоссарий#Вычислительная сложность|вычислительной сложности]] падение эффективности становится не таким быстрым. Уменьшение эффективности на рассмотренной области работы параллельной программы объясняется быстрым ростом накладных расходов на организацию параллельного выполнения. С ростом вычислительной сложности задачи эффективность снижается так же быстро, но при больших значениях числа процессов. Это подтверждает предположение о том, что накладные расходы начинают сильно превалировать над вычислениями.&lt;br /&gt;
*	По размеру задачи: 0,06017. При увеличении размера задачи эффективность возрастает. Эффективность возрастает тем быстрее, чем большее число процессов используется для выполнения. Это подтверждает предположение о том, что размер задачи сильно влияет на эффективность выполнения приложения. Оценка показывает, что с ростом размера задачи эффективность на рассмотренной области значений параметров запуска сильно увеличивается. Также, учитывая разницу максимальной и минимальной эффективности в 2,5%, можно сделать вывод, что рост эффективности при увеличении размера задачи наблюдается на большей части рассмотренной области значений.&lt;br /&gt;
*	По двум направлениям: 0,000403. При рассмотрении увеличения как вычислительной сложности, так и числа процессов на всей рассмотренной области значений эффективность увеличивается, однако скорость увеличения эффективности небольшая. В совокупности с тем фактом, что разница между максимальной и минимальной эффективностью на рассмотренной области значений параметров небольшая, эффективность с увеличением масштабов возрастает, но медленно и с небольшими перепадами.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Информация о реализациях данного алгоритма не найдена. При анализе алгоритма было разработано 2 программы: &amp;lt;br/&amp;gt; &lt;br /&gt;
&lt;br /&gt;
:1) приложение с графическим интерфейсом, написанное на &#039;&#039;&#039;Qt&#039;&#039;&#039;&lt;br /&gt;
:::* не поддерживает распараллеливание&lt;br /&gt;
:::* справляется с графами размера до 500 вершин&lt;br /&gt;
:::* удобный анализ графов&lt;br /&gt;
:::* помимо нахождения автоморфизмов, решает задачи изоморфизма и гомоморфизма графов&lt;br /&gt;
:2) программа на языки &#039;&#039;&#039;C++&#039;&#039;&#039; с поддержкой &#039;&#039;&#039;OpenMPI&#039;&#039;&#039;&lt;br /&gt;
:::* поддерживает распараллеливание средствами OpenMPI&lt;br /&gt;
:::* помимо нахождения автоморфизмов, сохраняет много информации для анализа графов с большим количеством вершин&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25061</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25061"/>
		<updated>2017-12-09T13:32:19Z</updated>

		<summary type="html">&lt;p&gt;Full: /* Ресурс параллелизма алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&amp;lt;br&amp;gt;&lt;br /&gt;
Автор статьи: Ефремов С.С. (группа 419)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром алгоритма является последовательность множеств  &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;. Вычисляется на основе соответствующих &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt;. Построение &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt; занимает несущественную часть времени.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Каждое множество &amp;lt;math&amp;gt; M_i (i = 2 \ldots n) &amp;lt;/math&amp;gt; вычисляется из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; путем добавления в каждый элемент (частичная перестановка, представленная вектором целых чисел) из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; всех возможных оставшихся чисел, которых нет в соответствующем элементе.&lt;br /&gt;
&lt;br /&gt;
Для этого удобно использовать 2 не фиксированных по количеству строк двумерных массива размера t на n (t может увеличиваться), хранящих частичные отображения, такого вида: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
a_{11} &amp;amp; a_{12} &amp;amp; \ldots &amp;amp;a_{1i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
a_{21} &amp;amp; a_{22} &amp;amp; \ldots &amp;amp;a_{2i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
a_{k1} &amp;amp; a_{k2} &amp;amp; \ldots &amp;amp;a_{ki} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
? - эти значения не известны и заполняются постепенно.&lt;br /&gt;
&lt;br /&gt;
Один массив для &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt;, другой для вычисления из предыдущего &amp;lt;math&amp;gt; M_i &amp;lt;/math&amp;gt;.&lt;br /&gt;
Из каждой строки множества &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; (первый массив), в соответствие с алгоритмом, получается &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; новых строк длины i, которые записываются во второй массив (расширяется, если нужно).&lt;br /&gt;
&lt;br /&gt;
После этого, второй массив копируется в первый и запускается цикл по всем векторам. Вектор исключается из массива, если &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; равен какому-либо числу в данном векторе или вектор с &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; является частичной перестановкой, не удовлетворяющей критерию;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Схема реализации представлена на языке C++&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#define GRAPH_SIZE 300&lt;br /&gt;
#define ROW_ARR_SIZE 10000 &lt;br /&gt;
#define COL_ARR_SIZE GRAPH_SIZE&lt;br /&gt;
&lt;br /&gt;
const int N = GRAPH_SIZE;&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; Mi(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; M&#039;i(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
unsigned char **matrix;&lt;br /&gt;
&lt;br /&gt;
struct_M&#039;i make_M&#039;i(Mi) {&lt;br /&gt;
    struct_M&#039;i M&#039;i;&lt;br /&gt;
    for (auto x: Mi) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
            if (check_h(x) &amp;amp;&amp;amp; !eq(x, i)) {&lt;br /&gt;
                M&#039;i.push_back(x.add(i));&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return M&#039;i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct_Mi make_Mi(M&#039;i) {&lt;br /&gt;
    struct_Mi Mi;&lt;br /&gt;
    for (auto x: M&#039;i) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
           Mi.push_back(x.add(i));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return Mi;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    //заполнение матрицы смежности&lt;br /&gt;
    init_automorphisms(matrix);&lt;br /&gt;
&lt;br /&gt;
    //распараллеливание&lt;br /&gt;
    switch(process) {&lt;br /&gt;
    case 0:&lt;br /&gt;
        begin = 0;&lt;br /&gt;
        end = stop_0;&lt;br /&gt;
    case 1:&lt;br /&gt;
        begin = start_1;&lt;br /&gt;
        end = stop_1;&lt;br /&gt;
    ...&lt;br /&gt;
    case N:&lt;br /&gt;
        begin = start_n;&lt;br /&gt;
        end = M_0.size();&lt;br /&gt;
&lt;br /&gt;
    //основной цикл&lt;br /&gt;
    for (i = begin; i &amp;lt; end; ++i) {&lt;br /&gt;
        Mi = make_Mi(M&#039;i-1);&lt;br /&gt;
        M&#039;i = make_M&#039;i(Mi);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //сохранение результата (вывод автоморфизмов)&lt;br /&gt;
    final_automorphism(M&#039;i);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Сложность всего алгоритма представляет собой сумму сложностей вычисления &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Количество элементов в каждом множестве (с вероятностью близкой к единице):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |M&#039;_{k}| \thickapprox \frac{n!}{(n-k-2)!~2^{(k)^2}} \thickapprox \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Можно оценить: &amp;lt;math&amp;gt; |M&#039;_k| = \frac{n(n-1)\ldots(n-k-1)}{2^{(k)^2}} \le \frac{n^{k}}{2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Количество операций сравнения для подсчета всех множеств:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \sum_{k = 1}^{n} \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} \times (n - k)(2k + 1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оценка (были учтены точка стабилизации и точка максимума последовательности множеств):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; n \times \frac{n^{(5/7) \ln(n)}}{2^{((5/7)\ln(n))^2}}\times n(2(\frac{5}{7}\ln(n)) + 1)\times \log_2(n) = O(n^2(\frac{e}{2})^{\ln(n)^2} \ln(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сложность экспоненциальная.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [4 : 128] с шагом &amp;lt;math&amp;gt; 2^n&amp;lt;/math&amp;gt; (точки отображены с шагом 4, усреднив результаты);&lt;br /&gt;
*	размер матрицы [300 : 1000].&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон алгоритма:&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0,11%;&lt;br /&gt;
*	максимальная эффективность реализации 2,65%.&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики производительности и эффективности выбранной реализации поиска автоморфизмов графов в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:.png|thumb|center|700px|Рисунок 1. Параллельная реализация алгоритма поиска автоморфизмов. Изменение производительности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
[[file:.png|thumb|center|700px|Рисунок 2. Параллельная реализация алгоритма поиска автоморфизмов. Изменение эффективности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
&lt;br /&gt;
Оценки масштабируемости выбранной реализации:&lt;br /&gt;
*	По числу процессов: -0,000593. При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска уменьшается, однако в целом уменьшение не очень быстрое. Малая интенсивность изменения объясняется крайне низкой общей эффективностью работы приложения с максимумом в 2,65%, и значение эффективности на рассмотренной области значений быстро доходит до десятых долей процента. Это свидетельствует о том, что на большей части области значений нет интенсивного снижения эффективности. Это объясняется также тем, что с ростом [[Глоссарий#Вычислительная сложность|вычислительной сложности]] падение эффективности становится не таким быстрым. Уменьшение эффективности на рассмотренной области работы параллельной программы объясняется быстрым ростом накладных расходов на организацию параллельного выполнения. С ростом вычислительной сложности задачи эффективность снижается так же быстро, но при больших значениях числа процессов. Это подтверждает предположение о том, что накладные расходы начинают сильно превалировать над вычислениями.&lt;br /&gt;
*	По размеру задачи: 0,06017. При увеличении размера задачи эффективность возрастает. Эффективность возрастает тем быстрее, чем большее число процессов используется для выполнения. Это подтверждает предположение о том, что размер задачи сильно влияет на эффективность выполнения приложения. Оценка показывает, что с ростом размера задачи эффективность на рассмотренной области значений параметров запуска сильно увеличивается. Также, учитывая разницу максимальной и минимальной эффективности в 2,5%, можно сделать вывод, что рост эффективности при увеличении размера задачи наблюдается на большей части рассмотренной области значений.&lt;br /&gt;
*	По двум направлениям: 0,000403. При рассмотрении увеличения как вычислительной сложности, так и числа процессов на всей рассмотренной области значений эффективность увеличивается, однако скорость увеличения эффективности небольшая. В совокупности с тем фактом, что разница между максимальной и минимальной эффективностью на рассмотренной области значений параметров небольшая, эффективность с увеличением масштабов возрастает, но медленно и с небольшими перепадами.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Информация о реализациях данного алгоритма не найдена. При анализе алгоритма было разработано 2 программы: &amp;lt;br/&amp;gt; &lt;br /&gt;
&lt;br /&gt;
:1) приложение с графическим интерфейсом, написанное на &#039;&#039;&#039;Qt&#039;&#039;&#039;&lt;br /&gt;
:::* не поддерживает распараллеливание&lt;br /&gt;
:::* справляется с графами размера до 500 вершин&lt;br /&gt;
:::* удобный анализ графов&lt;br /&gt;
:::* помимо нахождения автоморфизмов, решает задачи изоморфизма и гомоморфизма графов&lt;br /&gt;
:2) программа на языки &#039;&#039;&#039;C++&#039;&#039;&#039; с поддержкой &#039;&#039;&#039;OpenMPI&#039;&#039;&#039;&lt;br /&gt;
:::* поддерживает распараллеливание средствами OpenMPI&lt;br /&gt;
:::* помимо нахождения автоморфизмов, сохраняет много информации для анализа графов с большим количеством вершин&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25060</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25060"/>
		<updated>2017-12-09T13:31:42Z</updated>

		<summary type="html">&lt;p&gt;Full: /* Ресурс параллелизма алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&amp;lt;br&amp;gt;&lt;br /&gt;
Автор статьи: Ефремов С.С. (группа 419)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром алгоритма является последовательность множеств  &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;. Вычисляется на основе соответствующих &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt;. Построение &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt; занимает несущественную часть времени.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Каждое множество &amp;lt;math&amp;gt; M_i (i = 2 \ldots n) &amp;lt;/math&amp;gt; вычисляется из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; путем добавления в каждый элемент (частичная перестановка, представленная вектором целых чисел) из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; всех возможных оставшихся чисел, которых нет в соответствующем элементе.&lt;br /&gt;
&lt;br /&gt;
Для этого удобно использовать 2 не фиксированных по количеству строк двумерных массива размера t на n (t может увеличиваться), хранящих частичные отображения, такого вида: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
a_{11} &amp;amp; a_{12} &amp;amp; \ldots &amp;amp;a_{1i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
a_{21} &amp;amp; a_{22} &amp;amp; \ldots &amp;amp;a_{2i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
a_{k1} &amp;amp; a_{k2} &amp;amp; \ldots &amp;amp;a_{ki} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
? - эти значения не известны и заполняются постепенно.&lt;br /&gt;
&lt;br /&gt;
Один массив для &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt;, другой для вычисления из предыдущего &amp;lt;math&amp;gt; M_i &amp;lt;/math&amp;gt;.&lt;br /&gt;
Из каждой строки множества &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; (первый массив), в соответствие с алгоритмом, получается &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; новых строк длины i, которые записываются во второй массив (расширяется, если нужно).&lt;br /&gt;
&lt;br /&gt;
После этого, второй массив копируется в первый и запускается цикл по всем векторам. Вектор исключается из массива, если &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; равен какому-либо числу в данном векторе или вектор с &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; является частичной перестановкой, не удовлетворяющей критерию;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Схема реализации представлена на языке C++&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#define GRAPH_SIZE 300&lt;br /&gt;
#define ROW_ARR_SIZE 10000 &lt;br /&gt;
#define COL_ARR_SIZE GRAPH_SIZE&lt;br /&gt;
&lt;br /&gt;
const int N = GRAPH_SIZE;&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; Mi(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; M&#039;i(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
unsigned char **matrix;&lt;br /&gt;
&lt;br /&gt;
struct_M&#039;i make_M&#039;i(Mi) {&lt;br /&gt;
    struct_M&#039;i M&#039;i;&lt;br /&gt;
    for (auto x: Mi) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
            if (check_h(x) &amp;amp;&amp;amp; !eq(x, i)) {&lt;br /&gt;
                M&#039;i.push_back(x.add(i));&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return M&#039;i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct_Mi make_Mi(M&#039;i) {&lt;br /&gt;
    struct_Mi Mi;&lt;br /&gt;
    for (auto x: M&#039;i) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
           Mi.push_back(x.add(i));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return Mi;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    //заполнение матрицы смежности&lt;br /&gt;
    init_automorphisms(matrix);&lt;br /&gt;
&lt;br /&gt;
    //распараллеливание&lt;br /&gt;
    switch(process) {&lt;br /&gt;
    case 0:&lt;br /&gt;
        begin = 0;&lt;br /&gt;
        end = stop_0;&lt;br /&gt;
    case 1:&lt;br /&gt;
        begin = start_1;&lt;br /&gt;
        end = stop_1;&lt;br /&gt;
    ...&lt;br /&gt;
    case N:&lt;br /&gt;
        begin = start_n;&lt;br /&gt;
        end = M_0.size();&lt;br /&gt;
&lt;br /&gt;
    //основной цикл&lt;br /&gt;
    for (i = begin; i &amp;lt; end; ++i) {&lt;br /&gt;
        Mi = make_Mi(M&#039;i-1);&lt;br /&gt;
        M&#039;i = make_M&#039;i(Mi);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //сохранение результата (вывод автоморфизмов)&lt;br /&gt;
    final_automorphism(M&#039;i);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Сложность всего алгоритма представляет собой сумму сложностей вычисления &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Количество элементов в каждом множестве (с вероятностью близкой к единице):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |M&#039;_{k}| \thickapprox \frac{n!}{(n-k-2)!~2^{(k)^2}} \thickapprox \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Можно оценить: &amp;lt;math&amp;gt; |M&#039;_k| = \frac{n(n-1)\ldots(n-k-1)}{2^{(k)^2}} \le \frac{n^{k}}{2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Количество операций сравнения для подсчета всех множеств:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \sum_{k = 1}^{n} \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} \times (n - k)(2k + 1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оценка (были учтены точка стабилизации и точка максимума последовательности множеств):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; n \times \frac{n^{(5/7) \ln(n)}}{2^{((5/7)\ln(n))^2}}\times n(2(\frac{5}{7}\ln(n)) + 1)\times \log_2(n) = O(n^2(\frac{e}{2})^{\ln(n)^2} \ln(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сложность экспоненциальная.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
[[глоссарий#Граф алгоритма|Граф алгоритма]]&amp;lt;ref&amp;gt;Воеводин В.В.  Математические основы параллельных вычислений// М.: Изд. Моск. ун-та, 1991. 345 с.&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Воеводин В.В., Воеводин Вл.В. Параллельные вычисления. – СПб.: БХВ - Петербург, 2002. – 608 с.&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;Фролов А.В.. Принципы построения и описание языка Сигма. Препринт ОВМ АН N 236. М.: ОВМ АН СССР, 1989.&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [4 : 128] с шагом &amp;lt;math&amp;gt; 2^n&amp;lt;/math&amp;gt; (точки отображены с шагом 4, усреднив результаты);&lt;br /&gt;
*	размер матрицы [300 : 1000].&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон алгоритма:&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0,11%;&lt;br /&gt;
*	максимальная эффективность реализации 2,65%.&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики производительности и эффективности выбранной реализации поиска автоморфизмов графов в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:.png|thumb|center|700px|Рисунок 1. Параллельная реализация алгоритма поиска автоморфизмов. Изменение производительности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
[[file:.png|thumb|center|700px|Рисунок 2. Параллельная реализация алгоритма поиска автоморфизмов. Изменение эффективности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
&lt;br /&gt;
Оценки масштабируемости выбранной реализации:&lt;br /&gt;
*	По числу процессов: -0,000593. При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска уменьшается, однако в целом уменьшение не очень быстрое. Малая интенсивность изменения объясняется крайне низкой общей эффективностью работы приложения с максимумом в 2,65%, и значение эффективности на рассмотренной области значений быстро доходит до десятых долей процента. Это свидетельствует о том, что на большей части области значений нет интенсивного снижения эффективности. Это объясняется также тем, что с ростом [[Глоссарий#Вычислительная сложность|вычислительной сложности]] падение эффективности становится не таким быстрым. Уменьшение эффективности на рассмотренной области работы параллельной программы объясняется быстрым ростом накладных расходов на организацию параллельного выполнения. С ростом вычислительной сложности задачи эффективность снижается так же быстро, но при больших значениях числа процессов. Это подтверждает предположение о том, что накладные расходы начинают сильно превалировать над вычислениями.&lt;br /&gt;
*	По размеру задачи: 0,06017. При увеличении размера задачи эффективность возрастает. Эффективность возрастает тем быстрее, чем большее число процессов используется для выполнения. Это подтверждает предположение о том, что размер задачи сильно влияет на эффективность выполнения приложения. Оценка показывает, что с ростом размера задачи эффективность на рассмотренной области значений параметров запуска сильно увеличивается. Также, учитывая разницу максимальной и минимальной эффективности в 2,5%, можно сделать вывод, что рост эффективности при увеличении размера задачи наблюдается на большей части рассмотренной области значений.&lt;br /&gt;
*	По двум направлениям: 0,000403. При рассмотрении увеличения как вычислительной сложности, так и числа процессов на всей рассмотренной области значений эффективность увеличивается, однако скорость увеличения эффективности небольшая. В совокупности с тем фактом, что разница между максимальной и минимальной эффективностью на рассмотренной области значений параметров небольшая, эффективность с увеличением масштабов возрастает, но медленно и с небольшими перепадами.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Информация о реализациях данного алгоритма не найдена. При анализе алгоритма было разработано 2 программы: &amp;lt;br/&amp;gt; &lt;br /&gt;
&lt;br /&gt;
:1) приложение с графическим интерфейсом, написанное на &#039;&#039;&#039;Qt&#039;&#039;&#039;&lt;br /&gt;
:::* не поддерживает распараллеливание&lt;br /&gt;
:::* справляется с графами размера до 500 вершин&lt;br /&gt;
:::* удобный анализ графов&lt;br /&gt;
:::* помимо нахождения автоморфизмов, решает задачи изоморфизма и гомоморфизма графов&lt;br /&gt;
:2) программа на языки &#039;&#039;&#039;C++&#039;&#039;&#039; с поддержкой &#039;&#039;&#039;OpenMPI&#039;&#039;&#039;&lt;br /&gt;
:::* поддерживает распараллеливание средствами OpenMPI&lt;br /&gt;
:::* помимо нахождения автоморфизмов, сохраняет много информации для анализа графов с большим количеством вершин&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25059</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=25059"/>
		<updated>2017-12-09T13:25:26Z</updated>

		<summary type="html">&lt;p&gt;Full: /* Последовательная сложность алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&amp;lt;br&amp;gt;&lt;br /&gt;
Автор статьи: Ефремов С.С. (группа 419)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром алгоритма является последовательность множеств  &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;. Вычисляется на основе соответствующих &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt;. Построение &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt; занимает несущественную часть времени.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Каждое множество &amp;lt;math&amp;gt; M_i (i = 2 \ldots n) &amp;lt;/math&amp;gt; вычисляется из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; путем добавления в каждый элемент (частичная перестановка, представленная вектором целых чисел) из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; всех возможных оставшихся чисел, которых нет в соответствующем элементе.&lt;br /&gt;
&lt;br /&gt;
Для этого удобно использовать 2 не фиксированных по количеству строк двумерных массива размера t на n (t может увеличиваться), хранящих частичные отображения, такого вида: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
a_{11} &amp;amp; a_{12} &amp;amp; \ldots &amp;amp;a_{1i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
a_{21} &amp;amp; a_{22} &amp;amp; \ldots &amp;amp;a_{2i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
a_{k1} &amp;amp; a_{k2} &amp;amp; \ldots &amp;amp;a_{ki} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
? - эти значения не известны и заполняются постепенно.&lt;br /&gt;
&lt;br /&gt;
Один массив для &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt;, другой для вычисления из предыдущего &amp;lt;math&amp;gt; M_i &amp;lt;/math&amp;gt;.&lt;br /&gt;
Из каждой строки множества &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; (первый массив), в соответствие с алгоритмом, получается &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; новых строк длины i, которые записываются во второй массив (расширяется, если нужно).&lt;br /&gt;
&lt;br /&gt;
После этого, второй массив копируется в первый и запускается цикл по всем векторам. Вектор исключается из массива, если &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; равен какому-либо числу в данном векторе или вектор с &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; является частичной перестановкой, не удовлетворяющей критерию;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Схема реализации представлена на языке C++&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#define GRAPH_SIZE 300&lt;br /&gt;
#define ROW_ARR_SIZE 10000 &lt;br /&gt;
#define COL_ARR_SIZE GRAPH_SIZE&lt;br /&gt;
&lt;br /&gt;
const int N = GRAPH_SIZE;&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; Mi(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; M&#039;i(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
unsigned char **matrix;&lt;br /&gt;
&lt;br /&gt;
struct_M&#039;i make_M&#039;i(Mi) {&lt;br /&gt;
    struct_M&#039;i M&#039;i;&lt;br /&gt;
    for (auto x: Mi) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
            if (check_h(x) &amp;amp;&amp;amp; !eq(x, i)) {&lt;br /&gt;
                M&#039;i.push_back(x.add(i));&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return M&#039;i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct_Mi make_Mi(M&#039;i) {&lt;br /&gt;
    struct_Mi Mi;&lt;br /&gt;
    for (auto x: M&#039;i) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
           Mi.push_back(x.add(i));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return Mi;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    //заполнение матрицы смежности&lt;br /&gt;
    init_automorphisms(matrix);&lt;br /&gt;
&lt;br /&gt;
    //распараллеливание&lt;br /&gt;
    switch(process) {&lt;br /&gt;
    case 0:&lt;br /&gt;
        begin = 0;&lt;br /&gt;
        end = stop_0;&lt;br /&gt;
    case 1:&lt;br /&gt;
        begin = start_1;&lt;br /&gt;
        end = stop_1;&lt;br /&gt;
    ...&lt;br /&gt;
    case N:&lt;br /&gt;
        begin = start_n;&lt;br /&gt;
        end = M_0.size();&lt;br /&gt;
&lt;br /&gt;
    //основной цикл&lt;br /&gt;
    for (i = begin; i &amp;lt; end; ++i) {&lt;br /&gt;
        Mi = make_Mi(M&#039;i-1);&lt;br /&gt;
        M&#039;i = make_M&#039;i(Mi);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //сохранение результата (вывод автоморфизмов)&lt;br /&gt;
    final_automorphism(M&#039;i);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Сложность всего алгоритма представляет собой сумму сложностей вычисления &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Количество элементов в каждом множестве (с вероятностью близкой к единице):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |M&#039;_{k}| \thickapprox \frac{n!}{(n-k-2)!~2^{(k)^2}} \thickapprox \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Можно оценить: &amp;lt;math&amp;gt; |M&#039;_k| = \frac{n(n-1)\ldots(n-k-1)}{2^{(k)^2}} \le \frac{n^{k}}{2^{(k)^2}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Количество операций сравнения для подсчета всех множеств:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \sum_{k = 1}^{n} \frac{1}{e^{k}} \frac{n^{n+1/2}}{(n-k-2)^{(n-k-3/2)}~2^{(k)^2}} \times (n - k)(2k + 1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оценка (были учтены точка стабилизации и точка максимума последовательности множеств):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; n \times \frac{n^{(5/7) \ln(n)}}{2^{((5/7)\ln(n))^2}}\times n(2(\frac{5}{7}\ln(n)) + 1)\times \log_2(n) = O(n^2(\frac{e}{2})^{\ln(n)^2} \ln(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сложность экспоненциальная.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [4 : 128] с шагом &amp;lt;math&amp;gt; 2^n&amp;lt;/math&amp;gt; (точки отображены с шагом 4, усреднив результаты);&lt;br /&gt;
*	размер матрицы [300 : 1000].&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон алгоритма:&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0,11%;&lt;br /&gt;
*	максимальная эффективность реализации 2,65%.&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики производительности и эффективности выбранной реализации поиска автоморфизмов графов в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:.png|thumb|center|700px|Рисунок 1. Параллельная реализация алгоритма поиска автоморфизмов. Изменение производительности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
[[file:.png|thumb|center|700px|Рисунок 2. Параллельная реализация алгоритма поиска автоморфизмов. Изменение эффективности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
&lt;br /&gt;
Оценки масштабируемости выбранной реализации:&lt;br /&gt;
*	По числу процессов: -0,000593. При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска уменьшается, однако в целом уменьшение не очень быстрое. Малая интенсивность изменения объясняется крайне низкой общей эффективностью работы приложения с максимумом в 2,65%, и значение эффективности на рассмотренной области значений быстро доходит до десятых долей процента. Это свидетельствует о том, что на большей части области значений нет интенсивного снижения эффективности. Это объясняется также тем, что с ростом [[Глоссарий#Вычислительная сложность|вычислительной сложности]] падение эффективности становится не таким быстрым. Уменьшение эффективности на рассмотренной области работы параллельной программы объясняется быстрым ростом накладных расходов на организацию параллельного выполнения. С ростом вычислительной сложности задачи эффективность снижается так же быстро, но при больших значениях числа процессов. Это подтверждает предположение о том, что накладные расходы начинают сильно превалировать над вычислениями.&lt;br /&gt;
*	По размеру задачи: 0,06017. При увеличении размера задачи эффективность возрастает. Эффективность возрастает тем быстрее, чем большее число процессов используется для выполнения. Это подтверждает предположение о том, что размер задачи сильно влияет на эффективность выполнения приложения. Оценка показывает, что с ростом размера задачи эффективность на рассмотренной области значений параметров запуска сильно увеличивается. Также, учитывая разницу максимальной и минимальной эффективности в 2,5%, можно сделать вывод, что рост эффективности при увеличении размера задачи наблюдается на большей части рассмотренной области значений.&lt;br /&gt;
*	По двум направлениям: 0,000403. При рассмотрении увеличения как вычислительной сложности, так и числа процессов на всей рассмотренной области значений эффективность увеличивается, однако скорость увеличения эффективности небольшая. В совокупности с тем фактом, что разница между максимальной и минимальной эффективностью на рассмотренной области значений параметров небольшая, эффективность с увеличением масштабов возрастает, но медленно и с небольшими перепадами.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Информация о реализациях данного алгоритма не найдена. При анализе алгоритма было разработано 2 программы: &amp;lt;br/&amp;gt; &lt;br /&gt;
&lt;br /&gt;
:1) приложение с графическим интерфейсом, написанное на &#039;&#039;&#039;Qt&#039;&#039;&#039;&lt;br /&gt;
:::* не поддерживает распараллеливание&lt;br /&gt;
:::* справляется с графами размера до 500 вершин&lt;br /&gt;
:::* удобный анализ графов&lt;br /&gt;
:::* помимо нахождения автоморфизмов, решает задачи изоморфизма и гомоморфизма графов&lt;br /&gt;
:2) программа на языки &#039;&#039;&#039;C++&#039;&#039;&#039; с поддержкой &#039;&#039;&#039;OpenMPI&#039;&#039;&#039;&lt;br /&gt;
:::* поддерживает распараллеливание средствами OpenMPI&lt;br /&gt;
:::* помимо нахождения автоморфизмов, сохраняет много информации для анализа графов с большим количеством вершин&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=24792</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=24792"/>
		<updated>2017-12-01T07:14:51Z</updated>

		<summary type="html">&lt;p&gt;Full: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&amp;lt;br&amp;gt;&lt;br /&gt;
Автор статьи: Ефремов С.С. (группа 419)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром алгоритма является последовательность множеств  &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;. Вычисляется на основе соответствующих &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt;. Построение &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt; занимает несущественную часть времени.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Каждое множество &amp;lt;math&amp;gt; M_i (i = 2 \ldots n) &amp;lt;/math&amp;gt; вычисляется из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; путем добавления в каждый элемент (частичная перестановка, представленная вектором целых чисел) из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; всех возможных оставшихся чисел, которых нет в соответствующем элементе.&lt;br /&gt;
&lt;br /&gt;
Для этого удобно использовать 2 не фиксированных по количеству строк двумерных массива размера t на n (t может увеличиваться), хранящих частичные отображения, такого вида: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
a_{11} &amp;amp; a_{12} &amp;amp; \ldots &amp;amp;a_{1i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
a_{21} &amp;amp; a_{22} &amp;amp; \ldots &amp;amp;a_{2i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
a_{k1} &amp;amp; a_{k2} &amp;amp; \ldots &amp;amp;a_{ki} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
? - эти значения не известны и заполняются постепенно.&lt;br /&gt;
&lt;br /&gt;
Один массив для &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt;, другой для вычисления из предыдущего &amp;lt;math&amp;gt; M_i &amp;lt;/math&amp;gt;.&lt;br /&gt;
Из каждой строки множества &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; (первый массив), в соответствие с алгоритмом, получается &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; новых строк длины i, которые записываются во второй массив (расширяется, если нужно).&lt;br /&gt;
&lt;br /&gt;
После этого, второй массив копируется в первый и запускается цикл по всем векторам. Вектор исключается из массива, если &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; равен какому-либо числу в данном векторе или вектор с &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; является частичной перестановкой, не удовлетворяющей критерию;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Схема реализации представлена на языке C++&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#define GRAPH_SIZE 300&lt;br /&gt;
#define ROW_ARR_SIZE 10000 &lt;br /&gt;
#define COL_ARR_SIZE GRAPH_SIZE&lt;br /&gt;
&lt;br /&gt;
const int N = GRAPH_SIZE;&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; Mi(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; M&#039;i(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
unsigned char **matrix;&lt;br /&gt;
&lt;br /&gt;
struct_M&#039;i make_M&#039;i(Mi) {&lt;br /&gt;
    struct_M&#039;i M&#039;i;&lt;br /&gt;
    for (auto x: Mi) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
            if (check_h(x) &amp;amp;&amp;amp; !eq(x, i)) {&lt;br /&gt;
                M&#039;i.push_back(x.add(i));&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return M&#039;i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct_Mi make_Mi(M&#039;i) {&lt;br /&gt;
    struct_Mi Mi;&lt;br /&gt;
    for (auto x: M&#039;i) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
           Mi.push_back(x.add(i));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return Mi;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    //заполнение матрицы смежности&lt;br /&gt;
    init_automorphisms(matrix);&lt;br /&gt;
&lt;br /&gt;
    //распараллеливание&lt;br /&gt;
    switch(process) {&lt;br /&gt;
    case 0:&lt;br /&gt;
        begin = 0;&lt;br /&gt;
        end = stop_0;&lt;br /&gt;
    case 1:&lt;br /&gt;
        begin = start_1;&lt;br /&gt;
        end = stop_1;&lt;br /&gt;
    ...&lt;br /&gt;
    case N:&lt;br /&gt;
        begin = start_n;&lt;br /&gt;
        end = M_0.size();&lt;br /&gt;
&lt;br /&gt;
    //основной цикл&lt;br /&gt;
    for (i = begin; i &amp;lt; end; ++i) {&lt;br /&gt;
        Mi = make_Mi(M&#039;i-1);&lt;br /&gt;
        M&#039;i = make_M&#039;i(Mi);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //сохранение результата (вывод автоморфизмов)&lt;br /&gt;
    final_automorphism(M&#039;i);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [4 : 128] с шагом &amp;lt;math&amp;gt; 2^n&amp;lt;/math&amp;gt; (точки отображены с шагом 4, усреднив результаты);&lt;br /&gt;
*	размер матрицы [300 : 1000].&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон алгоритма:&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0,11%;&lt;br /&gt;
*	максимальная эффективность реализации 2,65%.&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики производительности и эффективности выбранной реализации поиска автоморфизмов графов в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:.png|thumb|center|700px|Рисунок 1. Параллельная реализация алгоритма поиска автоморфизмов. Изменение производительности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
[[file:.png|thumb|center|700px|Рисунок 2. Параллельная реализация алгоритма поиска автоморфизмов. Изменение эффективности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
&lt;br /&gt;
Оценки масштабируемости выбранной реализации:&lt;br /&gt;
*	По числу процессов: -0,000593. При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска уменьшается, однако в целом уменьшение не очень быстрое. Малая интенсивность изменения объясняется крайне низкой общей эффективностью работы приложения с максимумом в 2,65%, и значение эффективности на рассмотренной области значений быстро доходит до десятых долей процента. Это свидетельствует о том, что на большей части области значений нет интенсивного снижения эффективности. Это объясняется также тем, что с ростом [[Глоссарий#Вычислительная сложность|вычислительной сложности]] падение эффективности становится не таким быстрым. Уменьшение эффективности на рассмотренной области работы параллельной программы объясняется быстрым ростом накладных расходов на организацию параллельного выполнения. С ростом вычислительной сложности задачи эффективность снижается так же быстро, но при больших значениях числа процессов. Это подтверждает предположение о том, что накладные расходы начинают сильно превалировать над вычислениями.&lt;br /&gt;
*	По размеру задачи: 0,06017. При увеличении размера задачи эффективность возрастает. Эффективность возрастает тем быстрее, чем большее число процессов используется для выполнения. Это подтверждает предположение о том, что размер задачи сильно влияет на эффективность выполнения приложения. Оценка показывает, что с ростом размера задачи эффективность на рассмотренной области значений параметров запуска сильно увеличивается. Также, учитывая разницу максимальной и минимальной эффективности в 2,5%, можно сделать вывод, что рост эффективности при увеличении размера задачи наблюдается на большей части рассмотренной области значений.&lt;br /&gt;
*	По двум направлениям: 0,000403. При рассмотрении увеличения как вычислительной сложности, так и числа процессов на всей рассмотренной области значений эффективность увеличивается, однако скорость увеличения эффективности небольшая. В совокупности с тем фактом, что разница между максимальной и минимальной эффективностью на рассмотренной области значений параметров небольшая, эффективность с увеличением масштабов возрастает, но медленно и с небольшими перепадами.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Информация о реализациях данного алгоритма не найдена. При анализе алгоритма было разработано 2 программы: &amp;lt;br/&amp;gt; &lt;br /&gt;
&lt;br /&gt;
:1) приложение с графическим интерфейсом, написанное на &#039;&#039;&#039;Qt&#039;&#039;&#039;&lt;br /&gt;
:::* не поддерживает распараллеливание&lt;br /&gt;
:::* справляется с графами размера до 500 вершин&lt;br /&gt;
:::* удобный анализ графов&lt;br /&gt;
:::* помимо нахождения автоморфизмов, решает задачи изоморфизма и гомоморфизма графов&lt;br /&gt;
:2) программа на языки &#039;&#039;&#039;C++&#039;&#039;&#039; с поддержкой &#039;&#039;&#039;OpenMPI&#039;&#039;&#039;&lt;br /&gt;
:::* поддерживает распараллеливание средствами OpenMPI&lt;br /&gt;
:::* помимо нахождения автоморфизмов, сохраняет много информации для анализа графов с большим количеством вершин&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=24791</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=24791"/>
		<updated>2017-12-01T07:14:24Z</updated>

		<summary type="html">&lt;p&gt;Full: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&amp;lt;br&amp;gt;&lt;br /&gt;
Автор статьи: Ефремов С.С. (группа 419)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром алгоритма является последовательность множеств  &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;. Вычисляется на основе соответствующих &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt;. Построение &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt; занимает несущественную часть времени.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Каждое множество &amp;lt;math&amp;gt; M_i (i = 2 \ldots n) &amp;lt;/math&amp;gt; вычисляется из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; путем добавления в каждый элемент (частичная перестановка, представленная вектором целых чисел) из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; всех возможных оставшихся чисел, которых нет в соответствующем элементе.&lt;br /&gt;
&lt;br /&gt;
Для этого удобно использовать 2 не фиксированных по количеству строк двумерных массива размера t на n (t может увеличиваться), хранящих частичные отображения, такого вида: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
a_{11} &amp;amp; a_{12} &amp;amp; \ldots &amp;amp;a_{1i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
a_{21} &amp;amp; a_{22} &amp;amp; \ldots &amp;amp;a_{2i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
a_{k1} &amp;amp; a_{k2} &amp;amp; \ldots &amp;amp;a_{ki} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
? - эти значения не известны и заполняются постепенно.&lt;br /&gt;
&lt;br /&gt;
Один массив для &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt;, другой для вычисления из предыдущего &amp;lt;math&amp;gt; M_i &amp;lt;/math&amp;gt;.&lt;br /&gt;
Из каждой строки множества &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; (первый массив), в соответствие с алгоритмом, получается &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; новых строк длины i, которые записываются во второй массив (расширяется, если нужно).&lt;br /&gt;
&lt;br /&gt;
После этого, второй массив копируется в первый и запускается цикл по всем векторам. Вектор исключается из массива, если &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; равен какому-либо числу в данном векторе или вектор с &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; является частичной перестановкой, не удовлетворяющей критерию;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Схема реализации представлена на языке C++&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#define GRAPH_SIZE 300&lt;br /&gt;
#define ROW_ARR_SIZE 10000 &lt;br /&gt;
#define COL_ARR_SIZE GRAPH_SIZE&lt;br /&gt;
&lt;br /&gt;
const int N = GRAPH_SIZE;&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; Mi(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; M&#039;i(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
unsigned char **matrix;&lt;br /&gt;
&lt;br /&gt;
struct_M&#039;i make_M&#039;i(Mi) {&lt;br /&gt;
    struct_M&#039;i M&#039;i;&lt;br /&gt;
    for (auto x: Mi) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
            if (check_h(x) &amp;amp;&amp;amp; !eq(x, i)) {&lt;br /&gt;
                M&#039;i.push_back(x.add(i));&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return M&#039;i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct_Mi make_Mi(M&#039;i) {&lt;br /&gt;
    struct_Mi Mi;&lt;br /&gt;
    for (auto x: M&#039;i) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
           Mi.push_back(x.add(i));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return Mi;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    //заполнение матрицы смежности&lt;br /&gt;
    init_automorphisms(matrix);&lt;br /&gt;
&lt;br /&gt;
    //распараллеливание&lt;br /&gt;
    switch(process) {&lt;br /&gt;
    case 0:&lt;br /&gt;
        begin = 0;&lt;br /&gt;
        end = stop_0;&lt;br /&gt;
    case 1:&lt;br /&gt;
        begin = start_1;&lt;br /&gt;
        end = stop_1;&lt;br /&gt;
    ...&lt;br /&gt;
    case N:&lt;br /&gt;
        begin = start_n;&lt;br /&gt;
        end = M_0.size();&lt;br /&gt;
&lt;br /&gt;
    //основной цикл&lt;br /&gt;
    for (i = begin; i &amp;lt; end; ++i) {&lt;br /&gt;
        Mi = make_Mi(M&#039;i-1);&lt;br /&gt;
        M&#039;i = make_M&#039;i(Mi);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //сохранение результата (вывод автоморфизмов)&lt;br /&gt;
    final_automorphism(M&#039;i);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [4 : 256] с шагом &amp;lt;math&amp;gt; 2^n&amp;lt;/math&amp;gt; (точки отображены с шагом 4, усреднив результаты);&lt;br /&gt;
*	размер матрицы [300 : 1000].&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон алгоритма:&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0,11%;&lt;br /&gt;
*	максимальная эффективность реализации 2,65%.&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики производительности и эффективности выбранной реализации поиска автоморфизмов графов в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:.png|thumb|center|700px|Рисунок 1. Параллельная реализация алгоритма поиска автоморфизмов. Изменение производительности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
[[file:.png|thumb|center|700px|Рисунок 2. Параллельная реализация алгоритма поиска автоморфизмов. Изменение эффективности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
&lt;br /&gt;
Оценки масштабируемости выбранной реализации:&lt;br /&gt;
*	По числу процессов: -0,000593. При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска уменьшается, однако в целом уменьшение не очень быстрое. Малая интенсивность изменения объясняется крайне низкой общей эффективностью работы приложения с максимумом в 2,65%, и значение эффективности на рассмотренной области значений быстро доходит до десятых долей процента. Это свидетельствует о том, что на большей части области значений нет интенсивного снижения эффективности. Это объясняется также тем, что с ростом [[Глоссарий#Вычислительная сложность|вычислительной сложности]] падение эффективности становится не таким быстрым. Уменьшение эффективности на рассмотренной области работы параллельной программы объясняется быстрым ростом накладных расходов на организацию параллельного выполнения. С ростом вычислительной сложности задачи эффективность снижается так же быстро, но при больших значениях числа процессов. Это подтверждает предположение о том, что накладные расходы начинают сильно превалировать над вычислениями.&lt;br /&gt;
*	По размеру задачи: 0,06017. При увеличении размера задачи эффективность возрастает. Эффективность возрастает тем быстрее, чем большее число процессов используется для выполнения. Это подтверждает предположение о том, что размер задачи сильно влияет на эффективность выполнения приложения. Оценка показывает, что с ростом размера задачи эффективность на рассмотренной области значений параметров запуска сильно увеличивается. Также, учитывая разницу максимальной и минимальной эффективности в 2,5%, можно сделать вывод, что рост эффективности при увеличении размера задачи наблюдается на большей части рассмотренной области значений.&lt;br /&gt;
*	По двум направлениям: 0,000403. При рассмотрении увеличения как вычислительной сложности, так и числа процессов на всей рассмотренной области значений эффективность увеличивается, однако скорость увеличения эффективности небольшая. В совокупности с тем фактом, что разница между максимальной и минимальной эффективностью на рассмотренной области значений параметров небольшая, эффективность с увеличением масштабов возрастает, но медленно и с небольшими перепадами.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Информация о реализациях данного алгоритма не найдена. При анализе алгоритма было разработано 2 программы: &amp;lt;br/&amp;gt; &lt;br /&gt;
&lt;br /&gt;
:1) приложение с графическим интерфейсом, написанное на &#039;&#039;&#039;Qt&#039;&#039;&#039;&lt;br /&gt;
:::* не поддерживает распараллеливание&lt;br /&gt;
:::* справляется с графами размера до 500 вершин&lt;br /&gt;
:::* удобный анализ графов&lt;br /&gt;
:::* помимо нахождения автоморфизмов, решает задачи изоморфизма и гомоморфизма графов&lt;br /&gt;
:2) программа на языки &#039;&#039;&#039;C++&#039;&#039;&#039; с поддержкой &#039;&#039;&#039;OpenMPI&#039;&#039;&#039;&lt;br /&gt;
:::* поддерживает распараллеливание средствами OpenMPI&lt;br /&gt;
:::* помимо нахождения автоморфизмов, сохраняет много информации для анализа графов с большим количеством вершин&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=24790</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=24790"/>
		<updated>2017-12-01T06:27:44Z</updated>

		<summary type="html">&lt;p&gt;Full: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&amp;lt;br&amp;gt;&lt;br /&gt;
Автор статьи: Ефремов С.С. (группа 419)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром алгоритма является последовательность множеств  &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;. Вычисляется на основе соответствующих &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt;. Построение &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt; занимает несущественную часть времени.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Каждое множество &amp;lt;math&amp;gt; M_i (i = 2 \ldots n) &amp;lt;/math&amp;gt; вычисляется из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; путем добавления в каждый элемент (частичная перестановка, представленная вектором целых чисел) из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; всех возможных оставшихся чисел, которых нет в соответствующем элементе.&lt;br /&gt;
&lt;br /&gt;
Для этого удобно использовать 2 не фиксированных по количеству строк двумерных массива размера t на n (t может увеличиваться), хранящих частичные отображения, такого вида: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
a_{11} &amp;amp; a_{12} &amp;amp; \ldots &amp;amp;a_{1i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
a_{21} &amp;amp; a_{22} &amp;amp; \ldots &amp;amp;a_{2i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
a_{k1} &amp;amp; a_{k2} &amp;amp; \ldots &amp;amp;a_{ki} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
? - эти значения не известны и заполняются постепенно.&lt;br /&gt;
&lt;br /&gt;
Один массив для &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt;, другой для вычисления из предыдущего &amp;lt;math&amp;gt; M_i &amp;lt;/math&amp;gt;.&lt;br /&gt;
Из каждой строки множества &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; (первый массив), в соответствие с алгоритмом, получается &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; новых строк длины i, которые записываются во второй массив (расширяется, если нужно).&lt;br /&gt;
&lt;br /&gt;
После этого, второй массив копируется в первый и запускается цикл по всем векторам. Вектор исключается из массива, если &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; равен какому-либо числу в данном векторе или вектор с &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; является частичной перестановкой, не удовлетворяющей критерию;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Схема реализации представлена на языке C++&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#define GRAPH_SIZE 300&lt;br /&gt;
#define ROW_ARR_SIZE 10000 &lt;br /&gt;
#define COL_ARR_SIZE GRAPH_SIZE&lt;br /&gt;
&lt;br /&gt;
const int N = GRAPH_SIZE;&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; Mi(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; M&#039;i(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
unsigned char **matrix;&lt;br /&gt;
&lt;br /&gt;
struct_M&#039;i make_M&#039;i(Mi) {&lt;br /&gt;
    struct_M&#039;i M&#039;i;&lt;br /&gt;
    for (auto x: Mi) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
            if (check_h(x) &amp;amp;&amp;amp; !eq(x, i)) {&lt;br /&gt;
                M&#039;i.push_back(x.add(i));&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return M&#039;i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct_Mi make_Mi(M&#039;i) {&lt;br /&gt;
    struct_Mi Mi;&lt;br /&gt;
    for (auto x: M&#039;i) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
           Mi.push_back(x.add(i));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return Mi;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    //заполнение матрицы смежности&lt;br /&gt;
    init_automorphisms(matrix);&lt;br /&gt;
&lt;br /&gt;
    //распараллеливание&lt;br /&gt;
    switch(process) {&lt;br /&gt;
    case 0:&lt;br /&gt;
        begin = 0;&lt;br /&gt;
        end = stop_0;&lt;br /&gt;
    case 1:&lt;br /&gt;
        begin = start_1;&lt;br /&gt;
        end = stop_1;&lt;br /&gt;
    ...&lt;br /&gt;
    case N:&lt;br /&gt;
        begin = start_n;&lt;br /&gt;
        end = M_0.size();&lt;br /&gt;
&lt;br /&gt;
    //основной цикл&lt;br /&gt;
    for (i = begin; i &amp;lt; end; ++i) {&lt;br /&gt;
        Mi = make_Mi(M&#039;i-1);&lt;br /&gt;
        M&#039;i = make_M&#039;i(Mi);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //сохранение результата (вывод автоморфизмов)&lt;br /&gt;
    final_automorphism(M&#039;i);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Проведём исследование масштабируемости параллельной реализации разложения Холецкого согласно [[Scalability methodology|методике]]. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [4 : 256] с шагом 4;&lt;br /&gt;
*	размер матрицы [1024 : 5120].&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон [[Глоссарий#Эффективность реализации|эффективности реализации]] алгоритма:&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0,11%;&lt;br /&gt;
*	максимальная эффективность реализации 2,65%.&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики [[Глоссарий#Производительность|производительности]] и эффективности выбранной реализации разложения Холецкого в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:Масштабируемость Параллельной реализации метода Холецкого Производительность3.png|thumb|center|700px|Рисунок 8. Параллельная реализация метода Холецкого. Изменение производительности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
[[file:Холецкий масштабируемость эффективность2.png|thumb|center|700px|Рисунок 9. Параллельная реализация метода Холецкого. Изменение эффективности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
&lt;br /&gt;
Построим оценки масштабируемости выбранной реализации разложения Холецкого:&lt;br /&gt;
*	По числу процессов: -0,000593. При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска уменьшается, однако в целом уменьшение не очень быстрое. Малая интенсивность изменения объясняется крайне низкой общей эффективностью работы приложения с максимумом в 2,65%, и значение эффективности на рассмотренной области значений быстро доходит до десятых долей процента. Это свидетельствует о том, что на большей части области значений нет интенсивного снижения эффективности. Это объясняется также тем, что с ростом [[Глоссарий#Вычислительная сложность|вычислительной сложности]] падение эффективности становится не таким быстрым. Уменьшение эффективности на рассмотренной области работы параллельной программы объясняется быстрым ростом накладных расходов на организацию параллельного выполнения. С ростом вычислительной сложности задачи эффективность снижается так же быстро, но при больших значениях числа процессов. Это подтверждает предположение о том, что накладные расходы начинают сильно превалировать над вычислениями.&lt;br /&gt;
*	По размеру задачи: 0,06017. При увеличении размера задачи эффективность возрастает. Эффективность возрастает тем быстрее, чем большее число процессов используется для выполнения. Это подтверждает предположение о том, что размер задачи сильно влияет на эффективность выполнения приложения. Оценка показывает, что с ростом размера задачи эффективность на рассмотренной области значений параметров запуска сильно увеличивается. Также, учитывая разницу максимальной и минимальной эффективности в 2,5%, можно сделать вывод, что рост эффективности при увеличении размера задачи наблюдается на большей части рассмотренной области значений.&lt;br /&gt;
*	По двум направлениям: 0,000403. При рассмотрении увеличения как вычислительной сложности, так и числа процессов на всей рассмотренной области значений эффективность увеличивается, однако скорость увеличения эффективности небольшая. В совокупности с тем фактом, что разница между максимальной и минимальной эффективностью на рассмотренной области значений параметров небольшая, эффективность с увеличением масштабов возрастает, но медленно и с небольшими перепадами.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Информация о реализациях данного алгоритма не найдена. При анализе алгоритма было разработано 2 программы: &amp;lt;br/&amp;gt; &lt;br /&gt;
&lt;br /&gt;
:1) приложение с графическим интерфейсом, написанное на &#039;&#039;&#039;Qt&#039;&#039;&#039;&lt;br /&gt;
:::* не поддерживает распараллеливание&lt;br /&gt;
:::* справляется с графами размера до 500 вершин&lt;br /&gt;
:::* удобный анализ графов&lt;br /&gt;
:::* помимо нахождения автоморфизмов, решает задачи изоморфизма и гомоморфизма графов&lt;br /&gt;
:2) программа на языки &#039;&#039;&#039;C++&#039;&#039;&#039; с поддержкой &#039;&#039;&#039;OpenMPI&#039;&#039;&#039;&lt;br /&gt;
:::* поддерживает распараллеливание средствами OpenMPI&lt;br /&gt;
:::* помимо нахождения автоморфизмов, сохраняет много информации для анализа графов с большим количеством вершин&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=24696</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=24696"/>
		<updated>2017-11-30T18:48:38Z</updated>

		<summary type="html">&lt;p&gt;Full: /* Вычислительное ядро алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&amp;lt;br&amp;gt;&lt;br /&gt;
Автор статьи: Ефремов С.С. (группа 419)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром алгоритма является последовательность множеств  &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;. Вычисляется на основе соответствующих &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt;. Построение &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt; занимает несущественную часть времени.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Каждое множество &amp;lt;math&amp;gt; M_i (i = 2 \ldots n) &amp;lt;/math&amp;gt; вычисляется из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; путем добавления в каждый элемент (частичная перестановка, представленная вектором целых чисел) из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; всех возможных оставшихся чисел, которых нет в соответствующем элементе.&lt;br /&gt;
&lt;br /&gt;
Для этого удобно использовать 2 не фиксированных по количеству строк двумерных массива размера t на n (t может увеличиваться), хранящих частичные отображения, такого вида: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
a_{11} &amp;amp; a_{12} &amp;amp; \ldots &amp;amp;a_{1i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
a_{21} &amp;amp; a_{22} &amp;amp; \ldots &amp;amp;a_{2i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
a_{k1} &amp;amp; a_{k2} &amp;amp; \ldots &amp;amp;a_{ki} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
? - эти значения не известны и заполняются постепенно.&lt;br /&gt;
&lt;br /&gt;
Один массив для &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt;, другой для вычисления из предыдущего &amp;lt;math&amp;gt; M_i &amp;lt;/math&amp;gt;.&lt;br /&gt;
Из каждой строки множества &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; (первый массив), в соответствие с алгоритмом, получается &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; новых строк длины i, которые записываются во второй массив (расширяется, если нужно).&lt;br /&gt;
&lt;br /&gt;
После этого, второй массив копируется в первый и запускается цикл по всем векторам. Вектор исключается из массива, если &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; равен какому-либо числу в данном векторе или вектор с &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; является частичной перестановкой, не удовлетворяющей критерию;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Схема реализации представлена на языке C++&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#define GRAPH_SIZE 300&lt;br /&gt;
#define ROW_ARR_SIZE 10000 &lt;br /&gt;
#define COL_ARR_SIZE GRAPH_SIZE&lt;br /&gt;
&lt;br /&gt;
const int N = GRAPH_SIZE;&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; Mi(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; M&#039;i(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
unsigned char **matrix;&lt;br /&gt;
&lt;br /&gt;
struct_M&#039;i make_M&#039;i(Mi) {&lt;br /&gt;
    struct_M&#039;i M&#039;i;&lt;br /&gt;
    for (auto x: Mi) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
            if (check_h(x) &amp;amp;&amp;amp; !eq(x, i)) {&lt;br /&gt;
                M&#039;i.push_back(x.add(i));&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return M&#039;i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct_Mi make_Mi(M&#039;i) {&lt;br /&gt;
    struct_Mi Mi;&lt;br /&gt;
    for (auto x: M&#039;i) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
           Mi.push_back(x.add(i));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return Mi;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    //заполнение матрицы смежности&lt;br /&gt;
    init_automorphisms(matrix);&lt;br /&gt;
&lt;br /&gt;
    //распараллеливание&lt;br /&gt;
    switch(process) {&lt;br /&gt;
    case 0:&lt;br /&gt;
        begin = 0;&lt;br /&gt;
        end = stop_0;&lt;br /&gt;
    case 1:&lt;br /&gt;
        begin = start_1;&lt;br /&gt;
        end = stop_1;&lt;br /&gt;
    ...&lt;br /&gt;
    case N:&lt;br /&gt;
        begin = start_n;&lt;br /&gt;
        end = M_0.size();&lt;br /&gt;
&lt;br /&gt;
    //основной цикл&lt;br /&gt;
    for (i = begin; i &amp;lt; end; ++i) {&lt;br /&gt;
        Mi = make_Mi(M&#039;i-1);&lt;br /&gt;
        M&#039;i = make_M&#039;i(Mi);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //сохранение результата (вывод автоморфизмов)&lt;br /&gt;
    final_automorphism(M&#039;i);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Информация о реализациях данного алгоритма не найдена. При анализе алгоритма было разработано 2 программы: &amp;lt;br/&amp;gt; &lt;br /&gt;
&lt;br /&gt;
:1) приложение с графическим интерфейсом, написанное на &#039;&#039;&#039;Qt&#039;&#039;&#039;&lt;br /&gt;
:::* не поддерживает распараллеливание&lt;br /&gt;
:::* справляется с графами размера до 500 вершин&lt;br /&gt;
:::* удобный анализ графов&lt;br /&gt;
:::* помимо нахождения автоморфизмов, решает задачи изоморфизма и гомоморфизма графов&lt;br /&gt;
:2) программа на языки &#039;&#039;&#039;C++&#039;&#039;&#039; с поддержкой &#039;&#039;&#039;OpenMPI&#039;&#039;&#039;&lt;br /&gt;
:::* поддерживает распараллеливание средствами OpenMPI&lt;br /&gt;
:::* помимо нахождения автоморфизмов, сохраняет много информации для анализа графов с большим количеством вершин&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=24695</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=24695"/>
		<updated>2017-11-30T18:47:44Z</updated>

		<summary type="html">&lt;p&gt;Full: /* Схема реализации последовательного алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&amp;lt;br&amp;gt;&lt;br /&gt;
Автор статьи: Ефремов С.С. (группа 419)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром алгоритма является последовательность множеств  &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;. Вычисляется на основе соответствующих &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt;. Построение &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt; занимает не существенную часть времени.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Каждое множество &amp;lt;math&amp;gt; M_i (i = 2 \ldots n) &amp;lt;/math&amp;gt; вычисляется из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; путем добавления в каждый элемент (частичная перестановка, представленная вектором целых чисел) из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; всех возможных оставшихся чисел, которых нет в соответствующем элементе.&lt;br /&gt;
&lt;br /&gt;
Для этого удобно использовать 2 не фиксированных по количеству строк двумерных массива размера t на n (t может увеличиваться), хранящих частичные отображения, такого вида: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
a_{11} &amp;amp; a_{12} &amp;amp; \ldots &amp;amp;a_{1i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
a_{21} &amp;amp; a_{22} &amp;amp; \ldots &amp;amp;a_{2i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
a_{k1} &amp;amp; a_{k2} &amp;amp; \ldots &amp;amp;a_{ki} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
? - эти значения не известны и заполняются постепенно.&lt;br /&gt;
&lt;br /&gt;
Один массив для &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt;, другой для вычисления из предыдущего &amp;lt;math&amp;gt; M_i &amp;lt;/math&amp;gt;.&lt;br /&gt;
Из каждой строки множества &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; (первый массив), в соответствие с алгоритмом, получается &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; новых строк длины i, которые записываются во второй массив (расширяется, если нужно).&lt;br /&gt;
&lt;br /&gt;
После этого, второй массив копируется в первый и запускается цикл по всем векторам. Вектор исключается из массива, если &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; равен какому-либо числу в данном векторе или вектор с &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; является частичной перестановкой, не удовлетворяющей критерию;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Схема реализации представлена на языке C++&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#define GRAPH_SIZE 300&lt;br /&gt;
#define ROW_ARR_SIZE 10000 &lt;br /&gt;
#define COL_ARR_SIZE GRAPH_SIZE&lt;br /&gt;
&lt;br /&gt;
const int N = GRAPH_SIZE;&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; Mi(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; M&#039;i(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
unsigned char **matrix;&lt;br /&gt;
&lt;br /&gt;
struct_M&#039;i make_M&#039;i(Mi) {&lt;br /&gt;
    struct_M&#039;i M&#039;i;&lt;br /&gt;
    for (auto x: Mi) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
            if (check_h(x) &amp;amp;&amp;amp; !eq(x, i)) {&lt;br /&gt;
                M&#039;i.push_back(x.add(i));&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return M&#039;i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct_Mi make_Mi(M&#039;i) {&lt;br /&gt;
    struct_Mi Mi;&lt;br /&gt;
    for (auto x: M&#039;i) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
           Mi.push_back(x.add(i));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return Mi;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    //заполнение матрицы смежности&lt;br /&gt;
    init_automorphisms(matrix);&lt;br /&gt;
&lt;br /&gt;
    //распараллеливание&lt;br /&gt;
    switch(process) {&lt;br /&gt;
    case 0:&lt;br /&gt;
        begin = 0;&lt;br /&gt;
        end = stop_0;&lt;br /&gt;
    case 1:&lt;br /&gt;
        begin = start_1;&lt;br /&gt;
        end = stop_1;&lt;br /&gt;
    ...&lt;br /&gt;
    case N:&lt;br /&gt;
        begin = start_n;&lt;br /&gt;
        end = M_0.size();&lt;br /&gt;
&lt;br /&gt;
    //основной цикл&lt;br /&gt;
    for (i = begin; i &amp;lt; end; ++i) {&lt;br /&gt;
        Mi = make_Mi(M&#039;i-1);&lt;br /&gt;
        M&#039;i = make_M&#039;i(Mi);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //сохранение результата (вывод автоморфизмов)&lt;br /&gt;
    final_automorphism(M&#039;i);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Информация о реализациях данного алгоритма не найдена. При анализе алгоритма было разработано 2 программы: &amp;lt;br/&amp;gt; &lt;br /&gt;
&lt;br /&gt;
:1) приложение с графическим интерфейсом, написанное на &#039;&#039;&#039;Qt&#039;&#039;&#039;&lt;br /&gt;
:::* не поддерживает распараллеливание&lt;br /&gt;
:::* справляется с графами размера до 500 вершин&lt;br /&gt;
:::* удобный анализ графов&lt;br /&gt;
:::* помимо нахождения автоморфизмов, решает задачи изоморфизма и гомоморфизма графов&lt;br /&gt;
:2) программа на языки &#039;&#039;&#039;C++&#039;&#039;&#039; с поддержкой &#039;&#039;&#039;OpenMPI&#039;&#039;&#039;&lt;br /&gt;
:::* поддерживает распараллеливание средствами OpenMPI&lt;br /&gt;
:::* помимо нахождения автоморфизмов, сохраняет много информации для анализа графов с большим количеством вершин&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=24693</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=24693"/>
		<updated>2017-11-30T18:42:08Z</updated>

		<summary type="html">&lt;p&gt;Full: /* Существующие реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&amp;lt;br&amp;gt;&lt;br /&gt;
Автор статьи: Ефремов С.С. (группа 419)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром алгоритма является последовательность множеств  &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;. Вычисляется на основе соответствующих &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt;. Построение &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt; занимает не существенную часть времени.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Каждое множество &amp;lt;math&amp;gt; M_i (i = 2 \ldots n) &amp;lt;/math&amp;gt; вычисляется из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; путем добавления в каждый элемент (частичная перестановка, представленная вектором целых чисел) из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; всех возможных оставшихся чисел, которых нет в соответствующем элементе.&lt;br /&gt;
&lt;br /&gt;
Для этого удобно использовать 2 не фиксированных по количеству строк двумерных массива размера t на n (t может увеличиваться), хранящих частичные отображения, такого вида: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
a_{11} &amp;amp; a_{12} &amp;amp; \ldots &amp;amp;a_{1i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
a_{21} &amp;amp; a_{22} &amp;amp; \ldots &amp;amp;a_{2i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
a_{k1} &amp;amp; a_{k2} &amp;amp; \ldots &amp;amp;a_{ki} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
? - эти значения не известны и заполняются постепенно.&lt;br /&gt;
&lt;br /&gt;
Один массив для &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt;, другой для вычисления из предыдущего &amp;lt;math&amp;gt; M_i &amp;lt;/math&amp;gt;.&lt;br /&gt;
Из каждой строки множества &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; (первый массив), в соответствие с алгоритмом, получается &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; новых строк длины i, которые записываются во второй массив (расширяется, если нужно).&lt;br /&gt;
&lt;br /&gt;
После этого, второй массив копируется в первый и запускается цикл по всем векторам. Вектор исключается из массива, если &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; равен какому-либо числу в данном векторе или вектор с &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; является частичной перестановкой, не удовлетворяющей критерию;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Схема реализации представлена на с++&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#define GRAPH_SIZE 300&lt;br /&gt;
#define ROW_ARR_SIZE 10000 &lt;br /&gt;
#define COL_ARR_SIZE GRAPH_SIZE&lt;br /&gt;
&lt;br /&gt;
const int N = GRAPH_SIZE;&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; Mi(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; M&#039;i(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
unsigned char **matrix;&lt;br /&gt;
&lt;br /&gt;
struct_M&#039;i make_M&#039;i(Mi) {&lt;br /&gt;
    struct_M&#039;i M&#039;i;&lt;br /&gt;
    for (auto x: Mi) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
            if (check_h(x) &amp;amp;&amp;amp; !eq(x, i)) {&lt;br /&gt;
                M&#039;i.push_back(x.add(i));&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return M&#039;i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct_Mi make_Mi(M&#039;i) {&lt;br /&gt;
    struct_Mi Mi;&lt;br /&gt;
    for (auto x: M&#039;i) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
           Mi.push_back(x.add(i));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return Mi;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    //заполнение матрицы смежности&lt;br /&gt;
    init_automorphisms(matrix);&lt;br /&gt;
&lt;br /&gt;
    //распараллеливание&lt;br /&gt;
    switch(process) {&lt;br /&gt;
    case 0:&lt;br /&gt;
        begin = 0;&lt;br /&gt;
        end = stop_0;&lt;br /&gt;
    case 1:&lt;br /&gt;
        begin = start_1;&lt;br /&gt;
        end = stop_1;&lt;br /&gt;
    ...&lt;br /&gt;
    case N:&lt;br /&gt;
        begin = start_n;&lt;br /&gt;
        end = M_0.size();&lt;br /&gt;
&lt;br /&gt;
    //основной цикл&lt;br /&gt;
    for (i = begin; i &amp;lt; end; ++i) {&lt;br /&gt;
        Mi = make_Mi(M&#039;i-1);&lt;br /&gt;
        M&#039;i = make_M&#039;i(Mi);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //сохранение результата (вывод автоморфизмов)&lt;br /&gt;
    final_automorphism(M&#039;i);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Информация о реализациях данного алгоритма не найдена. При анализе алгоритма было разработано 2 программы: &amp;lt;br/&amp;gt; &lt;br /&gt;
&lt;br /&gt;
:1) приложение с графическим интерфейсом, написанное на &#039;&#039;&#039;Qt&#039;&#039;&#039;&lt;br /&gt;
:::* не поддерживает распараллеливание&lt;br /&gt;
:::* справляется с графами размера до 500 вершин&lt;br /&gt;
:::* удобный анализ графов&lt;br /&gt;
:::* помимо нахождения автоморфизмов, решает задачи изоморфизма и гомоморфизма графов&lt;br /&gt;
:2) программа на языки &#039;&#039;&#039;C++&#039;&#039;&#039; с поддержкой &#039;&#039;&#039;OpenMPI&#039;&#039;&#039;&lt;br /&gt;
:::* поддерживает распараллеливание средствами OpenMPI&lt;br /&gt;
:::* помимо нахождения автоморфизмов, сохраняет много информации для анализа графов с большим количеством вершин&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=24692</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=24692"/>
		<updated>2017-11-30T18:41:07Z</updated>

		<summary type="html">&lt;p&gt;Full: /* Существующие реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&amp;lt;br&amp;gt;&lt;br /&gt;
Автор статьи: Ефремов С.С. (группа 419)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром алгоритма является последовательность множеств  &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;. Вычисляется на основе соответствующих &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt;. Построение &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt; занимает не существенную часть времени.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Каждое множество &amp;lt;math&amp;gt; M_i (i = 2 \ldots n) &amp;lt;/math&amp;gt; вычисляется из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; путем добавления в каждый элемент (частичная перестановка, представленная вектором целых чисел) из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; всех возможных оставшихся чисел, которых нет в соответствующем элементе.&lt;br /&gt;
&lt;br /&gt;
Для этого удобно использовать 2 не фиксированных по количеству строк двумерных массива размера t на n (t может увеличиваться), хранящих частичные отображения, такого вида: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
a_{11} &amp;amp; a_{12} &amp;amp; \ldots &amp;amp;a_{1i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
a_{21} &amp;amp; a_{22} &amp;amp; \ldots &amp;amp;a_{2i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
a_{k1} &amp;amp; a_{k2} &amp;amp; \ldots &amp;amp;a_{ki} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
? - эти значения не известны и заполняются постепенно.&lt;br /&gt;
&lt;br /&gt;
Один массив для &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt;, другой для вычисления из предыдущего &amp;lt;math&amp;gt; M_i &amp;lt;/math&amp;gt;.&lt;br /&gt;
Из каждой строки множества &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; (первый массив), в соответствие с алгоритмом, получается &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; новых строк длины i, которые записываются во второй массив (расширяется, если нужно).&lt;br /&gt;
&lt;br /&gt;
После этого, второй массив копируется в первый и запускается цикл по всем векторам. Вектор исключается из массива, если &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; равен какому-либо числу в данном векторе или вектор с &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; является частичной перестановкой, не удовлетворяющей критерию;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Схема реализации представлена на с++&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#define GRAPH_SIZE 300&lt;br /&gt;
#define ROW_ARR_SIZE 10000 &lt;br /&gt;
#define COL_ARR_SIZE GRAPH_SIZE&lt;br /&gt;
&lt;br /&gt;
const int N = GRAPH_SIZE;&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; Mi(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; M&#039;i(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
unsigned char **matrix;&lt;br /&gt;
&lt;br /&gt;
struct_M&#039;i make_M&#039;i(Mi) {&lt;br /&gt;
    struct_M&#039;i M&#039;i;&lt;br /&gt;
    for (auto x: Mi) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
            if (check_h(x) &amp;amp;&amp;amp; !eq(x, i)) {&lt;br /&gt;
                M&#039;i.push_back(x.add(i));&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return M&#039;i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct_Mi make_Mi(M&#039;i) {&lt;br /&gt;
    struct_Mi Mi;&lt;br /&gt;
    for (auto x: M&#039;i) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
           Mi.push_back(x.add(i));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return Mi;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    //заполнение матрицы смежности&lt;br /&gt;
    init_automorphisms(matrix);&lt;br /&gt;
&lt;br /&gt;
    //распараллеливание&lt;br /&gt;
    switch(process) {&lt;br /&gt;
    case 0:&lt;br /&gt;
        begin = 0;&lt;br /&gt;
        end = stop_0;&lt;br /&gt;
    case 1:&lt;br /&gt;
        begin = start_1;&lt;br /&gt;
        end = stop_1;&lt;br /&gt;
    ...&lt;br /&gt;
    case N:&lt;br /&gt;
        begin = start_n;&lt;br /&gt;
        end = M_0.size();&lt;br /&gt;
&lt;br /&gt;
    //основной цикл&lt;br /&gt;
    for (i = begin; i &amp;lt; end; ++i) {&lt;br /&gt;
        Mi = make_Mi(M&#039;i-1);&lt;br /&gt;
        M&#039;i = make_M&#039;i(Mi);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //сохранение результата (вывод автоморфизмов)&lt;br /&gt;
    final_automorphism(M&#039;i);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Информация о реализациях данного алгоритма не найдена. При анализе алгоритма было разработано 2 программы: &amp;lt;br/&amp;gt; &lt;br /&gt;
&lt;br /&gt;
:1) приложение с графическим интерфейсом, написанное на &#039;&#039;&#039;Qt&#039;&#039;&#039;&lt;br /&gt;
:::* не поддерживает распараллеливание&lt;br /&gt;
:::* справляется с графами размера до 500 вершин&lt;br /&gt;
:::* удобный анализ графов&lt;br /&gt;
:::* помимо нахождения автоморфизмов, решает задачи изоморфизма и гомоморфизма графов&lt;br /&gt;
:2) программа на языки &#039;&#039;&#039;C++&#039;&#039;&#039; с поддержкой &#039;&#039;&#039;OpenMPI&#039;&#039;&#039;&lt;br /&gt;
:::* поддерживает распараллеливание средствами OpenMPI&lt;br /&gt;
:::* помимо нахождения автоморфизмов, сохраняет много информации для анализа больших графов&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=24691</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=24691"/>
		<updated>2017-11-30T18:38:17Z</updated>

		<summary type="html">&lt;p&gt;Full: /* Существующие реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&amp;lt;br&amp;gt;&lt;br /&gt;
Автор статьи: Ефремов С.С. (группа 419)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром алгоритма является последовательность множеств  &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;. Вычисляется на основе соответствующих &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt;. Построение &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt; занимает не существенную часть времени.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Каждое множество &amp;lt;math&amp;gt; M_i (i = 2 \ldots n) &amp;lt;/math&amp;gt; вычисляется из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; путем добавления в каждый элемент (частичная перестановка, представленная вектором целых чисел) из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; всех возможных оставшихся чисел, которых нет в соответствующем элементе.&lt;br /&gt;
&lt;br /&gt;
Для этого удобно использовать 2 не фиксированных по количеству строк двумерных массива размера t на n (t может увеличиваться), хранящих частичные отображения, такого вида: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
a_{11} &amp;amp; a_{12} &amp;amp; \ldots &amp;amp;a_{1i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
a_{21} &amp;amp; a_{22} &amp;amp; \ldots &amp;amp;a_{2i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
a_{k1} &amp;amp; a_{k2} &amp;amp; \ldots &amp;amp;a_{ki} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
? - эти значения не известны и заполняются постепенно.&lt;br /&gt;
&lt;br /&gt;
Один массив для &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt;, другой для вычисления из предыдущего &amp;lt;math&amp;gt; M_i &amp;lt;/math&amp;gt;.&lt;br /&gt;
Из каждой строки множества &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; (первый массив), в соответствие с алгоритмом, получается &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; новых строк длины i, которые записываются во второй массив (расширяется, если нужно).&lt;br /&gt;
&lt;br /&gt;
После этого, второй массив копируется в первый и запускается цикл по всем векторам. Вектор исключается из массива, если &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; равен какому-либо числу в данном векторе или вектор с &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; является частичной перестановкой, не удовлетворяющей критерию;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Схема реализации представлена на с++&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#define GRAPH_SIZE 300&lt;br /&gt;
#define ROW_ARR_SIZE 10000 &lt;br /&gt;
#define COL_ARR_SIZE GRAPH_SIZE&lt;br /&gt;
&lt;br /&gt;
const int N = GRAPH_SIZE;&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; Mi(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; M&#039;i(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
unsigned char **matrix;&lt;br /&gt;
&lt;br /&gt;
struct_M&#039;i make_M&#039;i(Mi) {&lt;br /&gt;
    struct_M&#039;i M&#039;i;&lt;br /&gt;
    for (auto x: Mi) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
            if (check_h(x) &amp;amp;&amp;amp; !eq(x, i)) {&lt;br /&gt;
                M&#039;i.push_back(x.add(i));&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return M&#039;i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct_Mi make_Mi(M&#039;i) {&lt;br /&gt;
    struct_Mi Mi;&lt;br /&gt;
    for (auto x: M&#039;i) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
           Mi.push_back(x.add(i));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return Mi;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    //заполнение матрицы смежности&lt;br /&gt;
    init_automorphisms(matrix);&lt;br /&gt;
&lt;br /&gt;
    //распараллеливание&lt;br /&gt;
    switch(process) {&lt;br /&gt;
    case 0:&lt;br /&gt;
        begin = 0;&lt;br /&gt;
        end = stop_0;&lt;br /&gt;
    case 1:&lt;br /&gt;
        begin = start_1;&lt;br /&gt;
        end = stop_1;&lt;br /&gt;
    ...&lt;br /&gt;
    case N:&lt;br /&gt;
        begin = start_n;&lt;br /&gt;
        end = M_0.size();&lt;br /&gt;
&lt;br /&gt;
    //основной цикл&lt;br /&gt;
    for (i = begin; i &amp;lt; end; ++i) {&lt;br /&gt;
        Mi = make_Mi(M&#039;i-1);&lt;br /&gt;
        M&#039;i = make_M&#039;i(Mi);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //сохранение результата (вывод автоморфизмов)&lt;br /&gt;
    final_automorphism(M&#039;i);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Информация о реализациях данного алгоритма не найдена. При анализе алгоритма было разработано 2 программы: &amp;lt;br/&amp;gt; &lt;br /&gt;
&lt;br /&gt;
:1) приложение с графическим интерфейсом, написанное на &#039;&#039;&#039;Qt&#039;&#039;&#039;&lt;br /&gt;
:::* не поддерживает распараллеливание&lt;br /&gt;
:::* справляется с графами размера до 500 вершин&lt;br /&gt;
:::* удобный анализ графов&lt;br /&gt;
:2) программа на языки &#039;&#039;&#039;C++&#039;&#039;&#039; с поддержкой &#039;&#039;&#039;OpenMPI&#039;&#039;&#039;&lt;br /&gt;
:::* поддерживает распараллеливание средствами OpenMPI&lt;br /&gt;
:::* помимо нахождения автоморфизмов, сохраняет много информации для анализа больших графов&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=24690</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=24690"/>
		<updated>2017-11-30T18:36:33Z</updated>

		<summary type="html">&lt;p&gt;Full: /* Существующие реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&amp;lt;br&amp;gt;&lt;br /&gt;
Автор статьи: Ефремов С.С. (группа 419)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром алгоритма является последовательность множеств  &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;. Вычисляется на основе соответствующих &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt;. Построение &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt; занимает не существенную часть времени.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Каждое множество &amp;lt;math&amp;gt; M_i (i = 2 \ldots n) &amp;lt;/math&amp;gt; вычисляется из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; путем добавления в каждый элемент (частичная перестановка, представленная вектором целых чисел) из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; всех возможных оставшихся чисел, которых нет в соответствующем элементе.&lt;br /&gt;
&lt;br /&gt;
Для этого удобно использовать 2 не фиксированных по количеству строк двумерных массива размера t на n (t может увеличиваться), хранящих частичные отображения, такого вида: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
a_{11} &amp;amp; a_{12} &amp;amp; \ldots &amp;amp;a_{1i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
a_{21} &amp;amp; a_{22} &amp;amp; \ldots &amp;amp;a_{2i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
a_{k1} &amp;amp; a_{k2} &amp;amp; \ldots &amp;amp;a_{ki} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
? - эти значения не известны и заполняются постепенно.&lt;br /&gt;
&lt;br /&gt;
Один массив для &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt;, другой для вычисления из предыдущего &amp;lt;math&amp;gt; M_i &amp;lt;/math&amp;gt;.&lt;br /&gt;
Из каждой строки множества &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; (первый массив), в соответствие с алгоритмом, получается &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; новых строк длины i, которые записываются во второй массив (расширяется, если нужно).&lt;br /&gt;
&lt;br /&gt;
После этого, второй массив копируется в первый и запускается цикл по всем векторам. Вектор исключается из массива, если &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; равен какому-либо числу в данном векторе или вектор с &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; является частичной перестановкой, не удовлетворяющей критерию;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Схема реализации представлена на с++&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#define GRAPH_SIZE 300&lt;br /&gt;
#define ROW_ARR_SIZE 10000 &lt;br /&gt;
#define COL_ARR_SIZE GRAPH_SIZE&lt;br /&gt;
&lt;br /&gt;
const int N = GRAPH_SIZE;&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; Mi(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; M&#039;i(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
unsigned char **matrix;&lt;br /&gt;
&lt;br /&gt;
struct_M&#039;i make_M&#039;i(Mi) {&lt;br /&gt;
    struct_M&#039;i M&#039;i;&lt;br /&gt;
    for (auto x: Mi) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
            if (check_h(x) &amp;amp;&amp;amp; !eq(x, i)) {&lt;br /&gt;
                M&#039;i.push_back(x.add(i));&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return M&#039;i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct_Mi make_Mi(M&#039;i) {&lt;br /&gt;
    struct_Mi Mi;&lt;br /&gt;
    for (auto x: M&#039;i) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
           Mi.push_back(x.add(i));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return Mi;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    //заполнение матрицы смежности&lt;br /&gt;
    init_automorphisms(matrix);&lt;br /&gt;
&lt;br /&gt;
    //распараллеливание&lt;br /&gt;
    switch(process) {&lt;br /&gt;
    case 0:&lt;br /&gt;
        begin = 0;&lt;br /&gt;
        end = stop_0;&lt;br /&gt;
    case 1:&lt;br /&gt;
        begin = start_1;&lt;br /&gt;
        end = stop_1;&lt;br /&gt;
    ...&lt;br /&gt;
    case N:&lt;br /&gt;
        begin = start_n;&lt;br /&gt;
        end = M_0.size();&lt;br /&gt;
&lt;br /&gt;
    //основной цикл&lt;br /&gt;
    for (i = begin; i &amp;lt; end; ++i) {&lt;br /&gt;
        Mi = make_Mi(M&#039;i-1);&lt;br /&gt;
        M&#039;i = make_M&#039;i(Mi);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //сохранение результата (вывод автоморфизмов)&lt;br /&gt;
    final_automorphism(M&#039;i);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Информация о реализациях данного алгоритма не найдена. При анализе алгоритма было разработано 2 программы: &amp;lt;br/&amp;gt; &lt;br /&gt;
&lt;br /&gt;
:1) приложение с графическим интерфейсом, написанное на &#039;&#039;&#039;Qt&#039;&#039;&#039;&lt;br /&gt;
:::* не поддерживает распараллеливание&lt;br /&gt;
:::* справляется с графами размера до 500 вершин&lt;br /&gt;
:::* удобный анализ графов&lt;br /&gt;
:2) программа на языки &#039;&#039;&#039;C++&#039;&#039;&#039; с поддержкой &#039;&#039;&#039;OpenMPI&#039;&#039;&#039;&lt;br /&gt;
:::* поддерживает распараллеливание средствами OpenMPI&lt;br /&gt;
:::* сохраняет много информации для анализа больших графов&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=24689</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=24689"/>
		<updated>2017-11-30T18:36:17Z</updated>

		<summary type="html">&lt;p&gt;Full: /* Существующие реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&amp;lt;br&amp;gt;&lt;br /&gt;
Автор статьи: Ефремов С.С. (группа 419)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром алгоритма является последовательность множеств  &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;. Вычисляется на основе соответствующих &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt;. Построение &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt; занимает не существенную часть времени.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Каждое множество &amp;lt;math&amp;gt; M_i (i = 2 \ldots n) &amp;lt;/math&amp;gt; вычисляется из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; путем добавления в каждый элемент (частичная перестановка, представленная вектором целых чисел) из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; всех возможных оставшихся чисел, которых нет в соответствующем элементе.&lt;br /&gt;
&lt;br /&gt;
Для этого удобно использовать 2 не фиксированных по количеству строк двумерных массива размера t на n (t может увеличиваться), хранящих частичные отображения, такого вида: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
a_{11} &amp;amp; a_{12} &amp;amp; \ldots &amp;amp;a_{1i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
a_{21} &amp;amp; a_{22} &amp;amp; \ldots &amp;amp;a_{2i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
a_{k1} &amp;amp; a_{k2} &amp;amp; \ldots &amp;amp;a_{ki} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
? - эти значения не известны и заполняются постепенно.&lt;br /&gt;
&lt;br /&gt;
Один массив для &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt;, другой для вычисления из предыдущего &amp;lt;math&amp;gt; M_i &amp;lt;/math&amp;gt;.&lt;br /&gt;
Из каждой строки множества &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; (первый массив), в соответствие с алгоритмом, получается &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; новых строк длины i, которые записываются во второй массив (расширяется, если нужно).&lt;br /&gt;
&lt;br /&gt;
После этого, второй массив копируется в первый и запускается цикл по всем векторам. Вектор исключается из массива, если &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; равен какому-либо числу в данном векторе или вектор с &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; является частичной перестановкой, не удовлетворяющей критерию;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Схема реализации представлена на с++&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#define GRAPH_SIZE 300&lt;br /&gt;
#define ROW_ARR_SIZE 10000 &lt;br /&gt;
#define COL_ARR_SIZE GRAPH_SIZE&lt;br /&gt;
&lt;br /&gt;
const int N = GRAPH_SIZE;&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; Mi(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; M&#039;i(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
unsigned char **matrix;&lt;br /&gt;
&lt;br /&gt;
struct_M&#039;i make_M&#039;i(Mi) {&lt;br /&gt;
    struct_M&#039;i M&#039;i;&lt;br /&gt;
    for (auto x: Mi) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
            if (check_h(x) &amp;amp;&amp;amp; !eq(x, i)) {&lt;br /&gt;
                M&#039;i.push_back(x.add(i));&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return M&#039;i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct_Mi make_Mi(M&#039;i) {&lt;br /&gt;
    struct_Mi Mi;&lt;br /&gt;
    for (auto x: M&#039;i) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
           Mi.push_back(x.add(i));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return Mi;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    //заполнение матрицы смежности&lt;br /&gt;
    init_automorphisms(matrix);&lt;br /&gt;
&lt;br /&gt;
    //распараллеливание&lt;br /&gt;
    switch(process) {&lt;br /&gt;
    case 0:&lt;br /&gt;
        begin = 0;&lt;br /&gt;
        end = stop_0;&lt;br /&gt;
    case 1:&lt;br /&gt;
        begin = start_1;&lt;br /&gt;
        end = stop_1;&lt;br /&gt;
    ...&lt;br /&gt;
    case N:&lt;br /&gt;
        begin = start_n;&lt;br /&gt;
        end = M_0.size();&lt;br /&gt;
&lt;br /&gt;
    //основной цикл&lt;br /&gt;
    for (i = begin; i &amp;lt; end; ++i) {&lt;br /&gt;
        Mi = make_Mi(M&#039;i-1);&lt;br /&gt;
        M&#039;i = make_M&#039;i(Mi);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //сохранение результата (вывод автоморфизмов)&lt;br /&gt;
    final_automorphism(M&#039;i);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Информация о реализациях данного алгоритма не найдена. При анализе алгоритма было разработано 2 программы: &amp;lt;br/&amp;gt; &lt;br /&gt;
&lt;br /&gt;
:1) приложение с графическим интерфейсом, написанное на &#039;&#039;&#039;Qt&#039;&#039;&#039;&lt;br /&gt;
:::* не поддерживает распараллеливание&lt;br /&gt;
:::* справляется с графами размера до 500 вершин&lt;br /&gt;
:::* удобный анализ графов&lt;br /&gt;
:2) программа на языки &#039;&#039;&#039;с++&#039;&#039;&#039; с поддержкой &#039;&#039;&#039;OpenMPI&#039;&#039;&#039;&lt;br /&gt;
:::* поддерживает распараллеливание средствами OpenMPI&lt;br /&gt;
:::* сохраняет много информации для анализа больших графов&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=24673</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=24673"/>
		<updated>2017-11-30T16:19:17Z</updated>

		<summary type="html">&lt;p&gt;Full: /* Схема реализации последовательного алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&amp;lt;br&amp;gt;&lt;br /&gt;
Автор статьи: Ефремов С.С. (группа 419)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром алгоритма является последовательность множеств  &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;. Вычисляется на основе соответствующих &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt;. Построение &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt; занимает не существенную часть времени.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Каждое множество &amp;lt;math&amp;gt; M_i (i = 2 \ldots n) &amp;lt;/math&amp;gt; вычисляется из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; путем добавления в каждый элемент (частичная перестановка, представленная вектором целых чисел) из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; всех возможных оставшихся чисел, которых нет в соответствующем элементе.&lt;br /&gt;
&lt;br /&gt;
Для этого удобно использовать 2 не фиксированных по количеству строк двумерных массива размера t на n (t может увеличиваться), хранящих частичные отображения, такого вида: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
a_{11} &amp;amp; a_{12} &amp;amp; \ldots &amp;amp;a_{1i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
a_{21} &amp;amp; a_{22} &amp;amp; \ldots &amp;amp;a_{2i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
a_{k1} &amp;amp; a_{k2} &amp;amp; \ldots &amp;amp;a_{ki} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
? - эти значения не известны и заполняются постепенно.&lt;br /&gt;
&lt;br /&gt;
Один массив для &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt;, другой для вычисления из предыдущего &amp;lt;math&amp;gt; M_i &amp;lt;/math&amp;gt;.&lt;br /&gt;
Из каждой строки множества &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; (первый массив), в соответствие с алгоритмом, получается &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; новых строк длины i, которые записываются во второй массив (расширяется, если нужно).&lt;br /&gt;
&lt;br /&gt;
После этого, второй массив копируется в первый и запускается цикл по всем векторам. Вектор исключается из массива, если &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; равен какому-либо числу в данном векторе или вектор с &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; является частичной перестановкой, не удовлетворяющей критерию;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Схема реализации представлена на с++&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#define GRAPH_SIZE 300&lt;br /&gt;
#define ROW_ARR_SIZE 10000 &lt;br /&gt;
#define COL_ARR_SIZE GRAPH_SIZE&lt;br /&gt;
&lt;br /&gt;
const int N = GRAPH_SIZE;&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; Mi(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; M&#039;i(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
unsigned char **matrix;&lt;br /&gt;
&lt;br /&gt;
struct_M&#039;i make_M&#039;i(Mi) {&lt;br /&gt;
    struct_M&#039;i M&#039;i;&lt;br /&gt;
    for (auto x: Mi) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
            if (check_h(x) &amp;amp;&amp;amp; !eq(x, i)) {&lt;br /&gt;
                M&#039;i.push_back(x.add(i));&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return M&#039;i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct_Mi make_Mi(M&#039;i) {&lt;br /&gt;
    struct_Mi Mi;&lt;br /&gt;
    for (auto x: M&#039;i) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
           Mi.push_back(x.add(i));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return Mi;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    //заполнение матрицы смежности&lt;br /&gt;
    init_automorphisms(matrix);&lt;br /&gt;
&lt;br /&gt;
    //распараллеливание&lt;br /&gt;
    switch(process) {&lt;br /&gt;
    case 0:&lt;br /&gt;
        begin = 0;&lt;br /&gt;
        end = stop_0;&lt;br /&gt;
    case 1:&lt;br /&gt;
        begin = start_1;&lt;br /&gt;
        end = stop_1;&lt;br /&gt;
    ...&lt;br /&gt;
    case N:&lt;br /&gt;
        begin = start_n;&lt;br /&gt;
        end = M_0.size();&lt;br /&gt;
&lt;br /&gt;
    //основной цикл&lt;br /&gt;
    for (i = begin; i &amp;lt; end; ++i) {&lt;br /&gt;
        Mi = make_Mi(M&#039;i-1);&lt;br /&gt;
        M&#039;i = make_M&#039;i(Mi);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //сохранение результата (вывод автоморфизмов)&lt;br /&gt;
    final_automorphism(M&#039;i);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=24656</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=24656"/>
		<updated>2017-11-30T15:43:52Z</updated>

		<summary type="html">&lt;p&gt;Full: /* Схема реализации последовательного алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&amp;lt;br&amp;gt;&lt;br /&gt;
Автор статьи: Ефремов С.С. (группа 419)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром алгоритма является последовательность множеств  &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;. Вычисляется на основе соответствующих &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt;. Построение &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt; занимает не существенную часть времени.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Каждое множество &amp;lt;math&amp;gt; M_i (i = 2 \ldots n) &amp;lt;/math&amp;gt; вычисляется из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; путем добавления в каждый элемент (частичная перестановка, представленная вектором целых чисел) из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; всех возможных оставшихся чисел, которых нет в соответствующем элементе.&lt;br /&gt;
&lt;br /&gt;
Для этого удобно использовать 2 не фиксированных по количеству строк двумерных массива размера t на n (t может увеличиваться), хранящих частичные отображения, такого вида: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
a_{11} &amp;amp; a_{12} &amp;amp; \ldots &amp;amp;a_{1i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
a_{21} &amp;amp; a_{22} &amp;amp; \ldots &amp;amp;a_{2i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
a_{k1} &amp;amp; a_{k2} &amp;amp; \ldots &amp;amp;a_{ki} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
? - эти значения не известны и заполняются постепенно.&lt;br /&gt;
&lt;br /&gt;
Один массив для &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt;, другой для вычисления из предыдущего &amp;lt;math&amp;gt; M_i &amp;lt;/math&amp;gt;.&lt;br /&gt;
Из каждой строки множества &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; (первый массив), в соответствие с алгоритмом, получается &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; новых строк длины i, которые записываются во второй массив (расширяется, если нужно).&lt;br /&gt;
&lt;br /&gt;
После этого, второй массив копируется в первый и запускается цикл по всем векторам. Вектор исключается из массива, если &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; равен какому-либо числу в данном векторе или вектор с &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; является частичной перестановкой, не удовлетворяющей критерию;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Схема реализации представлена на с++&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
#define GRAPH_SIZE 300&lt;br /&gt;
#define ROW_ARR_SIZE 10000 &lt;br /&gt;
#define COL_ARR_SIZE GRAPH_SIZE&lt;br /&gt;
&lt;br /&gt;
const int N = GRAPH_SIZE;&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; Mi(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; M&#039;i(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
unsigned char **matrix;&lt;br /&gt;
&lt;br /&gt;
struct_M&#039;i make_M&#039;i(Mi) {&lt;br /&gt;
    struct_M&#039;i M&#039;i;&lt;br /&gt;
    for (auto x: Mi) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
            if (check_h(x) &amp;amp;&amp;amp; !eq(x, i)) {&lt;br /&gt;
                M&#039;i.push_back(x.add(i));&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return M&#039;i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct_Mi make_Mi(M&#039;i) {&lt;br /&gt;
    struct_Mi Mi;&lt;br /&gt;
    for (auto x: M&#039;i) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
           Mi.push_back(x.add(i));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return Mi;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    //заполняется матрица смежности&lt;br /&gt;
    init_automorphisms(matrix);&lt;br /&gt;
&lt;br /&gt;
    //распараллеливание&lt;br /&gt;
    switch(process) {&lt;br /&gt;
    case 0:&lt;br /&gt;
        begin = 0;&lt;br /&gt;
        end = stop_0;&lt;br /&gt;
    case 1:&lt;br /&gt;
        begin = start_1;&lt;br /&gt;
        end = stop_1;&lt;br /&gt;
    ...&lt;br /&gt;
    case N:&lt;br /&gt;
        begin = start_n;&lt;br /&gt;
        end = M_0.size();&lt;br /&gt;
&lt;br /&gt;
    //основной цикл&lt;br /&gt;
    for (i = begin; i &amp;lt; end; ++i) {&lt;br /&gt;
        Mi = make_Mi(M&#039;i-1);&lt;br /&gt;
        M&#039;i = make_M&#039;i(Mi);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //сохранение результата (вывод автоморфизмов)&lt;br /&gt;
    final_automorphism(M&#039;i);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=24649</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=24649"/>
		<updated>2017-11-30T15:18:28Z</updated>

		<summary type="html">&lt;p&gt;Full: /* Схема реализации последовательного алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&amp;lt;br&amp;gt;&lt;br /&gt;
Автор статьи: Ефремов С.С. (группа 419)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром алгоритма является последовательность множеств  &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;. Вычисляется на основе соответствующих &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt;. Построение &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt; занимает не существенную часть времени.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Каждое множество &amp;lt;math&amp;gt; M_i (i = 2 \ldots n) &amp;lt;/math&amp;gt; вычисляется из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; путем добавления в каждый элемент (частичная перестановка, представленная вектором целых чисел) из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; всех возможных оставшихся чисел, которых нет в соответствующем элементе.&lt;br /&gt;
&lt;br /&gt;
Для этого удобно использовать 2 не фиксированных по количеству строк двумерных массива размера t на n (t может увеличиваться), хранящих частичные отображения, такого вида: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
a_{11} &amp;amp; a_{12} &amp;amp; \ldots &amp;amp;a_{1i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
a_{21} &amp;amp; a_{22} &amp;amp; \ldots &amp;amp;a_{2i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
a_{k1} &amp;amp; a_{k2} &amp;amp; \ldots &amp;amp;a_{ki} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
? - эти значения не известны и заполняются постепенно.&lt;br /&gt;
&lt;br /&gt;
Один массив для &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt;, другой для вычисления из предыдущего &amp;lt;math&amp;gt; M_i &amp;lt;/math&amp;gt;.&lt;br /&gt;
Из каждой строки множества &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; (первый массив), в соответствие с алгоритмом, получается &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; новых строк длины i, которые записываются во второй массив (расширяется, если нужно).&lt;br /&gt;
&lt;br /&gt;
После этого, второй массив копируется в первый и запускается цикл по всем векторам. Вектор исключается из массива, если &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; равен какому-либо числу в данном векторе или вектор с &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; является частичной перестановкой, не удовлетворяющей критерию;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Можно представить простым псевдокодом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt; &lt;br /&gt;
#define GRAPH_SIZE 300&lt;br /&gt;
#define ROW_ARR_SIZE 10000 &lt;br /&gt;
#define COL_ARR_SIZE GRAPH_SIZE&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; Mi(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
vector&amp;lt;array&amp;lt;unsigned short,COL_ARR_SIZE&amp;gt;&amp;gt; M&#039;i(ROW_ARR_SIZE, COL_ARR_SIZE);&lt;br /&gt;
const int N = GRAPH_SIZE;&lt;br /&gt;
&lt;br /&gt;
unsigned char **matrix;&lt;br /&gt;
&lt;br /&gt;
struct_M&#039;i make_M&#039;i(Mi) {&lt;br /&gt;
    struct_M&#039;i M&#039;i;&lt;br /&gt;
    for (auto x: Mi) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
            if (check_h(x) &amp;amp;&amp;amp; !eq(x, i)) {&lt;br /&gt;
                M&#039;i.push_back(x.add(i));&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return M&#039;i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct_Mi make_Mi(M&#039;i) {&lt;br /&gt;
    struct_Mi Mi;&lt;br /&gt;
    for (auto x: M&#039;i) {&lt;br /&gt;
        for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
           Mi.push_back(x.add(i));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return Mi;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
&lt;br /&gt;
    //заполняется матрица смежности&lt;br /&gt;
    init_automorphisms(matrix);&lt;br /&gt;
&lt;br /&gt;
    //распараллеливание&lt;br /&gt;
    switch(process) {&lt;br /&gt;
    case 0:&lt;br /&gt;
        begin = 0;&lt;br /&gt;
        end = stop_0;&lt;br /&gt;
    case 1:&lt;br /&gt;
        begin = start_1;&lt;br /&gt;
        end = stop_1;&lt;br /&gt;
    ...&lt;br /&gt;
    case N:&lt;br /&gt;
        begin = start_n;&lt;br /&gt;
        end = M_0.size();&lt;br /&gt;
&lt;br /&gt;
    //основной цикл&lt;br /&gt;
    for (i = begin; i &amp;lt; end; ++i) {&lt;br /&gt;
        Mi = make_Mi(M&#039;i-1);&lt;br /&gt;
        M&#039;i = make_M&#039;i(Mi);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //сохранение результата (вывод автоморфизмов)&lt;br /&gt;
    final_automorphism(M&#039;i);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=24636</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=24636"/>
		<updated>2017-11-30T13:04:47Z</updated>

		<summary type="html">&lt;p&gt;Full: /* Макроструктура алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&amp;lt;br&amp;gt;&lt;br /&gt;
Автор статьи: Ефремов С.С. (группа 419)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром алгоритма является последовательность множеств  &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;. Вычисляется на основе соответствующих &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt;. Построение &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt; занимает не существенную часть времени.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Каждое множество &amp;lt;math&amp;gt; M_i (i = 2 \ldots n) &amp;lt;/math&amp;gt; вычисляется из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; путем добавления в каждый элемент (частичная перестановка, представленная вектором целых чисел) из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; всех возможных оставшихся чисел, которых нет в соответствующем элементе.&lt;br /&gt;
&lt;br /&gt;
Для этого удобно использовать 2 не фиксированных по количеству строк двумерных массива размера t на n (t может увеличиваться), хранящих частичные отображения, такого вида: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
a_{11} &amp;amp; a_{12} &amp;amp; \ldots &amp;amp;a_{1i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
a_{21} &amp;amp; a_{22} &amp;amp; \ldots &amp;amp;a_{2i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
a_{k1} &amp;amp; a_{k2} &amp;amp; \ldots &amp;amp;a_{ki} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
? - эти значения не известны и заполняются постепенно.&lt;br /&gt;
&lt;br /&gt;
Один массив для &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt;, другой для вычисления из предыдущего &amp;lt;math&amp;gt; M_i &amp;lt;/math&amp;gt;.&lt;br /&gt;
Из каждой строки множества &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; (первый массив), в соответствие с алгоритмом, получается &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; новых строк длины i, которые записываются во второй массив (расширяется, если нужно).&lt;br /&gt;
&lt;br /&gt;
После этого, второй массив копируется в первый и запускается цикл по всем векторам. Вектор исключается из массива, если &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; равен какому-либо числу в данном векторе или вектор с &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; является частичной перестановкой, не удовлетворяющей критерию;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=24635</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=24635"/>
		<updated>2017-11-30T13:03:44Z</updated>

		<summary type="html">&lt;p&gt;Full: /* Макроструктура алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&amp;lt;br&amp;gt;&lt;br /&gt;
Автор статьи: Ефремов С.С. (группа 419)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром алгоритма является последовательность множеств  &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;. Вычисляется на основе соответствующих &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt;. Построение &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt; занимает не существенную часть времени.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Каждое множество &amp;lt;math&amp;gt; M_i (i = 2 \ldots n) &amp;lt;/math&amp;gt; вычисляется из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; путем добавления в каждый элемент (частичная перестановка, представленная вектором целых чисел) из &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; всех возможных оставшихся чисел, которых нет в соответствующем элементе.&lt;br /&gt;
&lt;br /&gt;
Для этого удобно использовать 2 не фиксированных по количеству строк двумерных массива размера t на n (t может увеличиваться), хранящих частичные отображения, такого вида: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
a_{11} &amp;amp; a_{12} &amp;amp; \ldots &amp;amp;a_{1i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
a_{21} &amp;amp; a_{22} &amp;amp; \ldots &amp;amp;a_{2i} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
a_{k1} &amp;amp; a_{k2} &amp;amp; \ldots &amp;amp;a_{ki} &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\ldots \cr&lt;br /&gt;
?      &amp;amp; ?      &amp;amp; \ldots &amp;amp;   ?   &amp;amp; ? &amp;amp; \ldots &amp;amp; ? \cr&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
? - эти значения не известны и заполняются постепенно.&lt;br /&gt;
&lt;br /&gt;
Один массив для &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt;, другой для вычисления из предыдущего &amp;lt;math&amp;gt; M_i &amp;lt;/math&amp;gt;.&lt;br /&gt;
Из каждой строки множества &amp;lt;math&amp;gt; M&#039;_{i-1} &amp;lt;/math&amp;gt; (первый массив), в соответствие с алгоритмом, получается &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; новых строк длины i, которые записываются во второй массив (расширяется, если нужно).&lt;br /&gt;
&lt;br /&gt;
После этого, второй массив копируется в первый и запускается цикл по всем векторам. Вектор исключается из массива, если:&lt;br /&gt;
1) &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; равен какому-либо числу в данном векторе;&lt;br /&gt;
2) вектор с &amp;lt;math&amp;gt; a_{ji} &amp;lt;/math&amp;gt; является частичной перестановкой, не удовлетворяющей критерию;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=24633</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=24633"/>
		<updated>2017-11-30T12:10:18Z</updated>

		<summary type="html">&lt;p&gt;Full: /* Вычислительное ядро алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&amp;lt;br&amp;gt;&lt;br /&gt;
Автор статьи: Ефремов С.С. (группа 419)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром алгоритма является последовательность множеств  &amp;lt;math&amp;gt;M&#039;_1 \ldots M&#039;_n&amp;lt;/math&amp;gt;. Вычисляется на основе соответствующих &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt;. Построение &amp;lt;math&amp;gt;M_1 \ldots M_n&amp;lt;/math&amp;gt; занимает не существенную часть времени.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=24623</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=24623"/>
		<updated>2017-11-30T10:25:37Z</updated>

		<summary type="html">&lt;p&gt;Full: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&amp;lt;br&amp;gt;&lt;br /&gt;
Автор статьи: Ефремов С.С. (группа 419)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=23667</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=23667"/>
		<updated>2017-10-30T14:34:03Z</updated>

		<summary type="html">&lt;p&gt;Full: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&amp;lt;br&amp;gt;&lt;br /&gt;
Автор статьи: Ефремов С.С. (группа 419)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=23666</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=23666"/>
		<updated>2017-10-30T14:33:29Z</updated>

		<summary type="html">&lt;p&gt;Full: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&amp;lt;br&amp;gt;&lt;br /&gt;
Автор статьи: Ефремов С.С. группа 419&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=23665</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=23665"/>
		<updated>2017-10-30T14:33:16Z</updated>

		<summary type="html">&lt;p&gt;Full: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&lt;br /&gt;
&lt;br /&gt;
Автор статьи: Ефремов С.С. группа 419&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=23664</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=23664"/>
		<updated>2017-10-30T14:32:56Z</updated>

		<summary type="html">&lt;p&gt;Full: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Алгоритм: Поиск автоморфизмов графов&lt;br /&gt;
Автор статьи: Ефремов С.С. группа 419&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=23663</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=23663"/>
		<updated>2017-10-30T14:26:02Z</updated>

		<summary type="html">&lt;p&gt;Full: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=23442</id>
		<title>Участник:Full/Поиск автоморфизмов графов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Full/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC%D0%BE%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=23442"/>
		<updated>2017-10-23T20:22:57Z</updated>

		<summary type="html">&lt;p&gt;Full: Новая страница: « = Свойства и структура алгоритмов =  Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Гр…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм, описанный в статье Егорова В.Н.&amp;lt;ref&amp;gt;Группы автоморфизмов и изоморфизм комбинаторных объектов и алгебраических структур. Егоров В.Н., Егоров А.В. (Ломоносовские чтения, Научная конференция, Москва, факультет ВМК МГУ имени М.В.Ломоносова).&amp;lt;/ref&amp;gt;, предназначен для поиска автоморфизмов графов, которые можно представить в виде матриц смежности, а также для исследования изоморфности графов. Так как алгоритм работает с матрицами, можно решать эти же задачи и на других комбинаторных объектах, представимых матрицами смежности&amp;lt;ref&amp;gt;О группах автоморфизмов матриц. Егоров В.Н. (журнал &amp;quot;Прикладная дискретная математика&amp;quot;).&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
На вход подается матрица смежности графа. При отображение вершины v1 в вершину v2 в соответсвующей графу матрице меняются местами строка и столбец v1 со строкой и столбцом v2. Автоморфизмом является отображение множества вершин графа на себя, сохраняющее смежность. Это есть такая перестановка строк и столбцов матрицы, после применения которой, матрица останется той же. &lt;br /&gt;
&lt;br /&gt;
В данном разделе представляется самый первый вариант описания тех задач (или классов задач), для решения которых предназначен алгоритм. В описании поясняются особенности как алгоритма, так и объектов, с которыми он работает. Если описание соответствует целому классу схожих по структуре алгоритмов, либо же посвящено описанию отдельного представителя некоторого класса, то это здесь указывается явно. Описываются базовые математические свойства и структура входных данных. При необходимости, в описании могут присутствовать формулы, а также даваться ссылки на описания других используемых алгоритмов. Данное описание должно быть достаточным для однозначного понимания сути решаемой задачи.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Определения и обозначения ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A = A^{n\times n}&amp;lt;/math&amp;gt; - матрица смежности графа &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;; &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; - элементы матрицы ,&amp;lt;math&amp;gt;\ i,j = 1,\ldots,n=|V|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Частичным отображением &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; - обозначает индекс элемента в множестве &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt;) называется подстановка вида &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{pmatrix} &lt;br /&gt;
1 &amp;amp; 2 &amp;amp; \ldots &amp;amp; k &amp;amp; k+1 &amp;amp;\ldots &amp;amp; n\cr&lt;br /&gt;
r_1 &amp;amp; r_2 &amp;amp; \ldots &amp;amp; r_k &amp;amp; q_{k+1} &amp;amp; \ldots &amp;amp; q_n&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, где &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt; - фиксированные (заданные) элементы, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; - произвольные, причем последовательность &amp;lt;math&amp;gt;r_1,\ldots,r_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_{k+1},\ldots,q_n&amp;lt;/math&amp;gt; является перестановкой вершин заданного графа.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; - множество, состоящее из элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\ s = 1,\ldots,n_k=|M_k|&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;|M_k|&amp;lt;/math&amp;gt; - количество элементов &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; в множестве.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt; - множество элементов, которые содержатся в &amp;lt;math&amp;gt;M_k&amp;lt;/math&amp;gt; и удовлетворяют критерию &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
h - критерий (описанный далее).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt; - последовательность множеств &amp;lt;math&amp;gt;M&#039;_k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k = 1,\ldots,n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Проверка по критерию ===&lt;br /&gt;
&lt;br /&gt;
Критерием &amp;lt;math&amp;gt;h&amp;lt;/math&amp;gt; является проверка подматриц на равенство. Предположим, требуется определить, удовлетворяет ли элемент &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; критерию h. Для этого необходимо, чтобы элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;, для всех &amp;lt;math&amp;gt;i,j \leq k&amp;lt;/math&amp;gt;, были равны соответствующим элементам &amp;lt;math&amp;gt;a_{r_ir_j}&amp;lt;/math&amp;gt;. Подматрица &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; выглядит так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
&amp;amp; r_1 &amp;amp; r_2 &amp;amp; \dots &amp;amp; r_k \cr&lt;br /&gt;
r_1 &amp;amp; a_{r_1r_1} &amp;amp; a_{r_1r_2} &amp;amp; \dots &amp;amp; a_{r_1r_k} \cr&lt;br /&gt;
r_2 &amp;amp; a_{r_2r_1} &amp;amp; a&#039;_{r_2r_2} &amp;amp; \dots &amp;amp; a_{r_2r_k} \cr&lt;br /&gt;
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \cr&lt;br /&gt;
r_k &amp;amp; a_{r_kr_1} &amp;amp; a_{r_kr_2} &amp;amp; \dots &amp;amp; a_{r_kr_k} \cr&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если хотя бы одно из равенств не выполнено, это означает, что по данной частичной подстановке хотя бы одна вершина отобразилась в другую так, что структура графа изменилась. А так как частичная перестановка &amp;lt;math&amp;gt;g^s_k&amp;lt;/math&amp;gt; фиксирует &amp;lt;math&amp;gt;r_1, \ldots r_k&amp;lt;/math&amp;gt;, то структура останется измененой, что означает отображение не будет являться автоморфизмом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Построение множеств частичных отображений ===&lt;br /&gt;
&lt;br /&gt;
Описание построения &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На первом этапе рассматриваются все &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt;, образующие множество &amp;lt;math&amp;gt;M_1&amp;lt;/math&amp;gt;. Каждый элемент &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; проверяется по критерию h. Элементы, удовлетворяющие h, образуют &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt;. В каждый элемент из &amp;lt;math&amp;gt;M&#039;_1&amp;lt;/math&amp;gt; добавляется еще одно отображение (2 &amp;lt;math&amp;gt;\to&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;r_2&amp;lt;/math&amp;gt;), т.е. происходит переход от &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Из каждого &amp;lt;math&amp;gt;g^s_1&amp;lt;/math&amp;gt; получается разных &amp;lt;math&amp;gt;(n-1)&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt;. Всевозможные элементы &amp;lt;math&amp;gt;g^s_2&amp;lt;/math&amp;gt; образуют &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;. Далее строится &amp;lt;math&amp;gt;M&#039;_2&amp;lt;/math&amp;gt;, добавляя в него только те элементы из &amp;lt;math&amp;gt;M_2&amp;lt;/math&amp;gt;, которые удовлетворяют критерию. Аналогично получаются множества &amp;lt;math&amp;gt;M_3,\ M&#039;_3,\ M_4,\ldots, M_n,\ M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Таким образом, получается последовательнось множеств частичных отображенией:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\{M&#039;_k\}&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;M&#039;_1 \subseteq M&#039;_2 \subseteq \ldots \subseteq M&#039;_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Множество &amp;lt;math&amp;gt;M&#039;_n&amp;lt;/math&amp;gt; является множеством всех возможных автоморфизмов (или пустое, если их нет).&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Full</name></author>
	</entry>
</feed>