<?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=Sleo</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=Sleo"/>
	<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/Sleo"/>
	<updated>2026-10-22T17:17:38Z</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:Khotkin/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0_%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE_%D1%80%D0%B0%D0%B7%D0%BC%D0%B5%D1%80%D0%B0&amp;diff=20988</id>
		<title>Участник:Khotkin/Построение матрицы Адамара произвольного размера</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:Khotkin/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0_%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE_%D1%80%D0%B0%D0%B7%D0%BC%D0%B5%D1%80%D0%B0&amp;diff=20988"/>
		<updated>2016-12-15T11:33:53Z</updated>

		<summary type="html">&lt;p&gt;Sleo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Sleo}}&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Построение матрицы Адамара&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(m2^{2m})&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(2^{2n})&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;2^{2n}&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[U:Khotkin|Хоткин Кирилл]] 623 гр., [[U:Mikhail Tsarev|Царев Михаил]] 615 гр.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Матрица Адамара&#039;&#039;&#039; &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; представляет собой матрицу размера  &#039;&#039;n&#039;&#039;×&#039;&#039;n&#039;&#039; из элементов  &amp;lt;math&amp;gt;+1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;-1&amp;lt;/math&amp;gt;, такую, что: &amp;lt;math&amp;gt;H \cdot H^T = n \cdot E_n,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;E_n&amp;lt;/math&amp;gt; — это единичная матрица размера &#039;&#039;n&#039;&#039;×&#039;&#039;n&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Матрицы Адамара находят широкое применение в теории кодирования (коды, исправляющие ошибки), теории планирования многофакторных экспериментов (ортогональные блок-схемы), квантовой информатике и прочих областях.&lt;br /&gt;
&lt;br /&gt;
Матрица Адамара остаётся матрицей Адамара при следующих преобразованиях:&lt;br /&gt;
* умножение строчки или столбца на −1;&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;H_m&amp;lt;/math&amp;gt; подразумевается матрица порядка &amp;lt;math&amp;gt;2^m&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Примерами матриц Адамара различных размеров являются следующие матрицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_0 = (1);&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_1 = &lt;br /&gt;
\begin{pmatrix} 1 &amp;amp; 1&lt;br /&gt;
\\1 &amp;amp; -1 &lt;br /&gt;
\end{pmatrix};&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_2 = &lt;br /&gt;
\begin{pmatrix} 1 &amp;amp; 1 &amp;amp; 1 &amp;amp; 1&lt;br /&gt;
\\1 &amp;amp; -1 &amp;amp; 1 &amp;amp; -1&lt;br /&gt;
\\1 &amp;amp; 1 &amp;amp;- 1 &amp;amp; -1&lt;br /&gt;
\\1 &amp;amp; -1 &amp;amp; -1 &amp;amp; 1&lt;br /&gt;
\end{pmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вообще, если &amp;lt;math&amp;gt;H_m&amp;lt;/math&amp;gt; матрица Адамара порядка &amp;lt;math&amp;gt;2^m&amp;lt;/math&amp;gt;, то матрица &lt;br /&gt;
&amp;lt;math&amp;gt;H_{m+1} = &lt;br /&gt;
\begin{pmatrix} H_m &amp;amp; H_m&lt;br /&gt;
\\H_m &amp;amp; -H_m&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
является матрицей Адамара порядка &amp;lt;math&amp;gt;2^{m+1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Кроме того, матрицу Адамара порядка &amp;lt;math&amp;gt;2^m&amp;lt;/math&amp;gt; можно получить по следующей формуле &amp;lt;math&amp;gt;H^{\otimes m} = H_1  \otimes ... \otimes H_1&amp;lt;/math&amp;gt;, где знак &amp;lt;math&amp;gt; \otimes &amp;lt;/math&amp;gt; означает тензорное произведение.&lt;br /&gt;
&lt;br /&gt;
Также существует недоказанная гипотеза Адамара, которая утверждает, что существуют матрицы Адамара порядка &amp;lt;math&amp;gt;4k&amp;lt;/math&amp;gt; для любого натурального &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, однако матрица Адамара порядка &amp;lt;math&amp;gt;268&amp;lt;/math&amp;gt;  до сих пор не построена, как и для ряда других порядков больше &amp;lt;math&amp;gt;268&amp;lt;/math&amp;gt;. Поэтому в данной работе будут рассматриваться матрицы Адамара порядка &amp;lt;math&amp;gt;2^m&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Описанные ранее способы построения матрицы Адамара не являются оптимальными, поэтому вычисление матрицы Адамара порядка &amp;lt;math&amp;gt;2^m&amp;lt;/math&amp;gt; будет производится поэлементно с помощью следующей формулы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
(H_m)_{ij}=(-1)^ {\sum_{k}{(i \&amp;amp; j)_k}},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;\&amp;amp; - &amp;lt;/math&amp;gt; побитовая операция И,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;(i \&amp;amp; j)_k - &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; -ый разряд в двоичном представлении числа &amp;lt;math&amp;gt;(i \&amp;amp; j)&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;&lt;br /&gt;
(H_m)_{ij}=(-1)^ {\sum_{k}{(i \&amp;amp; j)_k}}.&lt;br /&gt;
&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;(-1)^ {\sum_{k}{(i \&amp;amp; j)_k}}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Для вычисления очередного элемента матрицы Адамара нужно выполнить следующие шаги:&lt;br /&gt;
&lt;br /&gt;
1.  Побитовое умножение &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;:  &amp;lt;math&amp;gt;result = i \&amp;amp; j &amp;lt;/math&amp;gt; ;&lt;br /&gt;
&lt;br /&gt;
2. Нахождение числа единиц в двоичной записи числа &amp;lt;math&amp;gt;result &amp;lt;/math&amp;gt;:  &amp;lt;math&amp;gt; sum = \sum_{k}{(result)_k} &amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3. Нахождение элемента матрицы Адамара: &amp;lt;math&amp;gt;(H_m)_{ij}=(-1)^{sum}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Возможная реализация на языке C++:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int get_sign(unsigned N) {&lt;br /&gt;
    int i;&lt;br /&gt;
    for (i=0; N; N&amp;gt;&amp;gt;=1) { i+=N&amp;amp;1;}&lt;br /&gt;
    return (i&amp;amp;1) ? -1 : 1;&lt;br /&gt;
}&lt;br /&gt;
void adamar(int **e, int size) {&lt;br /&gt;
    for (unsigned int i = 0; i &amp;lt; size; ++i)&lt;br /&gt;
        for (unsigned int j = 0; j &amp;lt; size; ++j)&lt;br /&gt;
            e[i][j]=get_sign(i&amp;amp;j);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для выполнения первого шага алгоритма для всех элементов матрицы Адамара необходимо суммарно выполнить:&lt;br /&gt;
* &amp;lt;math&amp;gt;2^{2m}&amp;lt;/math&amp;gt; операций побитового умножения.&lt;br /&gt;
На втором шаге алгоритма необходимо выполнить для каждого элемента матрицы Адамара:&lt;br /&gt;
* от 0 до m или m логических сдвигов на один бит в зависимости от программной реализации;&lt;br /&gt;
* от 0 до m или m операций сложения в зависимости от программной реализации;&lt;br /&gt;
* от 0 до m или m операций логического умножения в зависимости от программной реализации.&lt;br /&gt;
На третьем шаге для всех элементов необходимо сумарно выполнить:&lt;br /&gt;
* &amp;lt;math&amp;gt;2^{2m}&amp;lt;/math&amp;gt; операций побитового умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;2^{2m}&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+2)2^{2m}&amp;lt;/math&amp;gt; операций логического умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;m\cdot2^{2m}&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
* &amp;lt;math&amp;gt;m\cdot2^{2m}&amp;lt;/math&amp;gt; операций логического сдвига на один бит;&lt;br /&gt;
* &amp;lt;math&amp;gt;2^{2m}&amp;lt;/math&amp;gt; операций сравнения с нулем.&lt;br /&gt;
Всего  &amp;lt;math&amp;gt;(3m+3)2^{2m}&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;i\&amp;amp;j&amp;lt;/math&amp;gt; - операция побитового умножения, где &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; соответствующие координаты элемента &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* NoO (number of ones) - вычисление количества единиц числа в двоичной системе. Состоит из последовательного применения операций сложения и побитового умножения;&lt;br /&gt;
* Sign - определение знака соответствующего элемента. Если результат предыдущего шага - чётное число, то знак положительный, иначе - отрицательный.  &lt;br /&gt;
&lt;br /&gt;
[[File:Hadamar matrix.png|thumb|center|1400px|Рисунок 1. Граф алгоритма построения матрицы Адамара.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Вычисление любого элемента можно производить независимо от других, то есть параллельно.&lt;br /&gt;
&lt;br /&gt;
Высота канонической ярусно-параллельной формы равна 3.&lt;br /&gt;
Ширина ЯПФ равна &amp;lt;math&amp;gt;2^{2m}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: m - размерность матрицы &amp;lt;math&amp;gt;H_m&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: 1 (число m).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица Адамара &amp;lt;math&amp;gt;H_{m}&amp;lt;/math&amp;gt; размерностью &amp;lt;math&amp;gt;2^m&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2^{2m}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
* &#039;&#039;Вычислительная мощность&#039;&#039; алгоритма построения матрицы Адамара, как отношение числа операций к суммарному объему входных и выходных данных: &lt;br /&gt;
:&amp;lt;math&amp;gt;\,\frac{(3m+3)2^{2m}}{1+2^{2m}}\, \approx 3m+3.&amp;lt;/math&amp;gt;;&lt;br /&gt;
* Алгоритм построения матрицы Адамара является &#039;&#039;недетерминированным&#039;&#039;, так как число операций меняется в зависимости от входных данных (числа m, которое формирует матрицу размерности 2&amp;lt;sup&amp;gt;&#039;&#039;m&#039;&#039;&amp;lt;/sup&amp;gt;&amp;amp;nbsp;&amp;amp;times;&amp;amp;nbsp;2&amp;lt;sup&amp;gt;&#039;&#039;m&#039;&#039;&amp;lt;/sup&amp;gt;);&lt;br /&gt;
* Данный алгоритм построения матрицы Адамара является &#039;&#039;несбалансированным&#039;&#039;. Так как каждый элемент матрицы может обрабатываться независимо от других, вычисление элементов можно распределить по процессам. В случае, когда количество элементов матрицы &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; не кратно количеству процессов &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, на некоторые процессы ложится дополнительная задача вычисления элементов матрицы в количестве &amp;lt;math&amp;gt;a=n\operatorname{mod}s&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Программная реализация алгоритма==&lt;br /&gt;
===Особенности реализации последовательного алгоритма===&lt;br /&gt;
&lt;br /&gt;
Учитывая, что рассматриваемый алгоритм строит симметричные матрицы Адамара, можно уменьшить количество вычисляемых элементов c &amp;lt;math&amp;gt;2^{2n}&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;\frac{2^n+2^{2n}}{2}&amp;lt;/math&amp;gt; путем вычисления только диагональных и наддиагональных элементов.&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
В ходе данной работы все вычислительные эксперименты были проведены на суперкомпьютере IBM Blue Gene/P. В суперкомпьютере насчитывается 2048 вычислительных узлов. Каждый вычислительный узел состоит из одного четырехъядерного PowerPC 450 процессора. Таким образом всего насчитывается 8192 процессорных ядер. Пиковая производительность составляет 27,9 терафлопс. На вычислительных узлах системы Blue Gene/P возможны три режима исполнения процессов: 1. режим симметричного мультипроцессора (symmetrical multiprocessing, SMP) 2. режим виртуальных вычислительных узлов (virtual node mode, VN) 3. режим двухъядерных вычислительных узлов (dual node mode, DUAL) Таким образом на вычислительном узле могут быть размещены один, четыре и два MPI процесса. В VN и DUAL режимах процессы в рамках вычислительного узла для обмена данными могут использовать механизм общей памяти. Вычислительный эксперимент проводился в режиме SMP.&lt;br /&gt;
&lt;br /&gt;
Параметрами запуска реализации алгоритма были число процессов и порядок матрицы, которые менялись в диапазонах [&amp;lt;math&amp;gt;2^0, 2^1,..., 2^i,..., 2^{10}&amp;lt;/math&amp;gt;] и [&amp;lt;math&amp;gt;2^5, 2^6,..., 2^j,..., 2^{14}&amp;lt;/math&amp;gt;] соответственно. При осуществлении реализации алгоритма на каждом узле компьютера размещалось по одному процессу, таким образом при увеличении числа процессов увеличивалось и число задействованных узлов.&lt;br /&gt;
&lt;br /&gt;
На рисунках ниже представлены графики производительности и эффективности параллелизма реализации алгоритма построения матрицы Адамара произвольного размера.&lt;br /&gt;
&lt;br /&gt;
[[file:Productivity.jpg|thumb|center|1000px|Рисунок 2. График производительности реализации алгоритма.]]&lt;br /&gt;
[[file:Parallel_efficiency.jpg|thumb|center|1000px|Рисунок 3. График эффективности параллелизма реализации алгоритма.]]&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;
# [http://www.exponenta.ru/soft/matlab/potemkin/book2/chapter5/hadamard.asp MATLAB];&lt;br /&gt;
# [https://reference.wolfram.com/language/ref/HadamardMatrix.html WOLFRAM];&lt;br /&gt;
# [http://pydoc.net/Python/rogues/0.3.0/rogues.matrices.hadamard/ Python];&lt;br /&gt;
# [http://www.obihiro.ac.jp/~suzukim/masuda/octave/html3/octave_97.html Octave];&lt;br /&gt;
&lt;br /&gt;
Стоит отметить, что во многих вычислительных пакетах встроена операция тензорного произведения матриц, которая позволяет строить матрицу Адамара по определению. Этот факт позволяет использовать матрицу Адамара в этих вычислительных пакетах: &lt;br /&gt;
# [https://ru.wikipedia.org/wiki/Maple MAPLE];&lt;br /&gt;
# [https://ru.wikipedia.org/wiki/Mathcad MATCATH];&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
[1] Кронберг, Ю.И. Ожигов, А.Ю. Чернявский — Алгебраический аппарат квантовой информатики 2&lt;/div&gt;</summary>
		<author><name>Sleo</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:%D0%A0%D1%83%D1%81%D0%BB%D0%B0%D0%BD/%D0%9F%D0%BB%D0%BE%D1%82%D0%BD%D0%BE%D1%81%D1%82%D0%BD%D1%8B%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8&amp;diff=19821</id>
		<title>Участник:Руслан/Плотностный алгоритм кластеризации</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:%D0%A0%D1%83%D1%81%D0%BB%D0%B0%D0%BD/%D0%9F%D0%BB%D0%BE%D1%82%D0%BD%D0%BE%D1%81%D1%82%D0%BD%D1%8B%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8&amp;diff=19821"/>
		<updated>2016-12-01T11:09:11Z</updated>

		<summary type="html">&lt;p&gt;Sleo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Sleo}}&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Плотностный алгоритм кластеризации DBSCAN&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(|X| \log |X|)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(m)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основной автор описания: [[User:Руслан|Кучеров Р.И.]]&lt;br /&gt;
&lt;br /&gt;
Алгоритм &#039;&#039;&#039;DBSCAN (Density Based Spatial Clustering of Applications with Noise)&#039;&#039;&#039; -  плотностный алгоритм для кластеризации пространственных данных с присутствием шума), был предложен Мартином Эстер, Гансом-Питером Кригель и коллегами в 1996 году как решение проблемы разбиения (изначально пространственных) данных на кластеры произвольной формы. Большинство алгоритмов, производящих плоское разбиение, создают кластеры по форме близкие к сферическим, так как минимизируют расстояние до центра кластера. Авторы DBSCAN экспериментально показали, что их алгоритм способен распознать кластеры различной формы.&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритма =&lt;br /&gt;
Кластеризация – это процесс разбиения множества элементов на непересекающиеся кластеры, так, чтобы в каждом кластере все элементы были схожи в каком-то смысле, а объекты разных кластеров существенно отличались.&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Идея, положенная в основу алгоритма, заключается в том, что внутри каждого кластера наблюдается типичная плотность точек (объектов), которая заметно выше, чем плотность снаружи кластера, а также плотность в областях с шумом ниже плотности любого из кластеров. Ещё точнее, что для каждой точки кластера её соседство заданного радиуса должно содержать не менее некоторого числа точек, это число точек задаётся пороговым значением. Алгоритм DBSCAN для заданных значений параметров &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и MinPts исследует кластер следующим образом: сначала выбирает случайную точку, являющуюся ядровой, в качестве затравки, затем помещает в кластер саму затравку и все точки, плотно-достижимые из неё.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Исходные данные: объекты, которые нужно кластеризовать, параметры &amp;lt;math&amp;gt;MinPts, \ \varepsilon&amp;lt;/math&amp;gt; . Между объектами можно считать расстояния.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: разбиение объектов по кластерам. Количество кластеров зависит от исходных данных.&lt;br /&gt;
&lt;br /&gt;
Для построения оценки плотности, на основе соседства точек вводятся понятия достижимости и связности. Под &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; -соседями точки &amp;lt;math&amp;gt;x \in X&amp;lt;/math&amp;gt; понимается множество точек, расстояние до которых не превышает &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; , т. е. &amp;lt;math&amp;gt;N_\varepsilon (x) = \{y \in X | D(x, y) \le \varepsilon\}.&amp;lt;/math&amp;gt; Тогда точка y достижима из точки &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, если существует последовательность точек &amp;lt;math&amp;gt;x^{(1)}=x, x^{(2)},... , x^{(p-1)}, x^{(p)}=y&amp;lt;/math&amp;gt;, для которой выполнено:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
x^{(i+1)} \in N_\varepsilon (x^{(i)}), i=1,... ,p-1 \\&lt;br /&gt;
\mid N_\varepsilon (x^{(i)}) \mid \ge MinPts, i=1,... ,p-1&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здесь значение &amp;lt;math&amp;gt;MinPts&amp;lt;/math&amp;gt; задаётся пользователем и регулирует порог «шума». Согласно второму условию, у точек, находящихся внутри кластера, должно быть не менее &amp;lt;math&amp;gt;MinPts \ \varepsilon&amp;lt;/math&amp;gt; -соседей. Такие точки называются «ядрами». Остальные точки разделяются на граничные (имеющие менее &amp;lt;math&amp;gt;MinPts \ \varepsilon&amp;lt;/math&amp;gt; -cоседей, но достижимые из какого-либо «ядра») и шумовые. Две точки связны, если существует «ядро», из которого они обе достижимы. При такой постановке задачи, под кластером понимается максимальное связное подмножество множества X . Точки, не попавшие в какой-либо кластер (не принадлежащие &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; -окрестности какого-либо «ядра»), относятся к классу «шум».&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательной версии зависти от поиска всех точек в &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-окрестности конкретной точки. Из-за поиска &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседства алгоритм имеет квадратичную вычислительную сложность &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; (где n - количество точек). Но если задействовать K-мерное дерево, то можно снизить сложность до &amp;lt;math&amp;gt;O(\text{n log n})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм DBSCAN использует пространственную структуру данных для определения соседних объектов. Это может быть R*-дерево или k-d дерево. Такие структуры данных позволяют найти все объекты в пределах определенного расстояния от текущего объекта. Также для построения этих деревьев нужно уметь находить расстояние между объектами &amp;lt;math&amp;gt;\rho(u, v)&amp;lt;/math&amp;gt; , в, это расстояние можно вводить разными способами. Например, если &amp;lt;math&amp;gt;\rho(u,v)&amp;lt;/math&amp;gt; - метрика в евклидовом пространстве, &amp;lt;math&amp;gt;u=(u_1,...,u_n)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(v_1,...,v_n)&amp;lt;/math&amp;gt;, то расстояние вычисляется следующим образом: &amp;lt;math&amp;gt;\rho(u,v)=\sqrt{(u_1-v_1)^2+(u_2-v_2)^2+...+(u_n-v_n)^2} = \sqrt{\sum_{k=1}^n(u_k-v_k)^2}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм начинает работу с произвольной точки &amp;lt;math&amp;gt;x \in X&amp;lt;/math&amp;gt; и возвращает &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; -окрестность(строка 4). Если &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-окрестность содержит, как минимум minpts точек, процедура выдает новый кластер C. Алгоритм извлекает все точки в X, которые являются плотность достижима из x и добавляет их в кластер C(строки 8-17). Если в &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-окрестности x точек меньше, чем minpts, то x помечается как шум(строка 6). Однако, х все еще может быть добавлены в кластер, если она определится как пограничная точка во время изучения других основных точек(строки 16-17). Поиск точек в &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-окрестности(функция GETNEIGHBORS)известен, как запрос в диапазоне значений и получает все плотностно достижимые точки от главной точки(строки 8-17) известный как алгоритм наращивания областей. Заметим что кластер может быть определен однозначно, начиная с любой &amp;quot;ядровой&amp;quot; точки&amp;lt;ref&amp;gt; A. Zhou, S. Zhou, J. Cao, Y. Fan, and Y. Hu, “Approaches for scaling DBSCAN algorithm to large spatial databases,” Journal of computer science and technology, vol. 15, no. 6, pp. 509–526, 2000.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    1: procedure DBSCAN(X, eps, minpts)&lt;br /&gt;
    2:     for each unvisited point x ∈ X do&lt;br /&gt;
    3:         mark x as visited&lt;br /&gt;
    4:         N ← GETNEIGHBORS(x, eps)&lt;br /&gt;
    5:         if |N| &amp;lt; minpts then&lt;br /&gt;
    6:             mark x as noise&lt;br /&gt;
    7:         else&lt;br /&gt;
    8:             C ← {x}&lt;br /&gt;
    9:             for each point x&#039; ∈ N do&lt;br /&gt;
    10:                N ← N \ x&#039;&lt;br /&gt;
    11:                if x&#039; is not visited then&lt;br /&gt;
    12:                    mark x&#039; as visited&lt;br /&gt;
    13:                    N&#039; ← GETNEIGHBORS(x&#039;, eps)&lt;br /&gt;
    14:                    if |N&#039;| ≥ minpts then&lt;br /&gt;
    15:                        N ← N ∪ N&#039;&lt;br /&gt;
    16:                if x&#039; is not yet member of any cluster then&lt;br /&gt;
    17:                    C ← C ∪ {x&#039;}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
В общем случае алгоритм DBSCAN имеет квадратичную вычислительную сложность &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;(где n это количество точек в X) из-за поиска &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседства. Но если использовать пространственную индексацию (например, использую k-мерное дерево&amp;lt;ref&amp;gt;M. B. Kennel, “KDTREE 2: Fortran 95 and C++ software to efficiently search for near neighbors in a multi-dimensional Euclidean space,” 2004, institute for Nonlinear Science, University of California.&amp;lt;/ref&amp;gt; или R-дерево) для поиска &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседства, сложность снижается до &amp;lt;math&amp;gt;O(n log n)&amp;lt;/math&amp;gt;&amp;lt;ref&amp;gt;J. Bentley, “Multidimensional binary search trees used for associative searching,” Communications of the ACM, vol. 18, no. 9, pp. 509–517, 1975.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
На рисунке 1 представлен информационный граф алгоритма кластеризации DBSCAN. На входе у нас множество точек &amp;lt;math&amp;gt;P_i&amp;lt;/math&amp;gt; и мы пробегаем по всем непосещенным точкам. Далее мы, для каждой непосещенной точки, маркируем ее как посещенную и находим всех её &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей(на графике это узел &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;). Добавляем точку к кластеру(узел &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;). Затем, пробегаем по всем плотностно-достижимых точках(&amp;lt;math&amp;gt;P_j&amp;lt;/math&amp;gt;) к нашей точке, и для каждой такой точки ищем &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-сосдей и добавляем их в кластер, если они ещё не принадлежат никакому кластеру.&lt;br /&gt;
&lt;br /&gt;
[[file:Информационный_граф.png|thumb|center|700px|Рис.1  Граф алгоритма без отображения входных и выходных данных. &amp;lt;math&amp;gt;P_i&amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt;P_j&amp;lt;/math&amp;gt; - точки данного множества, &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; - поиск &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - добавление элемента к кластеру.]]&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Поиск &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей требует вычисления n расстояний и выполнения n сравнений с &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Эти операции для каждой пары точек независимы и могут быть выполнены параллельно. Таким образом, при наличии неограниченного числа процессоров сложность поиска составит O(1). Так как поиск выполняется для каждой точки ровно один раз, параллельная сложность всего алгоритма составит O(n).&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Входные данные: набор точек x, пороговое расстояние &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;, а также минимальное количество точек, необходимых для формирования кластера, minpts.&lt;br /&gt;
&lt;br /&gt;
Выход: множество кластеров С.&lt;br /&gt;
&lt;br /&gt;
Если указать маленькое значение &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;, то все точки будут шумом. Если наоборот, сделать большое значение, то кластер не будет разбит, возьмет один кластер и включит в него все точки. Также, если взять minpts слишком большое или слишком маленькое, будет либо один кластер, либо все точки шумовые. Оптимальные значения находятся опытным путем.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
Соотношение последовательной и параллельной сложностей алгоритма является линейным (отношение квадратичной к линейной). При этом вычислительная мощность, как отношение числа операций к суммарному объему входных и выходных данных линейна.&lt;br /&gt;
&lt;br /&gt;
=== Преимущества алгоритма ===&lt;br /&gt;
* не требует указать априори количество кластеров, в отличие от K-средства&lt;br /&gt;
&lt;br /&gt;
* алгоритм может разбить на произвольной формы кластеры. Даже может выявить кластер находящийся внутри другого, но не пересекающийся с ним. Из-за параметра MinPts снижается так называемый эффект однолокальности(single-link)&lt;br /&gt;
&lt;br /&gt;
* алгоритм имеет понятие &amp;quot;шума&amp;quot; и устойчив к выбросам&lt;br /&gt;
&lt;br /&gt;
* алгоритм требует всего два параметра и в основном нечувствительны к упорядоченности изначально данных точек&lt;br /&gt;
&lt;br /&gt;
* параметры MinPts и &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; могут быть установлены, экспертами в какой-либо области, если данные хорошо изучены.&lt;br /&gt;
&lt;br /&gt;
=== Недостатки алгоритма ===&lt;br /&gt;
&lt;br /&gt;
* алгоритм не совсем детерминирован: пограничные точки, которые доступны из более чем одного кластера могут быть частью любого кластера, в зависимости от того, как происходит обработка данных. К счастью, эта ситуация не часто возникают, и мало влияет на результат кластеризации. На основных точках и точках &amp;quot;шума&amp;quot;, алгоритм детерминирован. Есть DBSCAN&amp;lt;ref&amp;gt;Campello, R. J. G. B.; Moulavi, D.; Sander, J. (2013). Density-Based Clustering Based on Hierarchical Density Estimates. Proceedings of the 17th Pacific-Asia Conference on Knowledge Discovery in Databases, PAKDD 2013. Lecture Notes in Computer Science. p. 160.&amp;lt;/ref&amp;gt; который представляет собой вариант, который рассматривает пограничные пункты как шум, и таким образом достигается полностью детерминированный результат, а также более последовательной статистической интерпретации плотности соединенных компонентов.&lt;br /&gt;
&lt;br /&gt;
* качество алогоритма зависит от меры, которую мы рассматриваем в пространстве. Наиболее распространенная мера использует евклидово расстояние. &lt;br /&gt;
 &lt;br /&gt;
* если данные и масштаб не очень хорошо поняты, выбирание значимого расстояния порогового &amp;lt;math&amp;gt;\varepsilon&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;
Было проведено исследование масштабируемости параллельной реализации алгоритма DBSCAN. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;. Исследовалась параллельная реализация алгоритма, написанная с использованием стандарта MPI. Распараллеливание проводилось по числу входных объектов.&lt;br /&gt;
&lt;br /&gt;
[[file:DbscanPerfomance.png|thumb|center|700px|Рис.2 График масштабируемости]]&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;
[https://github.com/ruslanmsk/parallel_dbscan Параллельная реализация на языке C++]&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&amp;lt;span class=&amp;quot;plainlinks&amp;quot;&amp;gt;[//en.wikipedia.org/wiki/ELKI ELKI]&amp;lt;/span&amp;gt; предлагает реализацию DBSCAN, а также GDBSCAN и другие варианты. Эта реализация может использовать различные структуры индексов для поквадратного выполнения и поддерживает произвольное расстояние функции и произвольные типы данных, но это можно обогнать низкоуровневой оптимизацией реализации на небольших наборах данных.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class=&amp;quot;plainlinks&amp;quot;&amp;gt;[//en.wikipedia.org/wiki/Scikit-learn Scikit-Learn]&amp;lt;/span&amp;gt; включает в себя реализацию Python для DBSCAN для произвольной метрики Минковского, который может быть ускорен с помощью KD-деревьев и шаровых деревьев, но который использует в худшем случае квадратичную память.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class=&amp;quot;plainlinks&amp;quot;&amp;gt;[//en.wikipedia.org/wiki/R_(programming_language) GNU R]&amp;lt;/span&amp;gt; содержит DBSCAN в [//cran.r-project.org/web/packages/fpc/index.html fpc] пакете с поддержкой произвольных функций расстояния через матриц. Однако он не имеет поддержки индекса (и, соответственно, имеет квадратичное время выполнения и сложность по памяти) и довольно медленно из-за интерпретации R. Более быстрая версия реализована на языке C++ с использованием KD-деревьев (только когда расстояние Евклидово ) в пакете R [//cran.r-project.org/web/packages/dbscan/index.html dbscan].&lt;br /&gt;
&lt;br /&gt;
[//www.philippe-fournier-viger.com/spmf/SPMF SPMF] предлагает GPL-V3 java-реализацию алгоритма DBSCAN с поддержкой KD-дерева (только для параметра расстояние Евклида).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class=&amp;quot;plainlinks&amp;quot;&amp;gt;[//en.wikipedia.org/wiki/Weka_(machine_learning) Weka]&amp;lt;/span&amp;gt; содержит (как дополнительный пакет в последних версиях) базовую реализацию DBSCAN, которая работает за квадратичное время и линейную память.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class=&amp;quot;plainlinks&amp;quot;&amp;gt;[//en.wikipedia.org/wiki/Apache_Commons Apache Commons Мath]&amp;lt;/span&amp;gt; содержит java-реализацию алгоритма выполняющегося за квадратичное время.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&lt;br /&gt;
* Ester, Martin, et al. &amp;quot;A density-based algorithm for discovering clusters in large spatial databases with noise.&amp;quot; Kdd. Vol. 96. No. 34. 1996.&lt;br /&gt;
&lt;br /&gt;
* Воеводин В.В. Математические основы параллельных вычислений// М.: Изд. Моск. ун-та, 1991. 345 с.&lt;br /&gt;
&lt;br /&gt;
* Воеводин В.В., Воеводин Вл.В. Параллельные вычисления. – СПб.: БХВ - Петербург, 2002. – 608 с.&lt;br /&gt;
&lt;br /&gt;
* Фролов А.В.. Принципы построения и описание языка Сигма. Препринт ОВМ АН N 236. М.: ОВМ АН СССР, 1989.&lt;/div&gt;</summary>
		<author><name>Sleo</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:%D0%9C%D0%B0%D1%80%D0%BA%D0%BE%D0%B2%D0%B0_%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=19820</id>
		<title>Участник:Маркова Екатерина/Построение матрицы Адамара</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:%D0%9C%D0%B0%D1%80%D0%BA%D0%BE%D0%B2%D0%B0_%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=19820"/>
		<updated>2016-12-01T11:07:31Z</updated>

		<summary type="html">&lt;p&gt;Sleo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Sleo}}&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Построение матрицы Адамара&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(N^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(m)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;N^2&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Основной автор статьи: Маркова Е.А. 615 гр.&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;N\times N&amp;lt;/math&amp;gt;, составленная из чисел &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;-1&amp;lt;/math&amp;gt;, столбцы которой ортогональны, так что справедливо соотношение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H*H^T = N*E_N&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;E_N&amp;lt;/math&amp;gt; - это единичная матрица размера &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;. Матрицы Адамара применяются в различных областях, включая комбинаторику, численный анализ, обработку сигналов.&lt;br /&gt;
&lt;br /&gt;
Предложенный алгоритм является рекурсивным и описывает получение матриц Адамара только порядка степени 2. На каждом следующем шаге алгоритма, новая матрица составляется из матрицы, полученной на предыдущем этапе, путем заполнения соответствующих блоков.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;H_m&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt; матрица Адамара порядка &amp;lt;math&amp;gt;2^m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;-H_m&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt; матрица с противоположными элементами. Тогда матрица &amp;lt;math&amp;gt;H_{2m}&amp;lt;/math&amp;gt; получается следующим образом:&lt;br /&gt;
&amp;lt;math&amp;gt;H_{2m} = \begin{bmatrix}&lt;br /&gt;
         H_m &amp;amp; H_m \\&lt;br /&gt;
         H_m &amp;amp; -H_m&lt;br /&gt;
      \end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Данным алгоритм описывает получение матриц Адамара только порядка степени 2, то есть &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; связаны соотношением &amp;lt;math&amp;gt;N = 2^m&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;m&amp;lt;/math&amp;gt; шагов:&lt;br /&gt;
&lt;br /&gt;
Шаг 1: &amp;lt;math&amp;gt;H_1 = (1);&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2: &amp;lt;math&amp;gt;H_2 = &lt;br /&gt;
\begin{pmatrix} 1 &amp;amp; 1&lt;br /&gt;
\\1 &amp;amp; -1 &lt;br /&gt;
\end{pmatrix};&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3: &amp;lt;math&amp;gt;H_3 = &lt;br /&gt;
\begin{pmatrix} 1 &amp;amp; 1 &amp;amp; 1 &amp;amp; 1&lt;br /&gt;
\\1 &amp;amp; -1 &amp;amp; 1 &amp;amp; -1&lt;br /&gt;
\\1 &amp;amp; 1 &amp;amp;- 1 &amp;amp; -1&lt;br /&gt;
\\1 &amp;amp; -1 &amp;amp; -1 &amp;amp; 1&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&amp;lt;/math&amp;gt;: искомая матрица &amp;lt;math&amp;gt;H_m&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро рекурсивного алгоритма состоит из  &amp;lt;math&amp;gt;\;N^2\;&amp;lt;/math&amp;gt;  присвоений значений матрицы Адамара&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_{1,1} = 1&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_{ij} = H_{i(j - \frac{N}{2})}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;i = 1..\frac{N}{2}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;j = \frac{N}{2}+1..N&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_{ij} = H_{(i-\frac{N}{2})j}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;i = \frac{N}{2}+1..N&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;j = 1.. \frac{N}{2}&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_{ij} = H_{(i-\frac{N}{2})(j-\frac{N}{2})}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;i = \frac{N}{2}+1..N &amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;j = \frac{N}{2}+1..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;lt;math&amp;gt;H&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_{ij} = H_{i(j - \frac{N}{2})}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;i = 1..\frac{N}{2}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;j = \frac{N}{2}+1..N&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
затем левый нижний блок&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_{ij} = H_{(i-\frac{N}{2})j}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;i = \frac{N}{2}+1..N&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;j = 1.. \frac{N}{2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Последним заполняется нижний правый блок матрицы&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_{ij} = H_{(i-\frac{N}{2})(j-\frac{N}{2})}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;i = \frac{N}{2}+1..N &amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;j = \frac{N}{2}+1..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;H&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;N\times N&amp;lt;/math&amp;gt; необходимо &amp;lt;math&amp;gt;\;N^2\;&amp;lt;/math&amp;gt;  присвоений значений. Из чего можно сделать вывод, что рекурсивный метод построения матрицы Адамара является алгоритмом с &#039;&#039;квадратичной сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
===Информационный граф===&lt;br /&gt;
&lt;br /&gt;
[[file:111.jpeg|thumb|center|500px|Рисунок 1. Граф отображает шаг, стрелками показаны пересылки данных, в узлах происходит операция присвоения значений и инверсия.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма===&lt;br /&gt;
&lt;br /&gt;
Логически алгоритм можно разделить на три части, которые на каждом шаге выполняются независимо.&lt;br /&gt;
Внутри каждой части происходит &amp;lt;math&amp;gt;2^{2N}-2^{2(N-1)}&amp;lt;/math&amp;gt; независимых присвоений, где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; - номер шага алгоритма, причем размерность матрицы на шаге &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; равна &amp;lt;math&amp;gt;2^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;
Объем входных данных: 1.&lt;br /&gt;
&lt;br /&gt;
Выходные данные: матрица размером &amp;lt;math&amp;gt;N\times N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Объем выходных данных: &amp;lt;math&amp;gt; N^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Свойства алгоритма===&lt;br /&gt;
Вычислительная мощность алгоритма равна суммарному объему входных и выходных данных: &amp;lt;math&amp;gt;N^2 + 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм полностью детерминирован.&lt;br /&gt;
&lt;br /&gt;
Не смотря на существование недоказанной гипотезы, что существует алгоритм, способный построить матрицы Адамара, размера кратного 4, данный алгоритм вычисляет только матрицы размера степени 2.&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;
Исследование проводилось на [http://cluster2.inm.ras.ru кластере ИВМ].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых параметров запуска реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1:32];&lt;br /&gt;
*	размер матрицы [32: 16384].&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон эффективности алгоритма:&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0,016%;&lt;br /&gt;
*	максимальная эффективность реализации 92%.&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики производительности и эффективности выбранной реализации построения Матрицы Адамара в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
Построим оценки масштабируемости выбранной реализации построения матрицы Адамара:&lt;br /&gt;
*	По числу процессоров: &lt;br /&gt;
[[Файл:EQP8kY4D9E0.jpg|thumb|center|700px|Рисунок 2. Масштабируемость по числу процессоров. По оси ОХ отложено количество процессоров, по оси ОУ - величина производительности для разного размера матрицы.]]&lt;br /&gt;
*	По размеру задачи:&lt;br /&gt;
[[Файл:PmIAoJaqnO8.jpg|thumb|center|700px|Рисунок 3. Масштабируемость по размеру задачи. По оси ОХ отложена размерность матрицы, по оси ОУ - величина производительности для разного количества процессоров]]&lt;br /&gt;
*	По двум направлениям:&lt;br /&gt;
[[Файл:Khm.jpg|thumb|center|700px|Рисунок 4. Масштабируемость по двум направлениям. По ОХ - количество процессоров, по ОУ - размерность матрицы, по OZ - величина производительности при изменении в двух направлениях.]]&lt;br /&gt;
[[Файл:untitled.jpg|thumb|center|700px|Рисунок 5. Параллельная реализация построения матрицы Адамара. Изменение производительности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
&lt;br /&gt;
[https://www.dropbox.com/s/1ga1fp26nztt65n/hadamard_2.c?dl=0 Исследованная реализация на языке C]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Реализация&lt;br /&gt;
[https://www.mathworks.com/help/matlab/ref/hadamard.html?requestedDomain=www.mathworks.com MATLAB]&lt;br /&gt;
&lt;br /&gt;
Реализация &lt;br /&gt;
[http://pydoc.net/Python/rogues/0.3.0/rogues.matrices.hadamard/ PYTHON]&lt;br /&gt;
&lt;br /&gt;
Реализация&lt;br /&gt;
[https://reference.wolfram.com/language/ref/HadamardMatrix.html WOLFRAM]&lt;br /&gt;
&lt;br /&gt;
На языке &#039;&#039;Java&#039;&#039; реализован класс &#039;&#039;Hadamard&#039;&#039; не входящий в стандарт языка. С кодом можно ознакомиться по [https://gist.github.com/guitarkitten/3937264 ссылке].&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
1. Мак-Вильямс Ф., Слоэн Н. — &amp;quot;Теория кодов, исправляющих ошибки&amp;quot; (1979)&lt;br /&gt;
&lt;br /&gt;
2. Кронберг, Ю.И. Ожигов, А.Ю. Чернявский — &amp;quot;Алгебраический аппарат квантовой информатики 2&amp;quot;&lt;br /&gt;
&lt;br /&gt;
3. М. Н. Аршинов, Л. Е. Садовский — &amp;quot;Коды и математика&amp;quot; (1983)&lt;/div&gt;</summary>
		<author><name>Sleo</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Katemeron&amp;diff=19819</id>
		<title>Обсуждение участника:Katemeron</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Katemeron&amp;diff=19819"/>
		<updated>2016-12-01T11:07:18Z</updated>

		<summary type="html">&lt;p&gt;Sleo: Полностью удалено содержимое страницы&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Sleo</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:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=19818</id>
		<title>Участник:Nikita/Построение матрицы Адамара</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:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=19818"/>
		<updated>2016-12-01T10:57:33Z</updated>

		<summary type="html">&lt;p&gt;Sleo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Sleo}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Построение матрицы Адамара&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы статьи: [[Участник:Nikita|Иванов Н.В.]] (1.1,1.7,1.9,1.10,2.4,2.7), [[Участник:Tsyganov Nikita|Цыганов Н.И.]] (1.2,1.3,1.4,1.5,1.6,1.7,1.8,2.4).&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Матрицы Адамара были введены в математический обиход в конце прошлого века и играют важную роль в алгебре и комбинаторике. Они находят широкое применение в теории кодирования (коды, исправляющие ошибки), теории планирования многофакторных экспериментов (блок-схемы) и других областях математики.&amp;lt;ref name=&amp;quot;rt&amp;quot;&amp;gt;http://cyberleninka.ru/article/n/matritsy-adamara-nechetnogo-poryadka.pdf&amp;lt;/ref&amp;gt; Сравнительно недавно (в 1960 г.) было замечено, что эти матрицы могут быть использованы для построения кодов с большим кодовым расстоянием.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Матрицей Адамара порядка n&#039;&#039;&#039;&#039;&#039; называется &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;, элементами которой являются +1 и −1 такая, что &amp;lt;math&amp;gt;H H^T = n E_n&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;E_n&amp;lt;/math&amp;gt; - единичная матрица размера n.&lt;br /&gt;
&lt;br /&gt;
Матрица Адамара обладает следующими &#039;&#039;свойствами&#039;&#039;:&lt;br /&gt;
* Различные строки матрицы ортогональны&lt;br /&gt;
* Скалярное произведение любой строки саму на себя равно n&lt;br /&gt;
* Умножение любой строки или столбца на -1 переводит H в другую матрицу Адамара&lt;br /&gt;
* Если все элементы первой строки и первого столбца равны +1, то матрица Адамара называется нормализованной&lt;br /&gt;
&lt;br /&gt;
Ниже показаны примеры нормализованных матриц Адамара порядка 1,2 и 4, причем нормализованность матриц сохраняется при перестановке любых строк и столбцов, кроме первых:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_1 = (1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_2 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1 &amp;amp; -1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_4 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; 1 &amp;amp; 1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; 1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; -1 &amp;amp; 1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Предполагается, что существуют матрицы Адамара порядка 1, 2 и всех порядков n, кратных 4, хотя это до сих пор еще не было доказано. Нет универсального алгоритма построения матрицы Адамара произвольного размера, но известно большое число методов для различных частных случаев, и наименьший порядок, для которого матрица Адамара еще не построена, равен 268 (на 1977 г.). &amp;lt;ref name=&amp;quot;rt2&amp;quot;&amp;gt;Мак-Вильямс Ф. Дж., Слоэн Н. Дж. А. Теория кодов, исправляющих ошибки: Пер. с англ. — М: Связь, 1979. — c. 52-57&amp;lt;/ref&amp;gt; Мы приведем метод построения Пейли, который важен для теории кодирования. &lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для решения поставленной задачи будем использовать метод Пейли.&lt;br /&gt;
Это построение дает матрицы Адамара любого порядка &amp;lt;math&amp;gt;n=p+1&amp;lt;/math&amp;gt;, кратного 4, где p-простое число.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Определение.&#039;&#039;&#039; Пусть p-простое число. Ненулевые квадраты чисел, приведенные по модулю p, называются квадратичными вычетами по модулю p или просто вычетами по модулю p. &lt;br /&gt;
&lt;br /&gt;
Чтобы найти все вычеты по модулю p, достаточно рассмотреть квадраты чисел от &amp;lt;math&amp;gt;1^2&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;(p-1)^2&amp;lt;/math&amp;gt;. Но если учесть, что &amp;lt;math&amp;gt;(p-a)^2 &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p = (-a)^2 &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p = a^2 &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p&amp;lt;/math&amp;gt;, то достаточно рассмотреть лишь числа &amp;lt;math&amp;gt;1^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, 2^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, ... , (\frac{p-1}{2})^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
Функция &amp;lt;math&amp;gt;X(i)&amp;lt;/math&amp;gt;, называемая символом Лежандра, определяется на целых числах следующим образом:&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=0&amp;lt;/math&amp;gt;, если i кратно p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=1&amp;lt;/math&amp;gt;, если остаток от деления i на p является квадратным вычетом по модулю p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=-1&amp;lt;/math&amp;gt;, если остаток от деления i на p является невычетом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь мы построим матрицу Джекобстола &amp;lt;math&amp;gt;Q=(q_{ij})&amp;lt;/math&amp;gt;. Она представляет собой &amp;lt;math&amp;gt;(p*p)&amp;lt;/math&amp;gt;-матрицу, строки и столбцы которой пронумерованы числами 0,1,..., p-1, а элементы &amp;lt;math&amp;gt;q_{ij}=X(j-i)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Пусть теперь &amp;lt;math&amp;gt;&lt;br /&gt;
H =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1^T &amp;amp; Q-I\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Все элементы главной диагонали этой матрицы, кроме элемента &amp;lt;math&amp;gt;h_{00}&amp;lt;/math&amp;gt;, равны &amp;lt;math&amp;gt;X(0)-1=-1&amp;lt;/math&amp;gt;. Нетрудно заметить, что данная матрица состоит только лишь из элементов 1 и -1.&lt;br /&gt;
&lt;br /&gt;
Доказано, что такая матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; представляет собой нормализованную матрицу Адамара порядка p+1, которую называют матрицей типа Пейли.&amp;lt;ref name=&amp;quot;rt3&amp;quot;&amp;gt;http://tc.nsu.ru/uploads/codingtheory.pdf&amp;lt;/ref&amp;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;gt;0&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число.&lt;br /&gt;
&lt;br /&gt;
Вспомогательные данные: &lt;br /&gt;
&lt;br /&gt;
* Число &amp;lt;math&amp;gt;p=n-1&amp;lt;/math&amp;gt;;&lt;br /&gt;
* Вектор квадратичных вычетов (по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;r_i&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;2p&amp;lt;/math&amp;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;h_{ij}&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;. Индексация строчек и столбцов идёт с нуля. &lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
:1. Строится вектор квадратичных вычетов &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt;.&lt;br /&gt;
:: Первые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов вектора &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;) определяются следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;i \in \{1^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, 2^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, ... , (\frac{p-1}{2})^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p\}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;, то есть если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; является квадратичным вычетом по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;;&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=-1&amp;lt;/math&amp;gt;, иначе.&lt;br /&gt;
::Вторые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов (&amp;lt;math&amp;gt;i=p,1,...,2p-1&amp;lt;/math&amp;gt;) являются копией первых &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов:&lt;br /&gt;
:::&amp;lt;math&amp;gt;r_i=r_{i-p}, i=p,1,...,2p-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
:2. Строится матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;.&lt;br /&gt;
::Элементы матрицы Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; находятся следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{0j}=1, j=0,1, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{i0}=1, i=1,2, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{ij}=r_{j-i+p}, i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро алгоритма состоит из &amp;lt;math&amp;gt;(n-1) \times (n-1)&amp;lt;/math&amp;gt; операций присваивания следующего вида:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;h_{ij}=r_{j-i+p},&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; i=1,2, ... ,n-1, j=1,2, ... ,n-1.&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;
Приведем процедуру на языке С++, реализующую описанный алгоритм. На вход процедуре подается порядок матрицы &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и ссылка на заполняемую матрицу &amp;lt;math&amp;gt;result&amp;lt;/math&amp;gt;. Считаем, что &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; положительно, делится на &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число, а размер матрицы &amp;lt;math&amp;gt;result&amp;lt;/math&amp;gt; равен &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void buildHadamardMatrix(int n, vector&amp;lt; vector&amp;lt;int&amp;gt; &amp;gt; &amp;amp; result)&lt;br /&gt;
{&lt;br /&gt;
    // 1) matrix size changing&lt;br /&gt;
    result.resize(n);&lt;br /&gt;
    for (int i=0; i&amp;lt;n; i++) {&lt;br /&gt;
        result[i].resize(n);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // 2) residue array building&lt;br /&gt;
    int p=n-1;&lt;br /&gt;
    vector&amp;lt;int&amp;gt; residues;&lt;br /&gt;
    residues.resize(2*p);&lt;br /&gt;
    for (int i=0; i&amp;lt;p; i++) {&lt;br /&gt;
        residues[i] = -1;&lt;br /&gt;
    }&lt;br /&gt;
    for (int i=1; i&amp;lt;= (p-1)/2; i++) {&lt;br /&gt;
        residues[i*i % p] = 1;&lt;br /&gt;
    }&lt;br /&gt;
    for (int i=p; i&amp;lt;2*p; i++) {&lt;br /&gt;
        residues[i] = residues[i-p];&lt;br /&gt;
    }&lt;br /&gt;
    // 3) Paley matrix building&lt;br /&gt;
    // first line filling&lt;br /&gt;
    for (int j=0; j&amp;lt;n; j++) {&lt;br /&gt;
        result[0][j] = 1;&lt;br /&gt;
    }&lt;br /&gt;
    // first column filling&lt;br /&gt;
    for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
        result[i][0] = 1;&lt;br /&gt;
    }&lt;br /&gt;
    // others&lt;br /&gt;
    for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
        for (int j=1; j&amp;lt;n; j++) {&lt;br /&gt;
            result[i][j] = residues[j-i+p];&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&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;
Основными операциями алгоритма являются:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций взятия остатка;&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2+\frac{5}{2}n-3&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;n-1&amp;lt;/math&amp;gt; параллельных ветвей, второй блок - &amp;lt;math&amp;gt;\frac{n}{2}-1&amp;lt;/math&amp;gt; параллельных ветвей, третий - &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; и четвёртый - &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Файл:i_graph2.png]]&lt;br /&gt;
&lt;br /&gt;
Каждая вершина из &amp;lt;math&amp;gt;A_1-A_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C_1-C_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;D_1-D_{n^2}&amp;lt;/math&amp;gt; соответствует операции присваивания, каждая вершина из &amp;lt;math&amp;gt;B_1-B_{\frac{n}{2}-1}&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;n-1&amp;lt;/math&amp;gt; операций присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-1&amp;lt;/math&amp;gt; участков, состоящих из трёх операций: умножения, взятия остатка и присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операций присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; операций присваивания.&lt;br /&gt;
&lt;br /&gt;
Из этого можно сделать вывод, что высота ярусно-параллельной формы информационного графа равняется 6 (присваивание, умножение, взятие остатка, присваивание, присваивание, присваивание). Ширина ярусно-параллельной формы равняется &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;, что означает, что при использовании &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; процессоров матрица Адамара будет строиться за 6 операций.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; число &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - порядок матрицы Адамара &amp;lt;math&amp;gt;H_n&amp;lt;/math&amp;gt;. Дополнительные ограничения на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;:&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - натуральное;&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4;&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое.&lt;br /&gt;
&#039;&#039;&#039;Объем входных данных:&#039;&#039;&#039; 1 (число &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; построенная матрица Адамара &amp;lt;math&amp;gt;H_n&amp;lt;/math&amp;gt; (её элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; (количество элементов матрицы Адамара размера &amp;lt;math&amp;gt;n*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;O(1)&amp;lt;/math&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
Алгоритм является полностью детерминированным. &lt;br /&gt;
&lt;br /&gt;
Для вершин &amp;lt;math&amp;gt;A_1-A_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B_1-B_{\frac{n}{2}-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C_1-C_{n-1}&amp;lt;/math&amp;gt; информационного графа степени исхода являются линейными, что означает, что при возможности на этапе реализации необходимо позаботиться об эффективном доступе к элементам массива &amp;quot;&amp;lt;math&amp;gt;residues&amp;lt;/math&amp;gt;&amp;quot;.&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;
Исследование масштабируемости параллельной реализации алгоритма построения матрицы Адамара проводилось на суперкомпьютере «Ломоносов». Для этого была исследована собственная реализация алгоритма с использованием средств MPI. В ходе исследования  было произведено множество запусков программы с различными значениями параметра &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; (размер матрицы Адамара) и числом процессоров.&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых параметров запуска реализации алгоритма:&lt;br /&gt;
*число процессоров (p): [2,64] с шагом 2;&lt;br /&gt;
*размер матрицы: простые числа в диапазоне [4,10000].&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон эффективности реализации алгоритма:&lt;br /&gt;
*минимальная эффективность реализации 0.0000036% при n=4, p=2;&lt;br /&gt;
*максимальная эффективность реализации 0.333426% при n=948, p=2.&lt;br /&gt;
&lt;br /&gt;
Ниже представлены графики времени работы, производительности и эффективности данной реализации алгоритма построения матрицы Адамара в зависимости от изменяемых параметров запуска.&lt;br /&gt;
[[Файл:time_graph1.png|500px|thumb|center|Время работы параллельного алгоритма в зависимости от размерности системы и числа процессоров.]]&lt;br /&gt;
[[Файл:perform_graph1.png|500px|thumb|center|Изменение производительности параллельного алгоритма в зависимости от размерности системы и числа процессоров.]]&lt;br /&gt;
[[Файл:efficiency_graph1.png|500px|thumb|center|Эффективность работы параллельного алгоритма в зависимости от размерности системы и числа процессоров.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/snikersman/Hadamard Исследованная параллельная реализация на языке C++]&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;
* [https://www.mathworks.com/help/matlab/ref/hadamard.html?requestedDomain=www.mathworks.com MATLAB] (вносятся дополнительные ограничения, когда n, или n/12, или n/20 являются степенями по основанию 2)&lt;br /&gt;
* [http://r-survey.r-forge.r-project.org/survey/html/hadamard.html R]&lt;br /&gt;
* [https://reference.wolframcloud.com/cloudplatform/ref/HadamardMatrix.html Wolfram Mathematica]&lt;br /&gt;
* [http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.linalg.hadamard.html SciPy для Python]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;/div&gt;</summary>
		<author><name>Sleo</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:%D0%95%D0%B2%D0%B3%D0%B5%D0%BD%D0%B8%D0%B9_%D0%A0%D0%B0%D0%B5%D0%B2/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0_%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE_%D1%80%D0%B0%D0%B7%D0%BC%D0%B5%D1%80%D0%B0&amp;diff=19817</id>
		<title>Участник:Евгений Раев/Построение матрицы Адамара произвольного размера</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:%D0%95%D0%B2%D0%B3%D0%B5%D0%BD%D0%B8%D0%B9_%D0%A0%D0%B0%D0%B5%D0%B2/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0_%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE_%D1%80%D0%B0%D0%B7%D0%BC%D0%B5%D1%80%D0%B0&amp;diff=19817"/>
		<updated>2016-12-01T10:56:55Z</updated>

		<summary type="html">&lt;p&gt;Sleo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Sleo}}&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Построение матрицы Адамара произвольного размера&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n*(2^{n})^2))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O((2^n)^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(2^n)^2&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Работу выполнил студент 611 группы Раев Евгений.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Матрица Адамара&#039;&#039;&#039; &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; — это квадратная матрица размера &#039;&#039;n&#039;&#039;×&#039;&#039;n&#039;&#039;, составленная из чисел 1 и −1, столбцы которой ортогональны, так что справедливо соотношение &lt;br /&gt;
: &amp;lt;math&amp;gt;H \cdot H^T = n \cdot E_n,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;E_n&amp;lt;/math&amp;gt; — это единичная матрица размера &#039;&#039;n&#039;&#039;. Матрицы Адамара применяются в различных областях, включая комбинаторику, численный анализ, обработку сигналов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Матрица оператора Адамара&#039;&#039;&#039; имееет вид&lt;br /&gt;
:&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
  H = \frac{1}{\sqrt2}&lt;br /&gt;
   &amp;amp;\begin{pmatrix}\begin{array}{rr}&lt;br /&gt;
    1 &amp;amp; 1\\&lt;br /&gt;
    1 &amp;amp; -1&lt;br /&gt;
   \end{array}\end{pmatrix}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Соответственно, существует итерационная формула нахождения матриц Адамара, через тензорное произведение матрицы оператора Адамара на матрицу Адамара меньшего порядка:&lt;br /&gt;
:&amp;lt;math&amp;gt;H_n = H_{1} \otimes H_{n-1}&amp;lt;/math&amp;gt;, где знак &amp;lt;math&amp;gt; \otimes &amp;lt;/math&amp;gt; означает тензорное произведение.&lt;br /&gt;
&lt;br /&gt;
Мы будем использовать в дальнейшем нормализованную матрицу оператора Адамара, без коэффицента (для удобности вывода):&lt;br /&gt;
:&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
  H = &lt;br /&gt;
   &amp;amp;\begin{pmatrix}\begin{array}{rr}&lt;br /&gt;
    1 &amp;amp; 1\\&lt;br /&gt;
    1 &amp;amp; -1&lt;br /&gt;
   \end{array}\end{pmatrix}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Представим пример высчитывания матриц Адамара:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
    H_{0} = 1,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
    H_{1} = H_{1} \otimes H_{0} = \begin{pmatrix}\begin{array}{rr}&lt;br /&gt;
    1 &amp;amp; 1\\&lt;br /&gt;
    1 &amp;amp; -1&lt;br /&gt;
   \end{array}\end{pmatrix} \otimes 1 = \begin{pmatrix}\begin{array}{rr}&lt;br /&gt;
    1 &amp;amp; 1\\&lt;br /&gt;
    1 &amp;amp; -1&lt;br /&gt;
   \end{array}\end{pmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
    H_{2} = H_{1} \otimes H_{1} = \begin{pmatrix}\begin{array}{rr}&lt;br /&gt;
    1 &amp;amp; 1\\&lt;br /&gt;
    1 &amp;amp; -1&lt;br /&gt;
   \end{array}\end{pmatrix} \otimes \begin{pmatrix}\begin{array}{rr}&lt;br /&gt;
    1 &amp;amp; 1\\&lt;br /&gt;
    1 &amp;amp; -1&lt;br /&gt;
   \end{array}\end{pmatrix} =    \begin{pmatrix}\begin{array}{rrrr}&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp;  1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  1&lt;br /&gt;
    \end{array}\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
    H_{3} = H_{1} \otimes H_{2} = \begin{pmatrix}\begin{array}{rr}&lt;br /&gt;
    1 &amp;amp; 1\\&lt;br /&gt;
    1 &amp;amp; -1&lt;br /&gt;
   \end{array}\end{pmatrix} \otimes \begin{pmatrix}\begin{array}{rrrr}&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp;  1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  1&lt;br /&gt;
    \end{array}\end{pmatrix} =    \begin{pmatrix}\begin{array}{rrrrrrrr}&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp;  1 &amp;amp;  1 &amp;amp; 1 &amp;amp;  1 &amp;amp;  1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1 &amp;amp; 1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1 &amp;amp; 1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  1 &amp;amp; 1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1 &amp;amp; -1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp;  1 &amp;amp;  1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  -1 &amp;amp; -1 &amp;amp;  1 &amp;amp;  1 &amp;amp; -1\\&lt;br /&gt;
    \end{array}\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом, получаем последовательность матриц Адамамра размерностью &amp;lt;math&amp;gt;2^n&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H^{\otimes n} = H_1  \otimes ... \otimes H_1&amp;lt;/math&amp;gt; (Описано в&amp;lt;ref&amp;gt;Википедия – свободная энциклопедия [Электронный ресурс]. - https://en.wikipedia.org/wiki/Hadamard_transform. - (дата обращения: 15.10.2016).&amp;lt;/ref&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Тензорное произведение довольно затратно для реализации на вычислительной технике (необходимо хранить в памяти матрицу предыдущего порядка), поэтому существует формула для определения элемента матрицы Адамара по его индексам:&lt;br /&gt;
:&amp;lt;math&amp;gt;H_{i,j} = (-1)^{\sum ij}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; - битовые представляения значений индексов, а &amp;lt;math&amp;gt;i j&amp;lt;/math&amp;gt; - побитовое умножение. (Описано в &amp;lt;ref&amp;gt;Кронберг, Ю.И. Ожигов, А.Ю. Чернявский — Алгебраический аппарат квантовой информатики 2&amp;lt;/ref&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_{i,j} = (-1)^{\sum i  j}&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;
1. Определение индексов находимого элемента матрицы Адамара: &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2. Побитовое умножение индексов : &amp;lt;math&amp;gt;res = ij&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
3. Подсчет количества значащих единиц в &amp;lt;math&amp;gt;res&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;count = \sum res&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
4. Получение знака элемента по его четности: &amp;lt;math&amp;gt;sign = (-1)^{count}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Данному алгоритму соответствует приведенный ниже код на языке С++:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;lt;cmath&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
int get_sign(int i, int j) //Get sign Hadamard matrix&#039;s element by indices&lt;br /&gt;
{&lt;br /&gt;
    int res = i &amp;amp; j;&lt;br /&gt;
    int count;&lt;br /&gt;
    for (count=0; res; res&amp;gt;&amp;gt;=1) &lt;br /&gt;
        { &lt;br /&gt;
            if (res &amp;amp; 1)&lt;br /&gt;
                count++;&lt;br /&gt;
        }&lt;br /&gt;
    if (count &amp;amp; 1 ==1)&lt;br /&gt;
        return -1;&lt;br /&gt;
    else&lt;br /&gt;
        return 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int print_HadamardMatrix(int N) //print Hadamard matrix 2^n size&lt;br /&gt;
{&lt;br /&gt;
    int matr_size(pow(2,N));&lt;br /&gt;
    for (int i = 0; i &amp;lt; matr_size; i++)&lt;br /&gt;
    {&lt;br /&gt;
        for (int j = 0; j &amp;lt; matr_size; j++) &lt;br /&gt;
        {&lt;br /&gt;
&lt;br /&gt;
            if (get_sign(i,j)==1) &lt;br /&gt;
                    cout &amp;lt;&amp;lt;&amp;quot; 1 &amp;quot;;&lt;br /&gt;
            else &lt;br /&gt;
                    cout &amp;lt;&amp;lt;&amp;quot;-1 &amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        cout &amp;lt;&amp;lt; endl;&lt;br /&gt;
    }&lt;br /&gt;
    cout &amp;lt;&amp;lt; endl;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, const char * argv[]) &lt;br /&gt;
{&lt;br /&gt;
    if(argc!=2) &lt;br /&gt;
    {&lt;br /&gt;
        printf(&amp;quot;Matrix size missing\n&amp;quot;);&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int N(atoi(argv[1]));&lt;br /&gt;
    print_HadamardMatrix(N);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Построение матрицы Адамара порядка &amp;lt;math&amp;gt;2^n&amp;lt;/math&amp;gt; требует рассчета &amp;lt;math&amp;gt;(2^{n})^2&amp;lt;/math&amp;gt; элементов матрицы. Это включает в себя:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;(2^{n})^2&amp;lt;/math&amp;gt; побитовых умножений индексов элемента &amp;lt;math&amp;gt;i \&amp;amp; j&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2. Операция определения значащих единиц, состоит из последовательных сдвигов и умножений на 1. В худшем случае, если мы будет рассчитывать элемент с координатам &amp;lt;math&amp;gt;(2^n-1,2^n-1)&amp;lt;/math&amp;gt; будет произведено n операций сдвига (так как число &amp;lt;math&amp;gt;2^n-1 &amp;lt;/math&amp;gt; кодируется n битами), и n операций умножения на 1 (для определения значащей единицы). То есть не более чем &amp;lt;math&amp;gt;2\cdot n\cdot(2^{n})^2 &amp;lt;/math&amp;gt; операций на данном шаге.&lt;br /&gt;
&lt;br /&gt;
3. &amp;lt;math&amp;gt;(2^{n})^2&amp;lt;/math&amp;gt; побитовых умножений количества значащих единиц из предыдущего пункта с 1 для определения четности числа.&lt;br /&gt;
&lt;br /&gt;
Следовательно, общая последовательная сложность алгоритма, равна &amp;lt;math&amp;gt;(2^{n})^2 +2\cdot n\cdot(2^{n})^2 +  2^(2^{n})^2&amp;lt;/math&amp;gt;, то есть  &amp;lt;math&amp;gt;(2^{n})^2(2+2n)&amp;lt;/math&amp;gt;, или &amp;lt;math&amp;gt;O(n*(2^{n})^2))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
На рисунке ниже изображен информационный граф алгоритма. Всего возможно &amp;lt;math&amp;gt;(2^n)^2&amp;lt;/math&amp;gt; параллельных ветвей, так как каждый элемент матрицы может считаться независимо друг от друга.&lt;br /&gt;
[[File:GraphHamadard.jpg|thumb|center|800px|Рисунок 1. Двухмерная модель алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Raev_graph2.jpg|thumb|center|800px|Рисунок 1. Трехмерная модель алгоритма. In - взодные данные, Out - результаты, &amp;lt;math&amp;gt; \&amp;amp; &amp;lt;/math&amp;gt; - операция умножения,&amp;lt;math&amp;gt; \sum &amp;lt;/math&amp;gt; - операция подсчета значащих единиц,&amp;lt;math&amp;gt; \pm &amp;lt;/math&amp;gt; - операция определения знака элемента по четности]]&lt;br /&gt;
&lt;br /&gt;
1. Операция &amp;lt;math&amp;gt; \&amp;amp; &amp;lt;/math&amp;gt; - побитовое умножение индексов.&amp;lt;math&amp;gt;ij&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; соответствующие координаты элемента &amp;lt;math&amp;gt;h_{kl}&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2. Операция &amp;lt;math&amp;gt; \sum &amp;lt;/math&amp;gt; -подсчет количества значащих единиц. Состоит из последовательных сдвигов и побитового умножения с 1.&lt;br /&gt;
&lt;br /&gt;
3. Операция &amp;lt;math&amp;gt; \pm &amp;lt;/math&amp;gt; - определение четности количества значащих единиц. Состоит из побитового умножения количества значащих единиц с 1.&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения матрицы Адамара необходимы операции сдивга и побитового умножения. Расчет каждого элемента независим друг от друга, следовательно расчет каждого элемента будет являться параллельной ветвью (как видно на информационном графе). При расчете элемента все операции внутри параллельной ветви выполняются последовательно, ожидая окончания предыдущей.&lt;br /&gt;
&lt;br /&gt;
Основной вклад в высоту ярусно-параллельной формы вносит 2 шаг, осуществляющий подсчет количества значащих единиц.&lt;br /&gt;
&lt;br /&gt;
Ширина ярусно-параллельной формы будет равна &amp;lt;math&amp;gt;O((2^n)^2)&amp;lt;/math&amp;gt; - количество рассчитываемых элементов.&lt;br /&gt;
Высота ярусно-параллельной формы будет равна &amp;lt;math&amp;gt;O(2+2n)=O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: Одно натуральное число n. Данный алгоритм на основе этого числа строит матрицу Адамара &amp;lt;math&amp;gt;H_n&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;2^{n}\times 2^{n}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: 1 (число n).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: &amp;lt;math&amp;gt;2^{n}\cdot 2^n&amp;lt;/math&amp;gt; чисел, которые представляют собой элементы &amp;lt;math&amp;gt;H_{i,j}&amp;lt;/math&amp;gt; матрицы Адамара &amp;lt;math&amp;gt;H_{n}&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;2^{n}\times 2^{n}&amp;lt;/math&amp;gt;. Вообще говоря, в силу симметричности матрицы Адамара, можно хранить только половину от этих данных, но алгоритм в статье не предполагает такой оптимизации).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;(2^{n})^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
* Соотношение последовательной и параллельной сложности можно определить как отношение высоты ярусно-параллельной формы и общей последовательно сложности, то есть &amp;lt;math&amp;gt;\frac{ (2+2n)(2^n)^2 }{2+2n} = (2^n)^2 &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;\frac{ (2^{n})^2(2+2n) } {1+(2^{n})^2 } &amp;lt;/math&amp;gt; ( то есть &amp;lt;math&amp;gt;\approx 2n&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;n -&amp;gt; +\infty&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;ref&amp;gt;http://parallel.ru/cluster&amp;lt;/ref&amp;gt;. Объектом исследования стала собственная реализация алгоритма с использованием средств MPI. &lt;br /&gt;
Наблюдались две переменные - время выполнения алгоритма и количество выполненных операций. Паратметры запуска - это размерность &amp;lt;math&amp;gt;2^N&amp;lt;/math&amp;gt; матрицы Адамара и количество процессоров.&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых параметров запуска реализации алгоритма:&lt;br /&gt;
*число процессоров: [2,32] с шагом 2;&lt;br /&gt;
*размер матрицы: степени двойки в диапазоне [2, 16] с шагом 1, то есть, реальная размерность матрицы была в диапазоне [4, 65536].&lt;br /&gt;
&lt;br /&gt;
Ниже представлен график времени работы от изменения входных параметров. Как видно, оптимизация программы с ростом числа процессоров идет довольно быстро.&lt;br /&gt;
[[Файл:raev_time.png|500px|thumb|center|Время работы параллельного алгоритма в зависимости от размерности системы и числа процессоров.]]&lt;br /&gt;
&lt;br /&gt;
Так как в нашем алгоритме существенно мало операция с плавающей точкой, в качестве альтернативы Flops использовалось значение [https://en.wikipedia.org/wiki/Instructions_per_second#Millions_of_instructions_per_second MIPS] . График производительности:&lt;br /&gt;
[[Файл:raev_perfomance.png|500px|thumb|center|Изменение производительности параллельного алгоритма в зависимости от размерности системы и числа процессоров.]]&lt;br /&gt;
&lt;br /&gt;
[[Файл:raev_perfomance1.png|500px|thumb|center|Неравномерное увеличение производительности]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/analyzehim/parallel/blob/master/Task%201/task.cpp Исследованная параллельная реализация на языке C++]&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;
* [https://reference.wolframcloud.com/cloudplatform/ref/HadamardMatrix.html Wolfram]&lt;br /&gt;
* [https://www.mathworks.com/help/matlab/ref/hadamard.html?requestedDomain=www.mathworks.com MATLAB]&lt;br /&gt;
* [http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.linalg.hadamard.html SciPy]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;/div&gt;</summary>
		<author><name>Sleo</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:%D0%9E%D0%B3%D0%BD%D0%B5%D0%B2%D0%B0_%D0%9C%D0%B0%D1%80%D0%B8%D1%8F/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=16840</id>
		<title>Участник:Огнева Мария/Метод встречи посередине</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:%D0%9E%D0%B3%D0%BD%D0%B5%D0%B2%D0%B0_%D0%9C%D0%B0%D1%80%D0%B8%D1%8F/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=16840"/>
		<updated>2016-11-13T23:29:23Z</updated>

		<summary type="html">&lt;p&gt;Sleo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Sleo}}&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Maria rojas|М.С. Огнева]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Криптоанализом назвают науку восстановления (дешифрования) открытого (нешифрованного) текста без доступа к ключу. Попытка криптоанализа называется атакой.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Методом встречи посередине&#039;&#039;&#039; (англ. meet-in-the-middle attack) называется класс атак на криптографические алгоритмы (алгоритмы шифрования), которые асимптотически уменьшают время полного перебора по всем ключам, но при этом увеличивают объем требуемой памяти. Впервые данный метод был предложен Уитфилдом Диффи и Мартином Хеллманом в 1977 году &amp;lt;ref&amp;gt;Diffie Whitfield, Hellman Martin E. &#039;&#039;Exhaustive Cryptanalysis of the NBS Data Encryption Standard.&#039;&#039; - Journal Computer vol.10 pp.74–84 - June 1977&amp;lt;/ref&amp;gt; для блочных шифров.&lt;br /&gt;
=== История ===&lt;br /&gt;
Алгоритм шифрования [https://ru.wikipedia.org/wiki/DES DES] был принят в качестве стандарта в 1977 году. Длина ключа нового стандарта составляла 56 бит, довольно большое число по тем временам, но оставляла возможность полного перебора (&amp;lt;math&amp;gt;2^{56} &amp;lt;/math&amp;gt;). В 1977 Диффи и Хеллман предложили устройство, стоимостью примерно 20 млн. долларов, которое смогло бы найти ключ DES за один день. Поэтому появилась необходимость увеличить стойкость алгоритма DES, используя технику многократного шифрования. Этот способ позволяет искусственно увеличить длину ключа, применяя несколько раз операцию шифрования с разными ключами. Так для алгоритма 2DES (двойное шифрование) длина ключа равна 112 бит, то есть полный перебор становится бессмысленной затеей.&lt;br /&gt;
В 1981 году Ральф Меркл и Мартин Хеллман&amp;lt;ref&amp;gt;Merkle Ralph C., Hellman  Martin E. &#039;&#039;On the security of multiple encryption.&#039;&#039; - Journal Communications of the ACM, num.7 vol.24 pp.465-467 - July 1981&amp;lt;/ref&amp;gt; подробно разбирают безопасность двойного шифрования и описывают метод встречи посередине, позволяющий восстановить ключ шифрования не за &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt; операций шифрования, а за относительно пустяковые &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; за счет перебора не одного длинного ключа, а двух более коротких. Следующая модернизация DES - Triple DES с 168-битным ключом - требует от метода встречи посередине &amp;lt;math&amp;gt;2^{56} &amp;lt;/math&amp;gt; памяти и &amp;lt;math&amp;gt;2^{112}&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;
# Применим для любого многократного шифрования одним алгоритмом по разным ключам, а также для случая, если множество ключей криптографического алгоритма замкнуто относительно композиции (для любых ключей k&#039; и k&amp;quot; найдется ключ k такой, что результат шифрования любого текста последовательно на k&#039; и k&amp;quot; равен результату шифрования того же текста на k).&lt;br /&gt;
&lt;br /&gt;
=== Описание метода для алгоритма двойного шифрования ===&lt;br /&gt;
На данной странице будет рассмотрен более простой вариант - двойное шифрование &amp;lt;ref&amp;gt;Грушо А.А., Применко Э.А., Тимонина Е.Е. &#039;&#039;Анализ и синтез криптоалгоритмов. Курс лекций.&#039;&#039; - Москва: 2000. - 110 с.&amp;lt;/ref&amp;gt; (две итерации шифрования). Пусть &amp;lt;math&amp;gt;p, c&amp;lt;/math&amp;gt; – открытый (plaintext) и шифрованный текст  (ciphertext) соответственно. Тогда сокращение полного перебора происходит следующим образом: &lt;br /&gt;
#Находим множество всех шифртекстов &amp;lt;math&amp;gt;W&amp;lt;/math&amp;gt;, получаемых одинарным шифрованием открытого текста &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; по всем возможным ключам первой итерации.&lt;br /&gt;
#Находим множество всех шифртекстов &amp;lt;math&amp;gt;Z&amp;lt;/math&amp;gt;, получаемых одинарным дешифрованием шифрованного текста &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; по всем возможным ключам второй итерации.&lt;br /&gt;
#Если множества &amp;lt;math&amp;gt;W&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;Z&amp;lt;/math&amp;gt; имеют непустое пересечение, то искомым ключом шифрования будет являться пара ключей, при помощи которых это пересечение было зашифровано из &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; и дешифровано из &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Пусть алгоритм шифрования описывается как &amp;lt;math&amp;gt;Enc(k, t) &amp;lt;/math&amp;gt;, дешифрования &amp;lt;math&amp;gt;Dec(k, t) &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; – ключ, &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; – текст. &lt;br /&gt;
Тогда получаемый двойным шифрованием по ключам &amp;lt;math&amp;gt;k_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k_2&amp;lt;/math&amp;gt; шифрованный текст равен: &amp;lt;math&amp;gt;c = Enc(k_2, Enc(k_1, p))&amp;lt;/math&amp;gt;. &lt;br /&gt;
Открытый текст получается из шифрованного двойным дешифрованием: &amp;lt;math&amp;gt;p=Dec(k_1, Dec(k_2, c))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; тексты &amp;lt;math&amp;gt;p, c&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039; ключ &amp;lt;math&amp;gt;k=(k_1, k_2)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
Предположим для упрощения, что для известной пары &amp;lt;math&amp;gt;(p, c)&amp;lt;/math&amp;gt; существует единственный ключ &amp;lt;math&amp;gt;(k_1, k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
Составим таблицы &amp;lt;math&amp;gt;W&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;Z&amp;lt;/math&amp;gt;:&lt;br /&gt;
*для всех &amp;lt;math&amp;gt;k^i_1 \in K_1&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;w(k^i_1) = Enc (k^i_1, p)&amp;lt;/math&amp;gt;&lt;br /&gt;
*для всех &amp;lt;math&amp;gt;k^j_2 \in K_2&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;z(k^j_2) = Dec (k^j_2, c)&amp;lt;/math&amp;gt;&lt;br /&gt;
Таблицы объединяются и сортируются по полученным промежуточным шифртекстам &amp;lt;math&amp;gt;z_i, w_j&amp;lt;/math&amp;gt;. Пара &amp;lt;math&amp;gt;z_i = w_j&amp;lt;/math&amp;gt;, которую можно найти одиночным просмотром объединенной таблицы, определяет искомый ключ &amp;lt;math&amp;gt;(k^i_1, k^j_2) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В более общем случае, может получиться не одна пара &amp;lt;math&amp;gt;z_i = w_j&amp;lt;/math&amp;gt;. Тогда необходимы еще пары &amp;lt;math&amp;gt;(p, c)&amp;lt;/math&amp;gt; для определения истинного ключа.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Основную сложность алгоритма составляет перебор ключей &amp;lt;math&amp;gt;k^i_1,k^j_2&amp;lt;/math&amp;gt;, а так же сортировка полученных массивов &amp;lt;math&amp;gt;W&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;Z&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Метод использует в качестве составных частей следующие алгоритмы:&lt;br /&gt;
# Алгоритм зашифрования/расшифрования&lt;br /&gt;
#*В качестве основных примем алгоритмы [https://ru.wikipedia.org/wiki/Blowfish Blowfish] и [https://ru.wikipedia.org/wiki/DES DES], сложность которых пропорциональна длине ключа. В связи с тем, что длина ключа не больше 64 бит, то будем считать, что эти алгоритмы выполняются за единицу времени.&lt;br /&gt;
# Алгоритм сортировки&lt;br /&gt;
#*Будем считать, что используется быстрая сортировка или сортировка слиянием, которые в среднем работают за &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
#Алгоритм поиска&lt;br /&gt;
#*Совпадающие значения матриц &amp;lt;math&amp;gt;W&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;Z&amp;lt;/math&amp;gt; будем искать одиночным просмотром всей таблицы.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Последовательность действий метода:&lt;br /&gt;
# Вычислить таблицы &amp;lt;math&amp;gt;W&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;Z&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления  и сохраняя соответствующие ключи для шифрования/дешифрования.&lt;br /&gt;
# Отсортировать массив &amp;lt;math&amp;gt;W \cup Z&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Найти совпадения в отсортированной таблице.&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
# Сложность вычисления таблиц &amp;lt;math&amp;gt;W&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;Z&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
# Объединение таблиц и их сортировка будет иметь сложность: &amp;lt;math&amp;gt;O([|K_1|+|K_2|]\log[|K_1|+|K_2|])&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Поиск совпадений: &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
Общая сложность всего метода равна: &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O([|K_1|+|K_2|]\log[|K_1|+|K_2|]) + O(|K_1|+|K_2|)=O([|K_1|+|K_2|]\log[|K_1|+|K_2|])&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= (k_1,k_2)&amp;lt;/math&amp;gt;. Если предположить, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;, то &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;.&lt;br /&gt;
Тогда сложность метода составит &amp;lt;math&amp;gt;O(\sqrt n\log n) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
Опишем информационный граф алгоритма. &lt;br /&gt;
&lt;br /&gt;
На вход подаётся открытый и шифрованный тексты. После открытый текст шифруется (Enc) по всем ключам &amp;lt;math&amp;gt;k_1&amp;lt;/math&amp;gt;, а дешифрованный дешифруется (Dec) по всем ключам &amp;lt;math&amp;gt;k_2&amp;lt;/math&amp;gt;. Далее полученные тексты сравниваются между собой (Cmp) и все ключи, на которых они совпали, являются выходами алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:Graph MITM.jpg|thumb|center|600px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Plaintext — открытый текст, ciphertext — шифрованный текст, Enc — операция шифрования, Dec — операция дешифрования, Cmp — операция сравнения, Key — полученный ключ]]&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Как видно из информационного графа, для реализации метода в параллельном варианте потребуется выполнение следующих двух ярусов ярусно-параллельной формы (ЯПФ):&lt;br /&gt;
# &amp;lt;math&amp;gt;2* \sqrt{n}&amp;lt;/math&amp;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;2&amp;lt;/math&amp;gt;, ширина – &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; (т.к. &amp;lt;math&amp;gt;n&amp;gt; 2* \sqrt n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: открытый текст &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; и шифрованный текст &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt;, имеющие одинаковую длину.&lt;br /&gt;
&lt;br /&gt;
Так как рассматриваемые шифры являются блочными, то равенство длины текстов длине ключа не является обязательным, тексты могут быть длиннее. В такой ситуации тексты представляют собой последовательность блоков, а для шифрования/дешифрования берётся один блок текстов (от открытого и от шифрованного) для максимального ускорения операций.&lt;br /&gt;
&lt;br /&gt;
Примем, что длина ключей &amp;lt;math&amp;gt;k_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k_2&amp;lt;/math&amp;gt; равна 64 битам. То есть длина текста равна 64 битам или кратна этому числу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество пар &amp;lt;math&amp;gt;(k_1,k_2)&amp;lt;/math&amp;gt;, для которых нашлись совпадения. &lt;br /&gt;
&lt;br /&gt;
Лишние пары могли получиться при шифровании/дешифровании одного из блоков текстов. Тогда для получения истинного ключа необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
Длина искомого ключа: 128 бит.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
Соотношение последовательной и параллельной сложности для данного метода равно &amp;lt;math&amp;gt;O(\sqrt n\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
При этом вычислительная мощность алгоритма, равная отношению числа операций к суммарному объему входных и выходных данных, составляет &amp;lt;math&amp;gt;O(\sqrt{n})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм полностью детерминирован при условии корректности данных. &lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин, соответствующих операциям шифрования/дешифрования, образуют пучки мощности &amp;lt;math&amp;gt;\sqrt{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;
В свободном доступе существуют коды для метода встречи посередине с использованием шифрования Blowfish и хэш-таблиц на [https://gist.github.com/dchest/1062437 C], а также с использованием шифрования 2DES на [https://github.com/le1ca/class-resources/blob/master/ddes/ddes.py питоне].&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Категория:Криптографические алгоритмы]]&lt;br /&gt;
*[https://ru.wikipedia.org/wiki/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5 Метод встречи посередине]&lt;br /&gt;
*[https://en.wikipedia.org/wiki/Meet-in-the-middle_attack Meet-in-the-middle attack]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Сноски:&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Sleo</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:Elmon/%D0%9F%D0%BB%D0%BE%D1%82%D0%BD%D0%BE%D1%81%D1%82%D0%BD%D1%8B%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_DBSCAN&amp;diff=16838</id>
		<title>Участник:Elmon/Плотностный алгоритм кластеризации DBSCAN</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:Elmon/%D0%9F%D0%BB%D0%BE%D1%82%D0%BD%D0%BE%D1%81%D1%82%D0%BD%D1%8B%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_DBSCAN&amp;diff=16838"/>
		<updated>2016-11-13T23:25:04Z</updated>

		<summary type="html">&lt;p&gt;Sleo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Sleo}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Плотностный алгоритм кластеризации DBSCAN&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(|H| \log |H|)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(w)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основной автор описания: [[User:Elmon|Гилевич В.В.]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Кластеризация — это процедура, упорядочивающая элементы из некоторого множества в сравнительно однородные группы (кластеры). Элементы могут содержать числовые, категориальные или смешанные данные. Плотностные методы выделяют кластеры на основе следующей идеи: кластером считается регион с высокой плотностью объектов, которые разделены разреженными регионами (с низкой плотностью объектов)&lt;br /&gt;
&lt;br /&gt;
Алгоритм DBSCAN (Density Based Spatial Clustering of Applications with Noise) &amp;lt;ref&amp;gt;A density-based algorithm for discovering clusters in large spatial database / M. Ester, H.-P. Kriegel,&lt;br /&gt;
J. Sander, X. Xu // Proc. 1996 Intern. Conf. on Knowledge Discovery and Data Mining. – 1996.&amp;lt;/ref&amp;gt; — плотностной алгоритм для кластеризации пространственных данных с присутствием шума, был предложен Мартином Эстер, Гансом-Питером Кригель и их коллегами в 1996 году как решение проблемы разбиения данных на кластеры произвольной формы.&lt;br /&gt;
&lt;br /&gt;
Алгоритм имеет ряд отличительных свойств:&lt;br /&gt;
* Не требуется заранее определять число кластеров&lt;br /&gt;
* Может отличать кластеры, которые нельзя разделить прямой линией (плоскостью, для N-мерного пространства), в том числе кластера, частично или полностью окруженные другим кластером.&lt;br /&gt;
* Хорошо работает в условиях зашумленных входных данных&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Исходные данные ===&lt;br /&gt;
Множество &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;, на котором определена функция расстояния &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
=== Вычисляемые данные===&lt;br /&gt;
Множество пар из элемента множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;, и соответствующий ему номер кластера.&lt;br /&gt;
&lt;br /&gt;
=== Параметры алгоритма ===&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; — максимальное расстояние между соседями;&lt;br /&gt;
* &amp;lt;math&amp;gt;MinPts&amp;lt;/math&amp;gt; — минимальное количество элементов находящихся &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-окрестности данного элемента для создания кластера.&lt;br /&gt;
&lt;br /&gt;
=== Определения ===&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;ядровой элемент&#039;&#039;: элемент &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; является ядровым, если количество элементов в &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-окрестности, включая сам элемент &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; больше или равно &amp;lt;math&amp;gt;MinPts&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;достижимость напрямую элемента &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; из элемента q&#039;&#039;: элемент &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; считается достижимым напрямую из элемента &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt;, если элемент &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; является ядровым, а элемент &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; находится в &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-окрестности элемента q;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;достижимость элемента &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; из элемента &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt;&#039;&#039;: элемент &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; достижим из элемента &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt;, если существует путь &amp;lt;math&amp;gt;p_1, \dots, p_n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;p_1 = p&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_n = q&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;p_{i + 1}&amp;lt;/math&amp;gt; напрямую достижим из &amp;lt;math&amp;gt;p_{i}&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;шум&#039;&#039;: все элементы, недостижимые из какого-либо другого считаются шумом.&lt;br /&gt;
&lt;br /&gt;
Так как достижимость не является симметричным отношением (никакой элемент не может быть достижим из неядрового, вне зависимости от расстояния), то предлагается ввести следующее отношение:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;связанность элемента p и элемента q&#039;&#039;: элемент &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; считается связанным с &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt;, если существует такой элемент &amp;lt;math&amp;gt;o&amp;lt;/math&amp;gt;, что &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; достижимы из него.&lt;br /&gt;
&lt;br /&gt;
Таким образом &#039;&#039;кластер&#039;&#039; должен удовлетворять двум условиям:&lt;br /&gt;
* Все элементы внутри кластера взаимно связанны;&lt;br /&gt;
* Если элемент связан с каким-либо элементом кластера, то он тоже является частью кластера.&lt;br /&gt;
&lt;br /&gt;
[[File:DBSCAN-Illustration.svg|thumb|right|400px| Рис. 1. Для &#039;&#039;MinPts&#039;&#039; = 4. Красные элементы соответствуют ядровым, желтые — достижимым, синяя — шуму.&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/DBSCAN Density-based spatial clustering of applications with noise (DBSCAN)&amp;lt;/ref&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
=== Пошаговое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
#Выбирается произвольная непосещенный элемент &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;.&lt;br /&gt;
#Элемент &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; помечается как посещенный. &lt;br /&gt;
#Проверяется, является ли элемент &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; ядровым.&lt;br /&gt;
#*Если элемент &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; является ядровым, то: &lt;br /&gt;
#**Он становится началом нового кластера или сохраняет номер кластера, который был присвоен элементу ранее; &lt;br /&gt;
#**Все элементы из &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-окрестности элемента &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; добавляются в его кластер (им присваевается номер кластера элемента &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;);&lt;br /&gt;
#**Процесс продолжается рекурсивно для каждого непосещенного элемента текущего кластера c шага 2.&lt;br /&gt;
#*Если элемент &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; не является ядровым, то &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; объявляется шумом. Алгоритм продолжается с шага 4.&lt;br /&gt;
#Если остались непосещенные точки, то алгоритм продолжается с шага 1.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром алгоритма является поиск элементов в &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-окрестности каждого элемента входного множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;. На эту часть алгоритма приходится основное время работы алгоритма, так как для каждого элемента необходимо выполнить эту операцию. Основные операции вычислительного ядра алгоритма: нахождение расстояние между элементами множества и сравнение его с порогом для определения того, являются ли один элемент достижимым напрямую из другого.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма == &lt;br /&gt;
&lt;br /&gt;
Алгоритм DBSCAN предполагает использование пространственной структуры данных (структуры, ориентированной на индексацию многомерной информации, такой как географические данные) — такие структуры позволяют найти все элементы в пределах определенного расстояния от текущего за &amp;lt;math&amp;gt;O(\log n)&amp;lt;/math&amp;gt;. Сложность построения таких структур &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt;, таким образом, использование такой структуры не увеличивает сложность всего алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;DBSCAN(X, \varepsilon, MinPts)&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;C = 0&amp;lt;/math&amp;gt;&lt;br /&gt;
   for &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; in &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;:&lt;br /&gt;
     if &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; is &amp;lt;math&amp;gt;visited&amp;lt;/math&amp;gt;:&lt;br /&gt;
       # Skipping already visited elements&lt;br /&gt;
       continue&lt;br /&gt;
     mark &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; as &amp;lt;math&amp;gt;visited&amp;lt;/math&amp;gt;&lt;br /&gt;
     # [Core operation] Searching for neighbors&lt;br /&gt;
     &amp;lt;math&amp;gt;neighbours&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;\{ o \ | \ \forall o \in X: D(p, o) \le \varepsilon \}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;| neighbours | \ge MinPts&amp;lt;/math&amp;gt;:&lt;br /&gt;
       # Found new cluster&lt;br /&gt;
       &amp;lt;math&amp;gt;C = C + 1&amp;lt;/math&amp;gt;&lt;br /&gt;
       add &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; to cluster &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;&lt;br /&gt;
       # Looking for more neighbors, until none left&lt;br /&gt;
       for &amp;lt;math&amp;gt;q \in neighbours&amp;lt;/math&amp;gt;:&lt;br /&gt;
         if &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; is not &amp;lt;math&amp;gt;visited&amp;lt;/math&amp;gt;:&lt;br /&gt;
           # If element is visited, then either it was marked as part of other cluster, or as noise&lt;br /&gt;
           mark &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; as &amp;lt;math&amp;gt;visited&amp;lt;/math&amp;gt;&lt;br /&gt;
           # [Core operation] Searching for neighbors&lt;br /&gt;
           &amp;lt;math&amp;gt;q\_neighbours&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;\{ o \ | \ \forall o \in X: D(q, o) \le \varepsilon \}&amp;lt;/math&amp;gt;&lt;br /&gt;
           if &amp;lt;math&amp;gt;| q\_neighbours | \ge MinPts&amp;lt;/math&amp;gt;:&lt;br /&gt;
             # We can expand neighbors with new elements from element &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt;&lt;br /&gt;
             &amp;lt;math&amp;gt;neighbours&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;neighbours \cup q\_neighbours&amp;lt;/math&amp;gt;  &lt;br /&gt;
         if &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; has no cluster mark:&lt;br /&gt;
           # If it&#039;s noise — mark as edge-element part of cluster&lt;br /&gt;
           mark &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; as part of cluster &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;&lt;br /&gt;
     else:&lt;br /&gt;
       mark &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; as &amp;lt;math&amp;gt;noise&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Для того, чтобы проверить принадлежность элемента множества к кластеру необходимо получить список соседей в его &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-окрестности. При использовании пространственной структуры данных данная операция может быть выполнена со сложностью &amp;lt;math&amp;gt;O(\log n)&amp;lt;/math&amp;gt;. Так как для необходимо определить принадлежность к кластеру всех элементов множества, то сложность самого алгоритма &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt;. При отказе от использования таких сткрутр сложность возрастает до &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, так как для каждого элемента требуется проверить на нахождение в &amp;lt;math&amp;gt;\varepsilon&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;
Первой группе вершин соответствует операция Neighbours. Естественно введённые координаты области таковы:&lt;br /&gt;
* &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; — меняется от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;k + f&amp;lt;/math&amp;gt;, принимая все целочисленные значения, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — число результирующих кластеров, &amp;lt;math&amp;gt;f&amp;lt;/math&amp;gt; — число элементов помеченных, как шум&lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, принимая все целочисленные значения, где &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; — число вершин в кластере &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;&lt;br /&gt;
Второй группе вершин соответствует операция Check. Естественно введённые координаты области аналогичны предыдущей.&lt;br /&gt;
&lt;br /&gt;
[[File:DBSCAN algo graph.png|thumb|center|800px|Рис. 2. Граф алгоритма DBSCAN с отображением входных данных. Element — входные данные, Neighbours —  операция поиска соседей, Check — операция проверки условий, добавления вершины к кластеру и выбора новой, Out — результаты.]]&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Так как в данном алгоритме присутствует параллелизм по данным, ширина ярусно-параллельной формы алгоритма &amp;lt;math&amp;gt;O(w)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; — количество частей, на которые разбиваются все входное множество объектов &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;. Высотой ярусно-параллельной формы алгоритма является &amp;lt;math&amp;gt;O(|H| \log |H|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|H|&amp;lt;/math&amp;gt; — максимальное количество элементов в области среди всех частей разбиения. Именно такую сложность имеет алгоритм PDBSCAN&amp;lt;ref&amp;gt;[http://www.ece.northwestern.edu/~choudhar/Publications/ANewScalableParallelDBSCANAlgorithmUsingDisjointSetDataStructure.pdf A New Scalable Parallel DBSCAN Algorithm Using the Disjoint-Set Data Structure \ Md. Mostofa Ali Patwary, Diana Palsetia, Ankit Agrawal, Wei-keng Liao, Fredrik Manne, Alok Choudhary]&amp;lt;/ref&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;X&amp;lt;/math&amp;gt;, на котором определена функция расстояния &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; (размерность входящего множества)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: размеченное множество точек &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;, в котором каждому элементу соответствует номер его кластера.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;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;
* [https://github.com/ContinuumIO/parallel_dbscan Параллельная реализация для Python на OpenMP/MPI]&lt;br /&gt;
* [https://github.com/propanoid/DBSCAN Параллельная реализация для C++ на Boost и OpenMP с использованием VP-дерева]&lt;br /&gt;
* [https://github.com/ahbarnett/validspike/tree/master/contrib/dbscan_patwary Параллельная реализация для С++ на OpenMP с использованием системы непересекающихся множеств]&lt;br /&gt;
* [https://github.com/bwoneill/pypardis Параллельная реализация для многомерных данных для Python на SciPy и NumPy ]&lt;br /&gt;
* [https://github.com/mhahsler/dbscan Последовательная реализация для R на С++]&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:DBSCAN]]&lt;/div&gt;</summary>
		<author><name>Sleo</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:EasyBreezy/%D0%A1%D1%82%D0%B0%D0%B1%D0%B8%D0%BB%D0%B8%D0%B7%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D0%B1%D0%B8%D1%81%D0%BE%D0%BF%D1%80%D1%8F%D0%B6%D0%B5%D0%BD%D0%BD%D1%8B%D1%85_%D0%B3%D1%80%D0%B0%D0%B4%D0%B8%D0%B5%D0%BD%D1%82%D0%BE%D0%B2_(BiCGSTAB)&amp;diff=16836</id>
		<title>Участник:EasyBreezy/Стабилизированный метод бисопряженных градиентов (BiCGSTAB)</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:EasyBreezy/%D0%A1%D1%82%D0%B0%D0%B1%D0%B8%D0%BB%D0%B8%D0%B7%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D0%B1%D0%B8%D1%81%D0%BE%D0%BF%D1%80%D1%8F%D0%B6%D0%B5%D0%BD%D0%BD%D1%8B%D1%85_%D0%B3%D1%80%D0%B0%D0%B4%D0%B8%D0%B5%D0%BD%D1%82%D0%BE%D0%B2_(BiCGSTAB)&amp;diff=16836"/>
		<updated>2016-11-13T23:19:08Z</updated>

		<summary type="html">&lt;p&gt;Sleo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Основные авторы описания: Александр Новиков (1.4, 1.6, 1.7, 2.7, 3), [[Участник:EasyBreezy|Гаврилов Алексей (1.1 - 1.3, 1.5, 1.8, 1.9, 2.7, 3)]]&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = BiCGSTAB&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt; O(n^2) &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; - размерность СЛАУ&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt; O(k*(6 \sqrt n + 4n + 5 \lceil \frac{n}{p} \rceil)) &amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt; 2 \sqrt n &amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = матрица &amp;lt;math&amp;gt;A \in R^{N \times N}&amp;lt;/math&amp;gt; ( &amp;lt;math&amp;gt;C^{N \times N}&amp;lt;/math&amp;gt; ) и вектор правой части &amp;lt;math&amp;gt;b \in R^N&amp;lt;/math&amp;gt; ( &amp;lt;math&amp;gt;C^N&amp;lt;/math&amp;gt; )&lt;br /&gt;
| output_data       = вектор решения системы &amp;lt;math&amp;gt;x \in R^N&amp;lt;/math&amp;gt; ( &amp;lt;math&amp;gt;C^N&amp;lt;/math&amp;gt; )&lt;br /&gt;
}}&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
:Стабилизированный метод бисопряженных градиентов, так же известный как BiCGSTAB (Biconjugate gradient stabilized method), был предложен голландским математиком Хенком ван дер Ворстом&amp;lt;ref&amp;gt;Henk A. vander Vorst, Iterative Krylov Methods for Large Linear Systems, Cambridge University Press 2003, 230p&amp;lt;/ref&amp;gt; в 1992 году. Статья, в которой описывался метод, стала самым цитируемым научным трудом в области математики в 1990х годах.&lt;br /&gt;
&lt;br /&gt;
:Метод появился, как ответ на задачу о построении способа решения систем линейных алгебраических уравнений произвольного вида. На момент появления BiCGSTAB уже существовали методы решения СЛАУ произвольного типа, в том числе и в комплексном пространстве, например метод бисопряженных градиентов. Однако существующие на тот момент методы либо обладали недостаточной скоростью сходимости, либо использовали в вычислениях тяжелые операции, такие как транспонирования матрицы, которые усложняли распараллеливание на многопроцессорных машинах.&lt;br /&gt;
:BiCGSTAB является итерационным методом решения систем линейных алгебраических уравнений. Мощь метода заключается в том, что его можно применять к матрицам общего вида, в том числе с комплексными коэффициентами. В процессе выполнения BiCGSTAB не использует для вычисления плохо распараллеливаемых операций, не допускает накопления погрешностей округления и нестабильного поведения невязки. Эти факторы выгодно отличают его от предшественников: метода бисопряженных градиентов и квадратичного метода сопряженных градиентов, из которого BiCGSTAB фактически и вытекает. К преимуществам так же можно добавить более высокую в общем случае скорость сходимости относительно ближайших конкурентов. Тем не менее, для некоторых видов СЛАУ BiCGSTAB может уступать более простым методам.&amp;lt;ref&amp;gt;Горбаченко В.И, Вычислительная линейная алгебра с примерами на MATLAB. — СПб.: БХВ-Петербург, 2011. — 320 с.: ил. — (Учебное пособие)&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:Благодаря свойствам алгоритма область применения метода весьма широка. Фактически, он используется во всех задачах, где требуется решать СЛАУ, в том числе СЛАУ большой размерности, к которым сводится большое количество численных методов, применяемых при решении задач математического моделирования. &lt;br /&gt;
&lt;br /&gt;
:BiCGSTAB относится к классу так называемых проекционных методов. Основная идея методов данного класса: искать итерационным способом наилучшее приближение решения в некотором подпространстве пространства &amp;lt;math&amp;gt;R^n&amp;lt;/math&amp;gt;, и чем шире подпространство, в котором ищется приближение решения, тем ближе будет приближенное решение к точному на каждой итерации. В качестве такого подпространства используются пространства Крылова, порожденные матрицей системы и невязкой первого приближения: &amp;lt;math&amp;gt;K^m (A, r^0) = span(r^0, Ar^0, A^2r^0, ..., A^{m-1} r^0).&amp;lt;/math&amp;gt;&amp;lt;ref&amp;gt;Горбаченко В.И, Вычислительная линейная алгебра с примерами на MATLAB. — СПб.: БХВ-Петербург, 2011. — 320 с.: ил. — (Учебное пособие)&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:Изложим основную идею любого проекционного метода, заложенную в том числе и в BiCGSTAB. Для простоты выкладок и рассуждений здесь и далее будем считать, что матрица системы и ее правая часть вещественны. Без ограничения общности все дальнейшие рассуждения могут быть перенесены и на комплексный случай. Итак, пусть решается система &amp;lt;math&amp;gt;Ax=b&amp;lt;/math&amp;gt; с невырожденной матрицей  &amp;lt;math&amp;gt;A \in R^{n \times n}&amp;lt;/math&amp;gt; и ненулевым  вектором  &amp;lt;math&amp;gt;b \in R^n&amp;lt;/math&amp;gt;.  Имеются  два подпространства &amp;lt;math&amp;gt;K_n&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;L_n&amp;lt;/math&amp;gt;. Требуется найти вектор &amp;lt;math&amp;gt;x \in K_n&amp;lt;/math&amp;gt;, который обеспечивает решение  системы, оптимальное относительно подпространства  L, то есть требуется выполнение условия Петрова-Галеркина: &amp;lt;math&amp;gt;(Ax,z)=(b,z), \forall z \in L_n&amp;lt;/math&amp;gt;. В данном случае вектор x называется обобщенным решением системы. &lt;br /&gt;
&lt;br /&gt;
:Условие Петрова-Галеркина можно записать и через определение невязки. Пусть &amp;lt;math&amp;gt;r = b - Ax&amp;lt;/math&amp;gt; - невязка, тогда условие Петрова-Галеркина перепишется в виде: &amp;lt;math&amp;gt;(b - Ax, z)=(r, z),\forall z \in L_n&amp;lt;/math&amp;gt;. Это равносильно тому, что вектор невязки ортогонален пространству &amp;lt;math&amp;gt;L_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Пусть для СЛАУ известно некоторое приближение &amp;lt;math&amp;gt;x^0&amp;lt;/math&amp;gt; точного решения &amp;lt;math&amp;gt;x^*&amp;lt;/math&amp;gt;. Данное приближение требуется уточнить поправкой &amp;lt;math&amp;gt; \delta: b - Ax^0 + \delta \perp L&amp;lt;/math&amp;gt;. Невязка уточненного решения имеет вид: &amp;lt;math&amp;gt;r_{new} = b - Ax^0 + \delta = r^0- A\delta&amp;lt;/math&amp;gt;. Условие Петрова-Галеркина тогда можно переписать так: &amp;lt;math&amp;gt;(r_{new}, z)= r^0 - (A\delta, z) = 0, \forall z \in L&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:Пусть  &amp;lt;math&amp;gt; dim K = dim L = m, V = (v_1, ..., v_n) \in R^{n \times m}, W = (w_1, ... w_n) \in R^{n \times m}&amp;lt;/math&amp;gt;, где V и W – матрицы, столбцы которых образуют базисы пространств K и L соответственно. Пусть так же &amp;lt;math&amp;gt; \delta = Vy, z = Wq&amp;lt;/math&amp;gt;, где y – коэффициенты разложения вектора поправки по базису пространства K, а q – коэффициенты разложения вектора z в пространстве L. Тогда новое приближение решения можно записать в виде: &amp;lt;math&amp;gt;x^1 = x^0 + \delta= x^0 + Vy&amp;lt;/math&amp;gt;. Из условия ортогональности Петрова-Галеркина получаем, что: &amp;lt;math&amp;gt;(r - AVy, Wq) = (W^Tr^0 - AVy, q) = 0&amp;lt;/math&amp;gt;. Поскольку &amp;lt;math&amp;gt;q \neq 0&amp;lt;/math&amp;gt;, то получаем СЛАУ для вектора y: &amp;lt;math&amp;gt;W^TAVy = W^Tr^0&amp;lt;/math&amp;gt;. Если предположить, что матрица &amp;lt;math&amp;gt;W^TAVy&amp;lt;/math&amp;gt; невырождена, то вектор y однозначно определяется и равен: &amp;lt;math&amp;gt;y = W^TAV^{-1}W^Tr^0&amp;lt;/math&amp;gt;. Подставляя найденные коэффициенты разложения в выражение для первого приближения получаем: &amp;lt;math&amp;gt;x^1 = x^0 + \delta = x^0 + W^TAV^{-1}W^Tr^0y&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:Подведем итог. Общий порядок шагов любого проекционного метода следующий:&lt;br /&gt;
#Выбрать пару подпространств &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt;&lt;br /&gt;
#Найти базис V пространства K и базис W пространства &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt;;&lt;br /&gt;
#Вычислить невязку&lt;br /&gt;
#Найти &amp;lt;math&amp;gt;y = W^T AV^{-1} W^T r^0&amp;lt;/math&amp;gt;&lt;br /&gt;
#Положить &amp;lt;math&amp;gt;x = x + Vy&amp;lt;/math&amp;gt;&lt;br /&gt;
#Если не достигнут критерий остановки итерационного процесса, то повторить алгоритм, начиная с первого шага.&lt;br /&gt;
&lt;br /&gt;
:Как будет показано далее, в BiCGSTAB не требуется вычислять матрицу  &amp;lt;math&amp;gt;W^T AV^{-1}&amp;lt;/math&amp;gt; в явном виде.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
:Рассмотрим СЛАУ с вещественными коэффициентами:&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;Ax = b, A \in R^{N \times N}, b \in R^N&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
:В основу алгоритма ложиться идея проекционного метода и использование свойства A-бисопряженности системы векторов, а именно: векторы &amp;lt;math&amp;gt;p^1, p^2, ...&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\overline p^1, \overline p^2, ...&amp;lt;/math&amp;gt; бисопряжены, если &amp;lt;math&amp;gt;(Ap^i,p^j ) = 0,&amp;lt;/math&amp;gt; при &amp;lt;math&amp;gt;i \neq j&amp;lt;/math&amp;gt;. Фактически, данное условие эквивалентно биортогональности относительно энергетического скалярного произведения. &lt;br /&gt;
 &lt;br /&gt;
:Общая концепция проекционных методов предписывает нам выбрать два подпространства. В нашем случае подпространства мы выберем два подпространства, задаваемые матрицей системы А, вектором невязки на нулевой итерации &amp;lt;math&amp;gt;r^0&amp;lt;/math&amp;gt; и вектором &amp;lt;math&amp;gt;\overline r^0&amp;lt;/math&amp;gt;. который выбирается из условия &amp;lt;math&amp;gt;(r^0, \overline r^0) \neq 0&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;K = K^k(A, r^0), L = K^k(A, \overline r^0)&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:Метод основан на построении биортогонального базиса &amp;lt;math&amp;gt;p^0, p^1, ... p^k .. &amp;lt;/math&amp;gt; пространства &amp;lt;math&amp;gt;K^k (A, r^0) &amp;lt;/math&amp;gt; и вычислении поправки такой, что новое приближение на очередной итерации было бы ортогонально второму подпространству Крылова. Базисные вектора строятся до тех пор, пока не будет достигнут критерий остановки итерационного процесса, а каждое последующее приближение формируется, как сумма приближения на предыдущей итерации и найденной поправки. Критерием останова итерационного процесса является достижения невязкой значения, которое меньше некоторого наперед заданного числа &amp;lt;math&amp;gt;\epsilon&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Основной итерационный процесс задается формулами:&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;x^{k + 1} = x^k + \alpha_k p_k + \omega_k s_k&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;p^{k + 1} = r^{k + 1} + \beta_k p_k - \omega_k Ap_k&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
:где:&lt;br /&gt;
#&amp;lt;math&amp;gt;x^{k + 1}&amp;lt;/math&amp;gt; - приближение на следующей итерации&lt;br /&gt;
#&amp;lt;math&amp;gt;x^k&amp;lt;/math&amp;gt; - приближение на предыдущей итерации&lt;br /&gt;
#&amp;lt;math&amp;gt;p_k&amp;lt;/math&amp;gt; - базисный вектор подпространства Крылова, порожденного матрице СЛАУ и невязкой&lt;br /&gt;
#&amp;lt;math&amp;gt;\alpha_k, \omega_k&amp;lt;/math&amp;gt; - вспомогательные скаляры, определяемые для каждого шага итерации&lt;br /&gt;
#&amp;lt;math&amp;gt;s_k&amp;lt;/math&amp;gt; - вспомогательный вектор&lt;br /&gt;
#&amp;lt;math&amp;gt;p^{k + 1}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;k + 1&amp;lt;/math&amp;gt;-ый базисный вектор&lt;br /&gt;
#&amp;lt;math&amp;gt;r^{k + 1}&amp;lt;/math&amp;gt; - невязка &amp;lt;math&amp;gt;k + 1&amp;lt;/math&amp;gt;-ой итерации&lt;br /&gt;
#&amp;lt;math&amp;gt;\beta_k&amp;lt;/math&amp;gt; - вспомогательный коэффициент&lt;br /&gt;
&lt;br /&gt;
:Вспомогательный вектор выражается следующим образом:&lt;br /&gt;
*&amp;lt;math&amp;gt;s_k = r^k - \alpha_k Ap_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:Вспомогательные коэффициенты вычисляются по формулам:&lt;br /&gt;
*&amp;lt;math&amp;gt;\alpha_k = \frac{(r^k, \overline r^0)}{(Ap_k, \overline r^0)}&amp;lt;/math&amp;gt;&lt;br /&gt;
*&amp;lt;math&amp;gt;\omega_k = \frac{(As_k, s_k)}{(As_k, As_k)}&amp;lt;/math&amp;gt;&lt;br /&gt;
*&amp;lt;math&amp;gt;\beta_k = \frac{(r^{k + 1}, \overline r^0)}{(r^k, \overline r^0}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:Подведем итог и запишем итерационный процесс&lt;br /&gt;
:Подготовительный этап:&lt;br /&gt;
#Выбирается некоторое начальное приближение &amp;lt;math&amp;gt;x^0&amp;lt;/math&amp;gt;&lt;br /&gt;
#По выбранному приближению находится невязка &amp;lt;math&amp;gt;r^0 = b - Ax^0&amp;lt;/math&amp;gt;&lt;br /&gt;
#Из условия &amp;lt;math&amp;gt;(r^0, \overline r^0) \neq 0&amp;lt;/math&amp;gt; выбирается вектор &amp;lt;math&amp;gt;\overline r^0&amp;lt;/math&amp;gt;&lt;br /&gt;
#Положим &amp;lt;math&amp;gt;p^0 = r^0&amp;lt;/math&amp;gt;&lt;br /&gt;
#Устанавливаем счетчик итераций: &amp;lt;math&amp;gt;n = 0&amp;lt;/math&amp;gt;&lt;br /&gt;
:Итерационный процесс:&lt;br /&gt;
#Находим &amp;lt;math&amp;gt;\alpha_k&amp;lt;/math&amp;gt;&lt;br /&gt;
#По найденному &amp;lt;math&amp;gt;\alpha_k&amp;lt;/math&amp;gt; вычисляем &amp;lt;math&amp;gt;s_k&amp;lt;/math&amp;gt;&lt;br /&gt;
#По найденному &amp;lt;math&amp;gt;s_k&amp;lt;/math&amp;gt; вычисляется вспомогательный коэффициент &amp;lt;math&amp;gt;\omega_k&amp;lt;/math&amp;gt;&lt;br /&gt;
#Находится новое приближение &amp;lt;math&amp;gt;x^{k + 1}&amp;lt;/math&amp;gt;&lt;br /&gt;
#Вычисляется невязка &amp;lt;math&amp;gt;r^{k + 1}&amp;lt;/math&amp;gt;. Если выполнено условие &amp;lt;math&amp;gt;\parallel r^{k + 1} \parallel &amp;lt; \epsilon&amp;lt;/math&amp;gt;, то алгоритм завершается.&lt;br /&gt;
#Вычисляется вспомогательный коэффициент &amp;lt;math&amp;gt;\beta_k&amp;lt;/math&amp;gt;&lt;br /&gt;
#Вычисляется новый базисный вектор: &amp;lt;math&amp;gt;p^{k + 1}&amp;lt;/math&amp;gt;&lt;br /&gt;
#Увеличивается номер итерации: &amp;lt;math&amp;gt;n = n + 1&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;
# [[Скалярное произведение векторов, вещественная версия, последовательно-параллельный вариант]] x 4 раза&lt;br /&gt;
# [[Умножение плотной матрицы на вектор ]] х 2 раза&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
:Всего в вычислительном блоке алгоритма присутствует 20 трудоемких операций: 2 операции умножения матрицы на вектор, 6 скалярных произведений и 6 сложений/вычитаний векторов и 6 умножений вектора на число.&lt;br /&gt;
&lt;br /&gt;
:Каждое скалярное произведение требует &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; произведений и &amp;lt;math&amp;gt;n - 1&amp;lt;/math&amp;gt; сложение, то есть &amp;lt;math&amp;gt;2n - 1&amp;lt;/math&amp;gt; операции. Скалярных произведений всего 6 штук (включая поиск нормы), что дает нам &amp;lt;math&amp;gt;12n - 6&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
:Умножение матрицы размерности &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt; на вектор эквивалентно взятию еще &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; скаляров, и так как таких операций в вычислительном ядре 2, то дополнительно имеется еще &amp;lt;math&amp;gt;2n(2n - 1)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
:Наконец, сложение или вычитание векторов требует &amp;lt;math&amp;gt;6n&amp;lt;/math&amp;gt; соотвествующих операций. Столько же требует 6 произведений вектора на число.&lt;br /&gt;
&lt;br /&gt;
:Итого: &amp;lt;math&amp;gt;2n(2n - 1) + 12n - 6 + 6n + 6n = 4n^2 + 22n - 6&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
:Нетрудоемкие операции, вроде извлечение квадратного корня и деление вещественных чисел друг на друга, не принимаются в расчет, так как они не влияют на итоговый результат. Окончательно можно заключить, что последовательная сложность алгоритма эквивалента &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[file:BiCGStabIterations.jpg|thumb|center|800px|&amp;lt;center&amp;gt;Информационный граф.&amp;lt;/center&amp;gt;]]&lt;br /&gt;
На графе представлены связи между операциями, выполняющимися в первых трех итерациях метода. При выполнении большего, чем 3, количества итераций, структура каждой новой будет повторять структуру третьей. Связи между итерациями не представлены, т.к. они не важны для понимания параллельной структуры алгоритма. Серым обозначено перемножение чисел, красным - умножение числа на вектор&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной прирост производительности параллельной версии алгоритма дает использование параллельных операций вычисления скалярного произведения, суммы векторов, а так же произведения матрицы на вектор. Каждая из операций вычисления скалярного произведения и суммы векторов, выполняемая на p процессорах, за счет метода сдваивания может ускориться до &amp;lt;math&amp;gt; \frac{p}{\log_2 p} &amp;lt;/math&amp;gt; раз. Ускорение же умножения матрицы на вектор может достигать p раз.&lt;br /&gt;
&lt;br /&gt;
Ширина и высота ЯПФ графа данного алгоритма напрямую зависит от конкретных реализаций макроопераций и входных данных.&lt;br /&gt;
&lt;br /&gt;
Для последовательно-параллельной реализации операции взятия скалярного произведения в наиболее оптимальном случае (&amp;lt;math&amp;gt;p= \sqrt n&amp;lt;/math&amp;gt;) высота будет равна &amp;lt;math&amp;gt;2 \sqrt n - 1&amp;lt;/math&amp;gt;, а ширина &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt;, где n - это длина вектора решения.&lt;br /&gt;
&lt;br /&gt;
Высота ЯПФ простейшего алгоритма умножения матрицы на вектор равна 2n, а ширина m, где n - это уже упомянутая длина вектора(она же ширина матрицы), а m - высота матрицы.&lt;br /&gt;
&lt;br /&gt;
Высота ЯПФ операции умножения вектора на число = &amp;lt;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt;, а ширина p.&lt;br /&gt;
&lt;br /&gt;
Высота ЯПФ операции вычисления разности векторов = &amp;lt;math&amp;gt; \log_2 p &amp;lt;/math&amp;gt;, а ширина p.&lt;br /&gt;
&lt;br /&gt;
В конечном счете общую высоту ЯПФ одной итерации алгоритма можно оценить, как &amp;lt;math&amp;gt;6 \sqrt n-3 + 4n + 3 + 1 + 3*\lceil \frac{n}{p} \rceil + 2* \lceil \frac{n}{p} \rceil = 6 \sqrt n + 4n + 5 \lceil \frac{n}{p} \rceil + 1&amp;lt;/math&amp;gt;, а ширину, как &amp;lt;math&amp;gt;2 \sqrt n&amp;lt;/math&amp;gt;, если не брать в рассчет проверку критерия сходимости и упрощенности первой итерации по сравнению с остальными.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
:Входные данные&lt;br /&gt;
#Матрица &amp;lt;math&amp;gt;A \in R^{N \times N}&amp;lt;/math&amp;gt; ( &amp;lt;math&amp;gt;C^{N \times N}&amp;lt;/math&amp;gt; )&lt;br /&gt;
#Вектор правой части &amp;lt;math&amp;gt;b \in R^N&amp;lt;/math&amp;gt; ( &amp;lt;math&amp;gt;C^N&amp;lt;/math&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
:Выходные данные:&lt;br /&gt;
#Вектор решения СЛАУ &amp;lt;math&amp;gt;x \in R^N&amp;lt;/math&amp;gt; ( &amp;lt;math&amp;gt;C^N&amp;lt;/math&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
:BiCGSTAB хорошо зарекомендовал себя для решения систем линейных алгебраический уравнений, поскольку обладает некоторыми важными свойствами:&lt;br /&gt;
#Благодаря применению подхода Петрова-Галеркина и техники ортогонализации, он численно устойчив&lt;br /&gt;
#Не меняется вид матрицы в процессе решения&lt;br /&gt;
#Эффективен для решения систем большой размерности с разреженной матрицей, поскольку в методе самая трудоемкая операция - умножение матрицы на вектор&lt;br /&gt;
#Лучше подходит под распределенные системы, поскольку не содержит операции транспонирования матрицы&lt;br /&gt;
#Применим для решения систем с несимметричными матрицами.&lt;br /&gt;
#Вычислительная мощность: &amp;lt;math&amp;gt;N/4&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;
===== Анализ на основе теста Apex-Map =====&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
==== Масштабируемость алгоритма ====&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
* Параллельная реализация алгоритма, предложенная MIT: [http://ab-initio.mit.edu/~meep/meep/src/bicgstab.cpp MIT BiCGSTAB]&lt;br /&gt;
* Параллельная реализация алгоритма в бесплатной библиотеке, поддерживающей MPI и OpenMP, HYPRE: [http://acts.nersc.gov/hypre/ Официальная страница] [https://github.com/LLNL/hypre/blob/master/src/krylov/bicgstab.c Исходный код]&lt;br /&gt;
* Параллельная реализация алгоритма на CUDA в условно бесплатной библиотеке [https://developer.nvidia.com/amgx/ NVIDIA AmgX]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;/div&gt;</summary>
		<author><name>Sleo</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:EasyBreezy&amp;diff=16835</id>
		<title>Обсуждение участника:EasyBreezy</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:EasyBreezy&amp;diff=16835"/>
		<updated>2016-11-13T23:19:00Z</updated>

		<summary type="html">&lt;p&gt;Sleo: Новая страница: «== Замечания к Стабилизированный_метод_биспоряженных_градиентов_(BiCGSTAB) ==  Все еще отсут…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Замечания к [[Стабилизированный_метод_биспоряженных_градиентов_(BiCGSTAB)]] ==&lt;br /&gt;
&lt;br /&gt;
Все еще отсутствует:&lt;br /&gt;
&lt;br /&gt;
1) пропущен пункт 1.5 &amp;quot;Схема реализации последовательного алгоритма&amp;quot; из-за чего сбита нумерация первой части, см [[Структура_описания_свойств_алгоритмов]]&lt;/div&gt;</summary>
		<author><name>Sleo</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:%D0%95%D0%B2%D0%B3%D0%B5%D0%BD%D0%B8%D0%B9_%D0%A0%D0%B0%D0%B5%D0%B2/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0_%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE_%D1%80%D0%B0%D0%B7%D0%BC%D0%B5%D1%80%D0%B0&amp;diff=16829</id>
		<title>Участник:Евгений Раев/Построение матрицы Адамара произвольного размера</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:%D0%95%D0%B2%D0%B3%D0%B5%D0%BD%D0%B8%D0%B9_%D0%A0%D0%B0%D0%B5%D0%B2/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0_%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE_%D1%80%D0%B0%D0%B7%D0%BC%D0%B5%D1%80%D0%B0&amp;diff=16829"/>
		<updated>2016-11-13T23:14:07Z</updated>

		<summary type="html">&lt;p&gt;Sleo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Построение матрицы Адамара произвольного размера&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n*(2^{n})^2))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O((2^n)^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(2^n)^2&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Работу выполнил студент 611 группы Раев Евгений.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Матрица Адамара&#039;&#039;&#039; &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; — это квадратная матрица размера &#039;&#039;n&#039;&#039;×&#039;&#039;n&#039;&#039;, составленная из чисел 1 и −1, столбцы которой ортогональны, так что справедливо соотношение &lt;br /&gt;
: &amp;lt;math&amp;gt;H \cdot H^T = n \cdot E_n,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;E_n&amp;lt;/math&amp;gt; — это единичная матрица размера &#039;&#039;n&#039;&#039;. Матрицы Адамара применяются в различных областях, включая комбинаторику, численный анализ, обработку сигналов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Матрица оператора Адамара&#039;&#039;&#039; имееет вид&lt;br /&gt;
:&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
  H = \frac{1}{\sqrt2}&lt;br /&gt;
   &amp;amp;\begin{pmatrix}\begin{array}{rr}&lt;br /&gt;
    1 &amp;amp; 1\\&lt;br /&gt;
    1 &amp;amp; -1&lt;br /&gt;
   \end{array}\end{pmatrix}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Соответственно, существует итерационная формула нахождения матриц Адамара, через тензорное произведение матрицы оператора Адамара на матрицу Адамара меньшего порядка:&lt;br /&gt;
:&amp;lt;math&amp;gt;H_n = H_{1} \otimes H_{n-1}&amp;lt;/math&amp;gt;, где знак &amp;lt;math&amp;gt; \otimes &amp;lt;/math&amp;gt; означает тензорное произведение.&lt;br /&gt;
&lt;br /&gt;
Мы будем использовать в дальнейшем нормализованную матрицу оператора Адамара, без коэффицента (для удобности вывода):&lt;br /&gt;
:&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
  H = &lt;br /&gt;
   &amp;amp;\begin{pmatrix}\begin{array}{rr}&lt;br /&gt;
    1 &amp;amp; 1\\&lt;br /&gt;
    1 &amp;amp; -1&lt;br /&gt;
   \end{array}\end{pmatrix}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Представим пример высчитывания матриц Адамара:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
    H_{0} = 1,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
    H_{1} = H_{1} \otimes H_{0} = \begin{pmatrix}\begin{array}{rr}&lt;br /&gt;
    1 &amp;amp; 1\\&lt;br /&gt;
    1 &amp;amp; -1&lt;br /&gt;
   \end{array}\end{pmatrix} \otimes 1 = \begin{pmatrix}\begin{array}{rr}&lt;br /&gt;
    1 &amp;amp; 1\\&lt;br /&gt;
    1 &amp;amp; -1&lt;br /&gt;
   \end{array}\end{pmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
    H_{2} = H_{1} \otimes H_{1} = \begin{pmatrix}\begin{array}{rr}&lt;br /&gt;
    1 &amp;amp; 1\\&lt;br /&gt;
    1 &amp;amp; -1&lt;br /&gt;
   \end{array}\end{pmatrix} \otimes \begin{pmatrix}\begin{array}{rr}&lt;br /&gt;
    1 &amp;amp; 1\\&lt;br /&gt;
    1 &amp;amp; -1&lt;br /&gt;
   \end{array}\end{pmatrix} =    \begin{pmatrix}\begin{array}{rrrr}&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp;  1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  1&lt;br /&gt;
    \end{array}\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
    H_{3} = H_{1} \otimes H_{2} = \begin{pmatrix}\begin{array}{rr}&lt;br /&gt;
    1 &amp;amp; 1\\&lt;br /&gt;
    1 &amp;amp; -1&lt;br /&gt;
   \end{array}\end{pmatrix} \otimes \begin{pmatrix}\begin{array}{rrrr}&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp;  1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  1&lt;br /&gt;
    \end{array}\end{pmatrix} =    \begin{pmatrix}\begin{array}{rrrrrrrr}&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp;  1 &amp;amp;  1 &amp;amp; 1 &amp;amp;  1 &amp;amp;  1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1 &amp;amp; 1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1 &amp;amp; 1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  1 &amp;amp; 1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1 &amp;amp; -1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp;  1 &amp;amp;  1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  -1 &amp;amp; -1 &amp;amp;  1 &amp;amp;  1 &amp;amp; -1\\&lt;br /&gt;
    \end{array}\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом, получаем последовательность матриц Адамамра размерностью &amp;lt;math&amp;gt;2^n&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H^{\otimes n} = H_1  \otimes ... \otimes H_1&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;H_{i,j} = (-1)^{\sum ij}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; - битовые представляения значений индексов, а &amp;lt;math&amp;gt;i j&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_{i,j} = (-1)^{\sum i  j}&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;
1. Определение индексов находимого элемента матрицы Адамара: &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2. Побитовое умножение индексов : &amp;lt;math&amp;gt;res = ij&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
3. Подсчет количества значащих единиц в &amp;lt;math&amp;gt;res&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;count = \sum res&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
4. Получение знака элемента по его четности: &amp;lt;math&amp;gt;sign = (-1)^{count}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Данному алгоритму соответствует приведенный ниже код на языке С++:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;lt;cmath&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
int get_sign(int i, int j) //Get sign Hadamard matrix&#039;s element by indices&lt;br /&gt;
{&lt;br /&gt;
    int res = i &amp;amp; j;&lt;br /&gt;
    int count;&lt;br /&gt;
    for (count=0; res; res&amp;gt;&amp;gt;=1) &lt;br /&gt;
        { &lt;br /&gt;
            if (res &amp;amp; 1)&lt;br /&gt;
                count++;&lt;br /&gt;
        }&lt;br /&gt;
    if (count &amp;amp; 1 ==1)&lt;br /&gt;
        return -1;&lt;br /&gt;
    else&lt;br /&gt;
        return 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int print_HadamardMatrix(int N) //print Hadamard matrix 2^n size&lt;br /&gt;
{&lt;br /&gt;
    int matr_size(pow(2,N));&lt;br /&gt;
    for (int i = 0; i &amp;lt; matr_size; i++)&lt;br /&gt;
    {&lt;br /&gt;
        for (int j = 0; j &amp;lt; matr_size; j++) &lt;br /&gt;
        {&lt;br /&gt;
&lt;br /&gt;
            if (get_sign(i,j)==1) &lt;br /&gt;
                    cout &amp;lt;&amp;lt;&amp;quot; 1 &amp;quot;;&lt;br /&gt;
            else &lt;br /&gt;
                    cout &amp;lt;&amp;lt;&amp;quot;-1 &amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        cout &amp;lt;&amp;lt; endl;&lt;br /&gt;
    }&lt;br /&gt;
    cout &amp;lt;&amp;lt; endl;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, const char * argv[]) &lt;br /&gt;
{&lt;br /&gt;
    if(argc!=2) &lt;br /&gt;
    {&lt;br /&gt;
        printf(&amp;quot;Matrix size missing\n&amp;quot;);&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int N(atoi(argv[1]));&lt;br /&gt;
    print_HadamardMatrix(N);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Построение матрицы Адамара порядка &amp;lt;math&amp;gt;2^n&amp;lt;/math&amp;gt; требует рассчета &amp;lt;math&amp;gt;(2^{n})^2&amp;lt;/math&amp;gt; элементов матрицы. Это включает в себя:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;(2^{n})^2&amp;lt;/math&amp;gt; побитовых умножений индексов элемента &amp;lt;math&amp;gt;i \&amp;amp; j&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2. Операция определения значащих единиц, состоит из последовательных сдвигов и умножений на 1. В худшем случае, если мы будет рассчитывать элемент с координатам &amp;lt;math&amp;gt;(2^n-1,2^n-1)&amp;lt;/math&amp;gt; будет произведено n операций сдвига (так как число &amp;lt;math&amp;gt;2^n-1 &amp;lt;/math&amp;gt; кодируется n битами), и n операций умножения на 1 (для определения значащей единицы). То есть не более чем &amp;lt;math&amp;gt;2\cdot n\cdot(2^{n})^2 &amp;lt;/math&amp;gt; операций на данном шаге.&lt;br /&gt;
&lt;br /&gt;
3. &amp;lt;math&amp;gt;(2^{n})^2&amp;lt;/math&amp;gt; побитовых умножений количества значащих единиц из предыдущего пункта с 1 для определения четности числа.&lt;br /&gt;
&lt;br /&gt;
Следовательно, общая последовательная сложность алгоритма, равна &amp;lt;math&amp;gt;(2^{n})^2 +2\cdot n\cdot(2^{n})^2 +  2^(2^{n})^2&amp;lt;/math&amp;gt;, то есть  &amp;lt;math&amp;gt;(2^{n})^2(2+2n)&amp;lt;/math&amp;gt;, или &amp;lt;math&amp;gt;O(n*(2^{n})^2))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
На рисунке ниже изображен информационный граф алгоритма. Всего возможно &amp;lt;math&amp;gt;(2^n)^2&amp;lt;/math&amp;gt; параллельных ветвей, так как каждый элемент матрицы может считаться независимо друг от друга.&lt;br /&gt;
[[File:GraphHamadard.jpg|thumb|center|800px|Рисунок 1. Двухмерная модель алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Raev_graph2.jpg|thumb|center|800px|Рисунок 1. Трехмерная модель алгоритма. In - взодные данные, Out - результаты, &amp;lt;math&amp;gt; \&amp;amp; &amp;lt;/math&amp;gt; - операция умножения,&amp;lt;math&amp;gt; \sum &amp;lt;/math&amp;gt; - операция подсчета значащих единиц,&amp;lt;math&amp;gt; \pm &amp;lt;/math&amp;gt; - операция определения знака элемента по четности]]&lt;br /&gt;
&lt;br /&gt;
1. Операция &amp;lt;math&amp;gt; \&amp;amp; &amp;lt;/math&amp;gt; - побитовое умножение индексов.&amp;lt;math&amp;gt;ij&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; соответствующие координаты элемента &amp;lt;math&amp;gt;h_{kl}&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2. Операция &amp;lt;math&amp;gt; \sum &amp;lt;/math&amp;gt; -подсчет количества значащих единиц. Состоит из последовательных сдвигов и побитового умножения с 1.&lt;br /&gt;
&lt;br /&gt;
3. Операция &amp;lt;math&amp;gt; \pm &amp;lt;/math&amp;gt; - определение четности количества значащих единиц. Состоит из побитового умножения количества значащих единиц с 1.&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения матрицы Адамара необходимы операции сдивга и побитового умножения. Расчет каждого элемента независим друг от друга, следовательно расчет каждого элемента будет являться параллельной ветвью (как видно на информационном графе). При расчете элемента все операции внутри параллельной ветви выполняются последовательно, ожидая окончания предыдущей.&lt;br /&gt;
&lt;br /&gt;
Основной вклад в высоту ярусно-параллельной формы вносит 2 шаг, осуществляющий подсчет количества значащих единиц.&lt;br /&gt;
&lt;br /&gt;
Ширина ярусно-параллельной формы будет равна &amp;lt;math&amp;gt;O((2^n)^2)&amp;lt;/math&amp;gt; - количество рассчитываемых элементов.&lt;br /&gt;
Высота ярусно-параллельной формы будет равна &amp;lt;math&amp;gt;O(2+2n)=O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: Одно натуральное число n. Данный алгоритм на основе этого числа строит матрицу Адамара &amp;lt;math&amp;gt;H_n&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;2^{n}\times 2^{n}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: 1 (число n).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: &amp;lt;math&amp;gt;2^{n}\cdot 2^n&amp;lt;/math&amp;gt; чисел, которые представляют собой элементы &amp;lt;math&amp;gt;H_{i,j}&amp;lt;/math&amp;gt; матрицы Адамара &amp;lt;math&amp;gt;H_{n}&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;2^{n}\times 2^{n}&amp;lt;/math&amp;gt;. Вообще говоря, в силу симметричности матрицы Адамара, можно хранить только половину от этих данных, но алгоритм в статье не предполагает такой оптимизации).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;(2^{n})^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
* Соотношение последовательной и параллельной сложности можно определить как отношение высоты ярусно-параллельной формы и общей последовательно сложности, то есть &amp;lt;math&amp;gt;\frac{ (2+2n)(2^n)^2 }{2+2n} = (2^n)^2 &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;\frac{ (2^{n})^2(2+2n) } {1+(2^{n})^2 } &amp;lt;/math&amp;gt; ( то есть &amp;lt;math&amp;gt;\approx 2n&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;n -&amp;gt; +\infty&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;
&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;
* [https://reference.wolframcloud.com/cloudplatform/ref/HadamardMatrix.html Wolfram]&lt;br /&gt;
* [https://www.mathworks.com/help/matlab/ref/hadamard.html?requestedDomain=www.mathworks.com MATLAB]&lt;br /&gt;
* [http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.linalg.hadamard.html SciPy]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
[1] Кронберг, Ю.И. Ожигов, А.Ю. Чернявский — Алгебраический аппарат квантовой информатики 2&lt;br /&gt;
&lt;br /&gt;
[2] Википедия – свободная энциклопедия [Электронный ресурс]. -  https://en.wikipedia.org/wiki/Hadamard_transform. - (дата обращения: 15.10.2016).&lt;/div&gt;</summary>
		<author><name>Sleo</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:%D0%95%D0%B2%D0%B3%D0%B5%D0%BD%D0%B8%D0%B9_%D0%A0%D0%B0%D0%B5%D0%B2&amp;diff=16828</id>
		<title>Обсуждение участника:Евгений Раев</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:%D0%95%D0%B2%D0%B3%D0%B5%D0%BD%D0%B8%D0%B9_%D0%A0%D0%B0%D0%B5%D0%B2&amp;diff=16828"/>
		<updated>2016-11-13T23:13:57Z</updated>

		<summary type="html">&lt;p&gt;Sleo: Новая страница: «Исправления:  Нету электронных ссылок из Литературы, которую вы указали, на конкретные к…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Исправления:&lt;br /&gt;
&lt;br /&gt;
Нету электронных ссылок из Литературы, которую вы указали, на конкретные куски текста внутри вашей статьи.&lt;/div&gt;</summary>
		<author><name>Sleo</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:%D0%91%D1%83%D0%B3%D0%B0%D0%BA%D0%BE%D0%B2_%D0%AE%D1%80%D0%B8%D0%B9/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0_%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D1%80%D0%B0%D0%B7%D0%BC%D0%B5%D1%80%D0%BD%D0%BE%D1%81%D1%82%D0%B8&amp;diff=16827</id>
		<title>Участник:Бугаков Юрий/Построение матрицы Адамара произвольной размерности</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:%D0%91%D1%83%D0%B3%D0%B0%D0%BA%D0%BE%D0%B2_%D0%AE%D1%80%D0%B8%D0%B9/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0_%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D1%80%D0%B0%D0%B7%D0%BC%D0%B5%D1%80%D0%BD%D0%BE%D1%81%D1%82%D0%B8&amp;diff=16827"/>
		<updated>2016-11-13T23:09:37Z</updated>

		<summary type="html">&lt;p&gt;Sleo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Sleo}}&lt;br /&gt;
Авторы: [[U:Бугаков Юрий|Бугаков Юрий]] (613 группа), Кужамалиев Ернур (601 группа).&lt;br /&gt;
&lt;br /&gt;
Бугаков Юрий: &lt;br /&gt;
&lt;br /&gt;
* Пункты 1.1, 1.2, 1.9, 1.10, 2.1, 2.7; &lt;br /&gt;
* Совместное обсуждение и работа над всей статьей в целом с другим автором.&lt;br /&gt;
&lt;br /&gt;
Кужамалиев Ернур: &lt;br /&gt;
&lt;br /&gt;
* Пункты 1.3, 1.4, 1.5, 1.6, 1.7 (рисунки авториские), 1.8;&lt;br /&gt;
* Совместное обсуждение и работа над всей статьей в целом с другим автором.&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Построение матрицы Адамара&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O( \left[ \frac{n}{4}\right]\,2^{2n})&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(2^{2n})&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;2^{2n}&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;
Важную роль в алгебре и комбинаторике играют матрицы Адамара, которые впервые были введены в математический обиход в конце прошлого века одним из крупнейших французских математиков [https://ru.wikipedia.org/wiki/%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80,_%D0%96%D0%B0%D0%BA Жаком Адамаром (1865-1963)]. Их применение в науке и технике посвящены тысячи публикаций. Они предоставляют эффективные возможности для организации хранения, обработки и передачи информации.&lt;br /&gt;
&lt;br /&gt;
Квадратная матрица Н порядка &#039;&#039;m&#039;&#039; с элементами ±1 называется матрицей Адамара, если выполняется условие&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt; H_m\,H_m^T = m\,E_m &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нетрудно заметить, что различные строки матрицы Адамара попарно ортогональны [1]. Также, можно увидеть из определения, что m четно и&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
H_{2m} =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
H_{m} &amp;amp;  H_{m}\\&lt;br /&gt;
H_{m} &amp;amp; -H_{m}\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
С матрицами Адамара связан ряд нерешенных проблем, одна из которых состоит в следующем. Мы уже видели, что порядок &#039;&#039;m&#039;&#039; матрицы Адамара при &#039;&#039;m&#039;&#039; ≥ 3 может быть лишь четным. Более того, при &#039;&#039;m&#039;&#039; ≥ 4 порядок обязан делиться на 4. До сих пор остается открытым вопрос: для любого ли &#039;&#039;m&#039;&#039;, кратного 4, существует матрица Адамара порядка m? Неизвестно, в частности, существует ли матрица Адамара порядка 268 (это наименьший порядок, кратный 4, для которого матрица Адамара еще не построена).&lt;br /&gt;
&lt;br /&gt;
Часто матрицу Адамара нормализуют и рассматривают размерности степени 2 (например [2],[3] и [4]). В дальнейшем будем рассматривать только такие случаи. Переопределим матрицу Адамара следующим образом:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Матрица Адамара &#039;&#039;H&#039;&#039;&amp;lt;sub&amp;gt;&#039;&#039;n&#039;&#039;&amp;lt;/sub&amp;gt;  - это матрица размера 2&amp;lt;sup&amp;gt;&#039;&#039;n&#039;&#039;&amp;lt;/sup&amp;gt;&amp;amp;nbsp;&amp;amp;times;&amp;amp;nbsp;2&amp;lt;sup&amp;gt;&#039;&#039;n&#039;&#039;&amp;lt;/sup&amp;gt;, для которой справедливо равенство&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;H_n = H_{1} \otimes H_{n-1}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
  H_1 = \frac{1}{\sqrt2}&lt;br /&gt;
   &amp;amp;\begin{pmatrix}\begin{array}{rr}&lt;br /&gt;
    1 &amp;amp; 1\\&lt;br /&gt;
    1 &amp;amp; -1&lt;br /&gt;
   \end{array}\end{pmatrix}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&#039;&#039;&#039;где &amp;lt;math&amp;gt; \otimes &amp;lt;/math&amp;gt; представляет собой [https://ru.wikipedia.org/wiki/%D0%A2%D0%B5%D0%BD%D0%B7%D0%BE%D1%80%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5 тензорное произведение].&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Представим некоторые частные примеры матриц Адамара:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
    H_0 = +1,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
  H_1 = \frac{1}{\sqrt2}&lt;br /&gt;
   \begin{pmatrix}\begin{array}{rr}&lt;br /&gt;
    1 &amp;amp; 1\\&lt;br /&gt;
    1 &amp;amp; -1&lt;br /&gt;
   \end{array}\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
  H_2 = \frac{1}{2}&lt;br /&gt;
   \begin{pmatrix}\begin{array}{rrrr}&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp;  1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  1&lt;br /&gt;
    \end{array}\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
  H_3 = \frac{1}{2^{\frac{3}{2}}}&lt;br /&gt;
   \begin{pmatrix}\begin{array}{rrrrrrrr}&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp;  1 &amp;amp;  1 &amp;amp; 1 &amp;amp;  1 &amp;amp;  1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1 &amp;amp; 1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1 &amp;amp; 1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  1 &amp;amp; 1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1 &amp;amp; -1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp;  1 &amp;amp;  1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  -1 &amp;amp; -1 &amp;amp;  1 &amp;amp;  1 &amp;amp; -1\\&lt;br /&gt;
    \end{array}\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;H_n&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;2^n\times 2^n&amp;lt;/math&amp;gt; можно вычислить поэлементно ([3], [4]):&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;h_{k,l} = \frac{1}{2^\frac{n}{2}} (-1)^{\sum_j k_j l_j}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
где &#039;&#039;k&#039;&#039;&amp;lt;sub&amp;gt;&#039;&#039;j&#039;&#039;&amp;lt;/sub&amp;gt; и &#039;&#039;l&#039;&#039;&amp;lt;sub&amp;gt;&#039;&#039;j&#039;&#039;&amp;lt;/sub&amp;gt; коэффициенты двоичного разложения чисел &#039;&#039;k&#039;&#039; и &#039;&#039;l&#039;&#039; (1 или 0):&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;k = \sum^{n}_{i=0} {k_i 2^i} = k_{n} 2^{n} + k_{n-1} 2^{n-1} + \cdots + k_1 2 + k_0&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
и&lt;br /&gt;
: &amp;lt;math&amp;gt;l = \sum^{n}_{i=0} {l_i 2^i} = l_{n} 2^{n} + l_{n-1} 2^{n-1} + \cdots + l_1 2 + l_0&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_{k,l} = \frac{1}{2^\frac{n}{2}} (-1)^{\sum_j k_j l_j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Основную часть метода составляют вычисления значений степени -1 для каждого элемента:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;\sum_{j=0}^n k_j l_j&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Как видно по формуле, получаемое значение равна количеству единиц в двоичной записи результата побитового умножения &#039;&#039;k&#039;&#039; и &#039;&#039;l&#039;&#039;. Существует эффективный метод вычисления количества единиц , сложность которого равна &#039;&#039;m&#039;&#039; операций вычитания и &#039;&#039;m&#039;&#039; операций побитового умножения, где &#039;&#039;m&#039;&#039;-искомое количество единиц.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
&lt;br /&gt;
1. Побитовое умножение &amp;lt;math&amp;gt;k\&amp;amp;l&amp;lt;/math&amp;gt;;  &lt;br /&gt;
&lt;br /&gt;
2. Вычисление количества единиц двоичной записи;&lt;br /&gt;
&lt;br /&gt;
3. Определение знака элемента по степени.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения матрицы Адамара порядка &amp;lt;math&amp;gt;N=2^n&amp;lt;/math&amp;gt; в первом шаге потребуется &amp;lt;math&amp;gt;N^2&amp;lt;/math&amp;gt; побитовых умножений &#039;&#039;k&amp;amp;l&#039;&#039;.&lt;br /&gt;
Во втором шаге, как говорилось выше, сложность метода вычисления количества единиц  числа в двоичном представлении равна удвоенному количеству единиц. В наихудшем случае сложность равна &amp;lt;math&amp;gt;2log_2N&amp;lt;/math&amp;gt;, при &#039;&#039;k=l=N-1&#039;&#039;, а в наилучшем 0. Для нахождения  степени всех элементов матрицы потребуются &amp;lt;math&amp;gt; 2N^2\left[\frac{log_2N}{4}\right]&amp;lt;/math&amp;gt; операций. В третьем шаге для определения знака потребуется &amp;lt;math&amp;gt;N^2&amp;lt;/math&amp;gt; операций, то есть сложность алгоритма &amp;lt;math&amp;gt; T(n) = 2\,(1+\left[\frac{n}{4}\right])\,2^{2n}. &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;k\&amp;amp;l&amp;lt;/math&amp;gt; - операция побитового умножения, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt; соответствующие координаты элемента &amp;lt;math&amp;gt;h_{kl}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* OP - вычисление количества единиц числа в двоичной системе. Состоит из последовательного применения операций вычитания и побитового умножения;&lt;br /&gt;
* SGN - определение знака соответствующего элемента. Если результат предыдущего шага четное, то знак положительный, иначе отрицательный.  &lt;br /&gt;
&lt;br /&gt;
[[file:Hadamar.png|thumb|center|1400px|Рисунок 1. Граф алгоритма.]]&lt;br /&gt;
[[file:OP3.png|thumb|center|1400px|Рисунок 2. Граф OP.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения матрицы порядка &amp;lt;math&amp;gt;N=2^n&amp;lt;/math&amp;gt; требуется последовательно выполнить следующие шаги:&lt;br /&gt;
* &amp;lt;math&amp;gt;N^2&amp;lt;/math&amp;gt;  вычислений побитового умножения,&lt;br /&gt;
* для каждого элемента от &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; операций вычитания и побитового умножения, в зависимости от результата предыдущего шага,&lt;br /&gt;
* &amp;lt;math&amp;gt;N^2&amp;lt;/math&amp;gt;  для определения знака значения элемента.&lt;br /&gt;
 &lt;br /&gt;
Таким образом для построения необходимы лишь простые операции вычитания и побитового умножения выполняемые с целыми положительными числами. Стоит заметить что вычисления для каждого элемента не зависят друг от друга. Также можно воспользоваться либо симметричностью матрицы Адамара либо закономерностью областей показанная в пункте 1.1.&lt;br /&gt;
Таким образом, основной вклад в высотe ЯПФ вносит операция вычисления количества единиц. Ширина ЯПФ будет равна &amp;lt;math&amp;gt;O(2^{2n})&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; n \in \N &amp;lt;/math&amp;gt; - размерность матрицы Адамара &amp;lt;math&amp;gt;H_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: 1 (натуральное число &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица Адамара &amp;lt;math&amp;gt;H_n&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;2^n\times 2^n&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2^{2n}&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;
* Соотношение последовательной и параллельной сложности:&lt;br /&gt;
Одним из трудных мест параллельной реализации является правильный выбор количества процессов. Рассматривается некоторое фиксированное число процессов &amp;lt;math&amp;gt;P\in \mathbb{N}&amp;lt;/math&amp;gt;. Считается, что каждый процесс &#039;&#039;P&#039;&#039; обрабатывает не более чем &amp;lt;math&amp;gt;\left[\frac{2^{2n}}{P}\right]\geq 1&amp;lt;/math&amp;gt; элементов. Тогда качественная формула может быть записана таким образом: &amp;lt;math&amp;gt;T(n,P)=2\,(1+\left[ \frac{n}{4} \right])\,\frac{2^{2n}}{P}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Неравенство &amp;lt;math&amp;gt;\left[\frac{2^{2n}}{P}\right]\geq 1&amp;lt;/math&amp;gt; можно переписать, как &amp;lt;math&amp;gt;log_2\,\sqrt{P}\leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Легко увидеть, что минимум функции &#039;&#039;T(n,P)&#039;&#039; будет при максимально возможном &#039;&#039;P&#039;&#039; : &amp;lt;math&amp;gt;log_2\,\sqrt{P}\leq n&amp;lt;/math&amp;gt;. Такое &#039;&#039;P&#039;&#039; будет оптимальным числом процессов для алгоритма. В частности, для &amp;lt;math&amp;gt;P=2^p,\,p\in\mathbb{N}&amp;lt;/math&amp;gt; оптимальное &amp;lt;math&amp;gt;P = 2^{2n}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:&amp;lt;math&amp;gt;\frac{T(n)}{T(n,P)}=P&amp;lt;/math&amp;gt;.&lt;br /&gt;
То есть, отношение последовательной и параллельной сложности будет &#039;&#039;линейно&#039;&#039; зависеть от &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;Вычислительная мощность&#039;&#039; алгоритма построения матрицы Адамара, как отношение числа операций к суммарному объему входных и выходных данных: &lt;br /&gt;
:&amp;lt;math&amp;gt;\,\frac{2^{2n}(2+[\frac{n}{4}])}{1+2^{2n}}\left( \sim [\frac{n}{4}],\,n\to+\infty \right)&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* Алгоритм построения матрицы Адамара является &#039;&#039;не детерминированным&#039;&#039;, так как число операций меняется в зависимости от входных данных (числа n, которое формирует матрицу размера 2&amp;lt;sup&amp;gt;&#039;&#039;n&#039;&#039;&amp;lt;/sup&amp;gt;&amp;amp;nbsp;&amp;amp;times;&amp;amp;nbsp;2&amp;lt;sup&amp;gt;&#039;&#039;n&#039;&#039;&amp;lt;/sup&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
* Степень исхода вершины информационного графа равна 1;&lt;br /&gt;
&lt;br /&gt;
* Алгоритм построения матрицы Адамара является &#039;&#039;сбалансированным&#039;&#039;. Так как количество вершин на разных процессорах одинаково, то алгоритм является сбалансированным по числу операций на каждом процессоре.&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;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void adamar(int** H, int n) // N = 2^n - размерность матрицы&lt;br /&gt;
{     &lt;br /&gt;
    int i,j,N;&lt;br /&gt;
    float h;&lt;br /&gt;
    h = pow(1/2,n/2); // h - нормализующий множитель&lt;br /&gt;
    N = pow(2,n);&lt;br /&gt;
&lt;br /&gt;
    for(i=0;i&amp;lt;N;++i) &lt;br /&gt;
    {&lt;br /&gt;
	for(j=0;j&amp;lt;N;++j)&lt;br /&gt;
	{&lt;br /&gt;
		ij = i &amp;amp; j;&lt;br /&gt;
    		for (l=0;ij;++l) ij&amp;amp;=ij-1; // l - количество единиц бинарного представления ij&lt;br /&gt;
		if(l%2==0) H[i][j] = h;&lt;br /&gt;
		else H[i][j] = -h;&lt;br /&gt;
	}&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Также существует рекурсивная реализация метода построения матрицы Адамара&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void adamar_recursion(int** H, int N, int i, int j, int h) // h - нормализующий множитель&lt;br /&gt;
{&lt;br /&gt;
    if(n==1) H[i][j] = h;&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        adamar(H, N/2, i, j, h);&lt;br /&gt;
        adamar(H, N/2, i, N/2+j, h);&lt;br /&gt;
        adamar(H, N/2, N/2+i, j, h);&lt;br /&gt;
        adamar(H, N/2, N/2+i, N/2+j, -h);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Или эквивалентный безрекурсивный вариант:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void adamar_not_recursion(int** H, int n) // N = 2^n - размерность матрицы&lt;br /&gt;
{     &lt;br /&gt;
    int i,j,N;&lt;br /&gt;
    float h;&lt;br /&gt;
    h = pow(1/2,n/2);&lt;br /&gt;
    N = pow(2,n);&lt;br /&gt;
    k=2;&lt;br /&gt;
    H[0][0] = h;&lt;br /&gt;
	&lt;br /&gt;
    while(k&amp;lt;=N)&lt;br /&gt;
    {&lt;br /&gt;
	for (i=0; i&amp;lt;k; ++i)&lt;br /&gt;
	{&lt;br /&gt;
		for (j=0; j&amp;lt;k; ++j)&lt;br /&gt;
		{&lt;br /&gt;
			if (i&amp;lt;k/2 &amp;amp;&amp;amp; j&amp;lt;k/2)&lt;br /&gt;
			{&lt;br /&gt;
			}&lt;br /&gt;
			else&lt;br /&gt;
			{&lt;br /&gt;
				if(i&amp;gt;=k/2 &amp;amp;&amp;amp; j&amp;gt;=k/2)&lt;br /&gt;
				{&lt;br /&gt;
					H[i][j] = -(H[i-k/2][j-k/2]);&lt;br /&gt;
				}&lt;br /&gt;
				else&lt;br /&gt;
				{&lt;br /&gt;
					if (i&amp;gt;j)&lt;br /&gt;
					{&lt;br /&gt;
						H[i][j] = H[i-k/2][j];&lt;br /&gt;
					}&lt;br /&gt;
					else&lt;br /&gt;
					{&lt;br /&gt;
						H[i][j] = H[i][j-k/2];&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
		&lt;br /&gt;
        k=k*2;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для данного случая, рекурсия является менее эффективной для генерации матрицы Адамара ([https://habrahabr.ru/post/256351/ Хабрахабр. О бедной рекурсии замолвите слово, или всё, что вы не знали и не хотите о ней знать.]). С точки зрения последовательной реализации, генерация матрицы Адамара с помощью adamar_not_recursion будет выигрывать у adamar, так как adamar_not_recursion будет выполнять меньшее количество операций. С точки зрения параллельной реализации adamar имеет 100% парализацию и при определенных условиях будет выигрывать по времени у распараллелинной adamar_not_recursion (пусть в adamar и будет выполняться большее количество операций, но они являются [https://ru.wikipedia.org/wiki/%D0%91%D0%B8%D1%82%D0%BE%D0%B2%D1%8B%D0%B5_%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%B8 битовыми операциями]).&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
Задача данного раздела - показать пределы [[глоссарий#Масштабируемость|&#039;&#039;масштабируемости&#039;&#039;]] алгоритма на различных платформах. Очень важный раздел. Нужно выделить, описать и оценить влияние точек барьерной синхронизации, глобальных операций, операций сборки/разборки данных, привести оценки или провести исследование [[глоссарий#Сильная масштабируемость|&#039;&#039;сильной&#039;&#039;]] и [[глоссарий#Слабая масштабируемость|&#039;&#039;слабой&#039;&#039;]] масштабируемости алгоритма и его реализаций.&lt;br /&gt;
&lt;br /&gt;
Масштабируемость алгоритма определяет свойства самого алгоритма безотносительно конкретных особенностей используемого компьютера. Она показывает, насколько параллельные свойства алгоритма позволяют использовать возможности растущего числа процессорных элементов. Масштабируемость параллельных программ определяется как относительно конкретного компьютера, так и относительно используемой технологии программирования, и в этом случае она показывает, насколько может вырасти реальная производительность данного компьютера на данной программе, записанной с помощью данной технологии программирования, при использовании бóльших вычислительных ресурсов (ядер, процессоров, вычислительных узлов).&lt;br /&gt;
&lt;br /&gt;
Ключевой момент данного раздела заключается в том, чтобы показать &#039;&#039;реальные параметры масштабируемости программы&#039;&#039; для данного алгоритма на различных вычислительных платформах в зависимости от числа процессоров и размера задачи  [4]. При этом важно подобрать такое соотношение между числом процессоров и размером задачи, чтобы отразить все характерные точки в поведении параллельной программы, в частности, достижение максимальной производительности, а также тонкие эффекты, возникающие, например, из-за блочной структуры алгоритма или иерархии памяти.&lt;br /&gt;
&lt;br /&gt;
На рис.5. показана масштабируемость классического алгоритма умножения плотных матриц в зависимости от числа процессоров и размера задачи. На графике хорошо видны области с большей производительностью, отвечающие уровням кэш-памяти.&lt;br /&gt;
[[file:Масштабируемость перемножения матриц производительность.png|thumb|center|700px|Рис.5 Масштабируемость классического алгоритма умножения плотных матриц в зависимости от числа процессоров и размера задачи]]&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;
# [http://www.exponenta.ru/soft/matlab/potemkin/book2/chapter5/hadamard.asp MATLAB];&lt;br /&gt;
# [https://reference.wolfram.com/language/ref/HadamardMatrix.html WOLFRAM];&lt;br /&gt;
# [http://pydoc.net/Python/rogues/0.3.0/rogues.matrices.hadamard/ Python];&lt;br /&gt;
# [http://www.obihiro.ac.jp/~suzukim/masuda/octave/html3/octave_97.html Octave].&lt;br /&gt;
&lt;br /&gt;
Стоит отметить, что во многих вычислительных пакетах встроена операция тензорного произведения матриц, которая позволяет строить матрицу Адамара по определению. Этот факт позволяет использовать матрицу Адамара в этих вычислительных пакетах: &lt;br /&gt;
# [https://ru.wikipedia.org/wiki/Maple MAPLE];&lt;br /&gt;
# [https://ru.wikipedia.org/wiki/Mathcad MATCATH].&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
[1] Мак-Вильямс Ф.Дж., Слоэн Н.Дж.А. Теория кодов, исправляющих ошибки: Пер. с англ. — М: Связь, 1979. — 744 с.&lt;br /&gt;
&lt;br /&gt;
[2] Кронберг, Ю.И. Ожигов, А.Ю. Чернявский — Алгебраический аппарат квантовой информатики 2&lt;br /&gt;
&lt;br /&gt;
[3] Kunz H.O.. On the Equivalence Between One-Dimensional Discrete Walsh-Hadamard and Multidimensional Discrete Fourier Transforms. IEEE Transactions on Computers. 28 (3): 267–8. [https://en.wikipedia.org/wiki/Digital_object_identifier doi]:[http://ieeexplore.ieee.org/document/1675334/ 10.1109/TC.1979.1675334]&lt;br /&gt;
&lt;br /&gt;
[4] Википедия – свободная энциклопедия [Электронный ресурс]. -  https://en.wikipedia.org/wiki/Hadamard_transform. - (дата обращения: 15.10.2016).&lt;br /&gt;
&lt;br /&gt;
[5] Воеводин В.В.. Воеводин Вл.В. Параллельные вычисления. - СПб.: БХВ-Петербург, 2002. - 608 с.&lt;br /&gt;
&lt;br /&gt;
[6] Воронцов К.В.. Математические методы обучения по прецедентам (теория обучения машин)&lt;/div&gt;</summary>
		<author><name>Sleo</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:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=16826</id>
		<title>Участник:Nikita/Построение матрицы Адамара</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:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=16826"/>
		<updated>2016-11-13T23:08:05Z</updated>

		<summary type="html">&lt;p&gt;Sleo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Sleo}}&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Построение матрицы Адамара&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы статьи: [[Участник:Nikita|Иванов Н.В.]] (1.1,1.7,1.9,1.10,2.7), [[Участник:Tsyganov Nikita|Цыганов Н.И.]] (1.2,1.3,1.4,1.5,1.6,1.7,1.8).&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Матрицы Адамара были введены в математический обиход в конце прошлого века и играют важную роль в алгебре и комбинаторике. Они находят широкое применение в теории кодирования (коды, исправляющие ошибки), теории планирования многофакторных экспериментов (блок-схемы) и других областях математики.&amp;lt;ref name=&amp;quot;rt&amp;quot;&amp;gt;http://cyberleninka.ru/article/n/matritsy-adamara-nechetnogo-poryadka.pdf&amp;lt;/ref&amp;gt; Сравнительно недавно (в 1960 г.) было замечено, что эти матрицы могут быть использованы для построения кодов с большим кодовым расстоянием.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Матрицей Адамара порядка n&#039;&#039;&#039;&#039;&#039; называется &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;, элементами которой являются +1 и −1 такая, что &amp;lt;math&amp;gt;H H^T = n E_n&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;E_n&amp;lt;/math&amp;gt; - единичная матрица размера n.&lt;br /&gt;
&lt;br /&gt;
Матрица Адамара обладает следующими &#039;&#039;свойствами&#039;&#039;:&lt;br /&gt;
* Различные строки матрицы ортогональны&lt;br /&gt;
* Скалярное произведение любой строки саму на себя равно n&lt;br /&gt;
* Умножение любой строки или столбца на -1 переводит H в другую матрицу Адамара&lt;br /&gt;
* Если все элементы первой строки и первого столбца равны +1, то матрица Адамара называется нормализованной&lt;br /&gt;
&lt;br /&gt;
Ниже показаны примеры нормализованных матриц Адамара порядка 1,2 и 4, причем нормализованность матриц сохраняется при перестановке любых строк и столбцов, кроме первых:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_1 = (1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_2 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1 &amp;amp; -1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_4 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; 1 &amp;amp; 1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; 1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; -1 &amp;amp; 1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Предполагается, что существуют матрицы Адамара порядка 1, 2 и всех порядков n, кратных 4, хотя это до сих пор еще не было доказано. Нет универсального алгоритма построения матрицы Адамара произвольного размера, но известно большое число методов для различных частных случаев, и наименьший порядок, для которого матрица Адамара еще не построена, равен 268 (на 1977 г.). &amp;lt;ref name=&amp;quot;rt2&amp;quot;&amp;gt;Мак-Вильямс Ф. Дж., Слоэн Н. Дж. А. Теория кодов, исправляющих ошибки: Пер. с англ. — М: Связь, 1979. — c. 52-57&amp;lt;/ref&amp;gt; Мы приведем метод построения Пейли, который важен для теории кодирования. &lt;br /&gt;
&lt;br /&gt;
====Метод Пейли====&lt;br /&gt;
Это построение дает матрицы Адамара любого порядка &amp;lt;math&amp;gt;n=p+1&amp;lt;/math&amp;gt;, кратного 4, где p-простое число.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Определение.&#039;&#039;&#039; Пусть p-простое число. Ненулевые квадраты чисел, приведенные по модулю p, называются квадратичными вычетами по модулю p или просто вычетами по модулю p.&lt;br /&gt;
&lt;br /&gt;
Функция &amp;lt;math&amp;gt;X(i)&amp;lt;/math&amp;gt;, называемая символом Лежандра, определяется на целых числах следующим образом:&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=0&amp;lt;/math&amp;gt;, если i кратно p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=1&amp;lt;/math&amp;gt;, если остаток от деления i на p является квадратным вычетом по модулю p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=-1&amp;lt;/math&amp;gt;, если остаток от деления i на p является невычетом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь мы построим матрицу Джекобстола &amp;lt;math&amp;gt;Q=(q_{ij})&amp;lt;/math&amp;gt;. Она представляет собой &amp;lt;math&amp;gt;(p*p)&amp;lt;/math&amp;gt;-матрицу, строки и столбцы которой пронумерованы числами 0,1,..., p-1, а элементы &amp;lt;math&amp;gt;q_{ij}=X(j-i)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Пусть теперь &amp;lt;math&amp;gt;&lt;br /&gt;
H =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1^T &amp;amp; Q-I\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Доказано, что такая матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; представляет собой нормализованную матрицу Адамара порядка p+1, которую называют матрицей типа Пейли.&amp;lt;ref name=&amp;quot;rt3&amp;quot;&amp;gt;http://tc.nsu.ru/uploads/codingtheory.pdf&amp;lt;/ref&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;gt;0&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число.&lt;br /&gt;
&lt;br /&gt;
Вспомогательные данные: &lt;br /&gt;
&lt;br /&gt;
* Число &amp;lt;math&amp;gt;p=n-1&amp;lt;/math&amp;gt;;&lt;br /&gt;
* Вектор квадратичных вычетов (по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;r_i&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;2p&amp;lt;/math&amp;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;h_{ij}&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;. Индексация строчек и столбцов идёт с нуля. &lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
:1. Строится вектор квадратичных вычетов &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt;.&lt;br /&gt;
:: Первые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов вектора &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;) определяются следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;i \in \{1^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, 2^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, ... , (\frac{p-1}{2})^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p\}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;, то есть если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; является квадратичным вычетом по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;;&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=-1&amp;lt;/math&amp;gt;, иначе.&lt;br /&gt;
::Вторые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов (&amp;lt;math&amp;gt;i=p,1,...,2p-1&amp;lt;/math&amp;gt;) являются копией первых &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов:&lt;br /&gt;
:::&amp;lt;math&amp;gt;r_i=r_{i-p}, i=p,1,...,2p-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
:2. Строится матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;.&lt;br /&gt;
::Элементы матрицы Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; находятся следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{0j}=1, j=0,1, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{i0}=1, i=1,2, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{ij}=r_{j-i+p}, i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро алгоритма состоит из &amp;lt;math&amp;gt;(n-1) \times (n-1)&amp;lt;/math&amp;gt; операций присваивания следующего вида:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;h_{ij}=r_{j-i+p},&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; i=1,2, ... ,n-1, j=1,2, ... ,n-1.&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;
Приведем процедуру на языке С++, реализующую описанный алгоритм. На вход процедуре подается порядок матрицы &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и ссылка на заполняемую матрицу &amp;lt;math&amp;gt;result&amp;lt;/math&amp;gt;. Считаем, что &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; положительно, делится на &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число, а размер матрицы &amp;lt;math&amp;gt;result&amp;lt;/math&amp;gt; равен &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void buildHadamardMatrix(int n, vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt; &amp;amp; result)&lt;br /&gt;
{&lt;br /&gt;
	// 1) Считаем вычеты по модулю p=n-1 и создаем вспомогательный массив вычетов residues&lt;br /&gt;
	// Достаточно посчитать значения (1^2 mod p), (2^2 mod p), ... , (((p-1)/2)^2 mod p) - эти значениями и будут являться вычетами.&lt;br /&gt;
	// Строим массив residues размера 2*p, в котором первые p элементов заполняются по следующей схеме: 1, если индекс элемента - вычет, -1 - иначе.&lt;br /&gt;
	// Вторая половина массива получается дублированием первой половины&lt;br /&gt;
	int p=n-1;&lt;br /&gt;
	vector&amp;lt;int&amp;gt; residues;&lt;br /&gt;
	residues.resize(2*p);&lt;br /&gt;
	// Заполняем массив&lt;br /&gt;
	for (int i=0; i&amp;lt;p; i++) {&lt;br /&gt;
		residue[i] = -1;&lt;br /&gt;
	}&lt;br /&gt;
	for (int i=1; i&amp;lt;= (p-1)/2; i++) {&lt;br /&gt;
		residue[i^2 % p] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	for (int i=p; i&amp;lt;2*p; i++) {&lt;br /&gt;
		residue[i] = residue[i-p];&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// 2) Построение матрицы Адамара&lt;br /&gt;
	// Заполнение первой строки 1-цами&lt;br /&gt;
	for (int j=0; j&amp;lt;n; j++) {&lt;br /&gt;
		result[0][j] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	// Заполнение первого столбца 1-цами&lt;br /&gt;
	for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
		result[i][0] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	// Заполнение оставшейся части матрицы с использованием вспомогательного массива вычетов residues&lt;br /&gt;
	for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
		for (int j=1; j&amp;lt;n; j++) {&lt;br /&gt;
			result[i][j] = residues[j-i+p];&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&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;
Основными операциями алгоритма являются:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций взятия остатка;&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2+\frac{5}{2}n-3&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;n-1&amp;lt;/math&amp;gt; параллельных ветвей, второй блок - &amp;lt;math&amp;gt;\frac{n}{2}-1&amp;lt;/math&amp;gt; параллельных ветвей, третий - &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; и четвёртый - &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Файл:i_graph2.png]]&lt;br /&gt;
&lt;br /&gt;
Каждая вершина из &amp;lt;math&amp;gt;A_1-A_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C_1-C_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;D_1-D_{n^2}&amp;lt;/math&amp;gt; соответствует операции присваивания, каждая вершина из &amp;lt;math&amp;gt;B_1-B_{\frac{n}{2}-1}&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;n-1&amp;lt;/math&amp;gt; операций присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-1&amp;lt;/math&amp;gt; участков, состоящих из трёх операций: умножения, взятия остатка и присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операций присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; операций присваивания.&lt;br /&gt;
&lt;br /&gt;
Из этого можно сделать вывод, что высота ярусно-параллельной формы информационного графа равняется 6 (присваивание, умножение, взятие остатка, присваивание, присваивание, присваивание). Ширина ярусно-параллельной формы равняется &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;, что означает, что при использовании &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; процессоров матрица Адамара будет строиться за 6 операций.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; число &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - порядок матрицы Адамара &amp;lt;math&amp;gt;H_n&amp;lt;/math&amp;gt;. Дополнительные ограничения на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;:&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - натуральное;&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4;&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое.&lt;br /&gt;
&#039;&#039;&#039;Объем входных данных:&#039;&#039;&#039; 1 (число &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; построенная матрица Адамара &amp;lt;math&amp;gt;H_n&amp;lt;/math&amp;gt; (её элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; (количество элементов матрицы Адамара размера &amp;lt;math&amp;gt;n*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;O(1)&amp;lt;/math&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
Алгоритм является полностью детерминированным. &lt;br /&gt;
&lt;br /&gt;
Для вершин &amp;lt;math&amp;gt;A_1-A_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B_1-B_{\frac{n}{2}-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C_1-C_{n-1}&amp;lt;/math&amp;gt; информационного графа степени исхода являются линейными, что означает, что при возможности на этапе реализации необходимо позаботиться об эффективном доступе к элементам массива &amp;quot;&amp;lt;math&amp;gt;residues&amp;lt;/math&amp;gt;&amp;quot;.&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;
* [https://www.mathworks.com/help/matlab/ref/hadamard.html?requestedDomain=www.mathworks.com MATLAB] (вносятся дополнительные ограничения, когда n, или n/12, или n/20 являются степенями по основанию 2)&lt;br /&gt;
* [http://r-survey.r-forge.r-project.org/survey/html/hadamard.html R]&lt;br /&gt;
* [https://reference.wolframcloud.com/cloudplatform/ref/HadamardMatrix.html Wolfram Mathematica]&lt;br /&gt;
* [http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.linalg.hadamard.html SciPy для Python]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;/div&gt;</summary>
		<author><name>Sleo</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:Elena777mc/%D0%9F%D0%BB%D0%BE%D1%82%D0%BD%D0%BE%D1%81%D1%82%D0%BD%D1%8B%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_DBSCAN&amp;diff=16824</id>
		<title>Участник:Elena777mc/Плотностный алгоритм кластеризации DBSCAN</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:Elena777mc/%D0%9F%D0%BB%D0%BE%D1%82%D0%BD%D0%BE%D1%81%D1%82%D0%BD%D1%8B%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_DBSCAN&amp;diff=16824"/>
		<updated>2016-11-13T22:53:39Z</updated>

		<summary type="html">&lt;p&gt;Sleo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Sleo}}&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Плотностный алгоритм кластеризации DBSCAN&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(|X| \log |X|)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(m)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:Elena777mc|Малахова Е.С.]] (1.2,1.4-1.8,2.7), [[Участник:Жаннат_Сагиолданова|Сагиолданова Ж.]] (1.1-1.3,1.9-1.10,3)&lt;br /&gt;
&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;x_1, x_2, ... , x_n (x_n&amp;lt;/math&amp;gt; имеет размерность  &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;) на &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; кластеров, так, чтобы в каждом кластере все элементы были схожи&lt;br /&gt;
в каком-то смысле. &amp;lt;math&amp;gt;x_i&amp;lt;/math&amp;gt; могут быть числовыми, категориальными или смешанными данными.  В плотностных методах кластеры рассматриваются как регионы пространства данных с высокой плотностью объектов, которые разделены регионами с низкой плотностью объектов.&lt;br /&gt;
&lt;br /&gt;
Алгоритм DBSCAN (Density Based Spatial Clustering of Applications with Noise) &amp;lt;ref&amp;gt;A density-based algorithm for discovering clusters in large spatial database / M. Ester, H.-P. Kriegel,&lt;br /&gt;
J. Sander, X. Xu // Proc. 1996 Intern. Conf. on Knowledge Discovery and Data Mining. – 1996. – P. 226 –&lt;br /&gt;
231.&amp;lt;/ref&amp;gt; –плотностной алгоритм для кластеризации пространственных данных с присутствием шума, был предложен Мартином Эстер, Гансом-Питером Кригель и их коллегами в 1996 году как решение проблемы разбиения (изначально пространственных) данных на кластеры произвольной формы. &lt;br /&gt;
&lt;br /&gt;
Большинство алгоритмов, производящих плоское разбиение, создают кластеры по форме близкие к сферическим, так как минимизируют расстояние точки до центра кластера.&lt;br /&gt;
&lt;br /&gt;
Авторы DBSCAN экспериментально показали, что их алгоритм способен распознать кластеры различной формы.&lt;br /&gt;
Идея, положенная в основу алгоритма, заключается в том, что внутри каждого кластера плотность точек (объектов) заметно выше, чем плотность снаружи кластера, а также плотность в областях с шумом ниже плотности любого из кластеров. Еще точнее, для каждой точки кластера ее окрестность в диапазоне заданного радиуса должна содержать не менее некоторого числа точек, которое задается пороговым значением.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
[[File:dbscan_osn.png|thumb|right|500px| Рис. 1. Пример ядровых, граничных и шумовых точек алгоритма &amp;lt;ref&amp;gt;http://stats.stackexchange.com/questions/194734/dbscan-what-is-a-core-point&amp;lt;/ref&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
Исходные данные: объекты, которые нужно кластеризовать, параметры &amp;lt;math&amp;gt;MinPts, \  \varepsilon&amp;lt;/math&amp;gt; . Между объектами можно считать расстояния.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: разбиение объектов по кластерам. Количество кластеров зависит от исходных данных.  &amp;lt;ref&amp;gt;&amp;quot;Xu, X. A fast parallel clustering algorithm for large spatial databases / X. Xu, M. Ester, H.-P. Kriegel // Proc. 1999 Intern. Conf. on Knowledge Discovery and Data Mining. – 1999. – Vol. 3, is. 3. – P. 263 – 290.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для построения оценки плотности, на основе соседства точек вводятся понятия&lt;br /&gt;
достижимости и связности. Под &amp;lt;math&amp;gt;\varepsilon &amp;lt;/math&amp;gt; -соседями точки &amp;lt;math&amp;gt;x \in X&amp;lt;/math&amp;gt; понимается множество точек, расстояние до которых не превышает &amp;lt;math&amp;gt;\varepsilon &amp;lt;/math&amp;gt;, т. е.&lt;br /&gt;
 &amp;lt;math&amp;gt;N_\varepsilon (x) = \{y \in X | D(x, y) \le \varepsilon\}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Тогда точка &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; достижима из точки &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, если существует последовательность точек &amp;lt;math&amp;gt;x^{(1)}=x, x^{(2)},... , x^{(p-1)}, x^{(p)}=y&amp;lt;/math&amp;gt;, для которой выполнено:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
  \begin{align}&lt;br /&gt;
x^{(i+1)} \in N_\varepsilon (x^{(i)}), i=1,... ,p-1 \\&lt;br /&gt;
\mid  N_\varepsilon (x^{(i)}) \mid \ge MinPts, i=1,... ,p-1&lt;br /&gt;
  \end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здесь значение &amp;lt;math&amp;gt;MinPts&amp;lt;/math&amp;gt; задаётся пользователем и регулирует порог «шума». Согласно второму условию, у точек, находящихся внутри кластера, должно быть не менее &amp;lt;math&amp;gt;MinPts \   \varepsilon&amp;lt;/math&amp;gt; -соседей. Такие точки называются «ядрами». Остальные точки разделяются на граничные (имеющие менее &amp;lt;math&amp;gt;MinPts \   \varepsilon &amp;lt;/math&amp;gt; -cоседей, но достижимые из какого-либо «ядра») и шумовые. Две точки связны, если существует «ядро», из которого они обе достижимы.&lt;br /&gt;
При такой постановке задачи, под кластером понимается максимальное связное подмножество множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; . Точки, не попавшие в какой-либо кластер (не принадлежащие &amp;lt;math&amp;gt;\varepsilon&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;\varepsilon&amp;lt;/math&amp;gt;-соседей каждого объекта входного множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;. На эту часть алгоритма приходится основное время работы алгоритма, так как требуется найти всех соседей для каждого объекта заданного множества. Основные операции, которые применяются в вычислительном ядре  алгоритма: нахождение расстояние между объектами и сравнение расстояния с порогом для определения того, являются ли данные объекты &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседями.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма == &lt;br /&gt;
Алгоритм DBSCAN использует пространственную структуру данных для определения соседних объектов. Это может быть R*-дерево или kd-дерево. Такие структуры данных позволяют найти все объекты в пределах определенного расстояния от текущего объекта. Сложность построения таких структур &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt;, и использование такой структуры не увеличит сложность всего алгоритма (если сложность самого алгоритма &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt;). Также для построения таких деревьев нужно уметь находить расстояния между объектами &amp;lt;math&amp;gt;\rho(u,v)&amp;lt;/math&amp;gt;, это расстояние можно вводить разными способами. Например, если &amp;lt;math&amp;gt;\rho(u,v)&amp;lt;/math&amp;gt; - метрика в евклидовом пространстве, &amp;lt;math&amp;gt;u=(u_1,...,u_n)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(v_1,...,v_n)&amp;lt;/math&amp;gt;, то расстояние вычисляется следующим образом: &amp;lt;math&amp;gt;\rho(u,v)=\sqrt{(u_1-v_1)^2+(u_2-v_2)^2+...+(u_n-v_n)^2} = \sqrt{\sum_{k=1}^n(u_k-v_k)^2}&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;DBSCAN(X, \varepsilon, MinPts)&amp;lt;/math&amp;gt;&lt;br /&gt;
 //Изначально все объекты в &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;не кластеризованы&lt;br /&gt;
    &amp;lt;math&amp;gt;FORALL&amp;lt;/math&amp;gt;  objects  &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; in &amp;lt;math&amp;gt;X\  DO&amp;lt;/math&amp;gt;&lt;br /&gt;
       &amp;lt;math&amp;gt;IF\  x&amp;lt;/math&amp;gt; is unclassified&lt;br /&gt;
         call function &amp;lt;math&amp;gt;expand\_cluster&amp;lt;/math&amp;gt; to construct a cluster wrt. &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;MinPts&amp;lt;/math&amp;gt; containing &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 // Вспомогательная функция, которая строит кластер на основе одной точки&lt;br /&gt;
 &amp;lt;math&amp;gt;FUNCTION\ expand\_cluster(x,X,\varepsilon, MinPts):&amp;lt;/math&amp;gt;&lt;br /&gt;
    &amp;lt;math&amp;gt;retrive\_\varepsilon neighborhood(x, \varepsilon)&amp;lt;/math&amp;gt;;&lt;br /&gt;
    &amp;lt;math&amp;gt;IF \mid N_{\varepsilon}(x) \mid &amp;lt; MinPts&amp;lt;/math&amp;gt; //т.е. &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; - не ядровой объект&lt;br /&gt;
       mark &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; as &amp;lt;math&amp;gt;noise&amp;lt;/math&amp;gt;  and &amp;lt;math&amp;gt;RETURN&amp;lt;/math&amp;gt;;&lt;br /&gt;
    &amp;lt;math&amp;gt;ELSE&amp;lt;/math&amp;gt;//т.е. &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; - ядровой объект&lt;br /&gt;
       select a new cluster-id and mark all objects in &amp;lt;math&amp;gt;N_{\varepsilon}(x)&amp;lt;/math&amp;gt; with this current &amp;lt;math&amp;gt;cluster-id&amp;lt;/math&amp;gt;; &lt;br /&gt;
       push all objects from &amp;lt;math&amp;gt;N_{\varepsilon}(x)&amp;lt;/math&amp;gt;\&amp;lt;math&amp;gt;(x)&amp;lt;/math&amp;gt; onto the stack seeds;&lt;br /&gt;
       &amp;lt;math&amp;gt;WHILE\ NOT&amp;lt;/math&amp;gt; seeds.empty() &amp;lt;math&amp;gt;DO&amp;lt;/math&amp;gt; &lt;br /&gt;
         &amp;lt;math&amp;gt;currentObject&amp;lt;/math&amp;gt; := seeds.top();&lt;br /&gt;
         seeds.pop();&lt;br /&gt;
         &amp;lt;math&amp;gt;retrive\_\varepsilon neighborhood(currentObject, \varepsilon)&amp;lt;/math&amp;gt;;&lt;br /&gt;
         &amp;lt;math&amp;gt;IF \mid N_{\varepsilon}(currentObjects) \mid \ge MinPts&amp;lt;/math&amp;gt;&lt;br /&gt;
           select all objects in &amp;lt;math&amp;gt;N_{\varepsilon}(currentObject)&amp;lt;/math&amp;gt; not yet classified or marked as &amp;lt;math&amp;gt;noise&amp;lt;/math&amp;gt;,&lt;br /&gt;
           push the unclassified objects onto seeds and mark all of these objects with current &amp;lt;math&amp;gt;cluster-id&amp;lt;/math&amp;gt;;&lt;br /&gt;
     &amp;lt;math&amp;gt;RETURN&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 // Вспомогательная функция, для определения &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей для объекта&lt;br /&gt;
 &amp;lt;math&amp;gt;FUNCTION\ retrive\_\varepsilon neighborhood(x, \varepsilon)&amp;lt;/math&amp;gt; //функция возвращает соседей на основе пространственной структуры данных&lt;br /&gt;
   return &amp;lt;math&amp;gt;\{ x&#039; \ | \ \forall x&#039; \in X: \rho(x, x&#039;) &amp;lt; \varepsilon \}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Для того, чтобы алгоритм мог кластеризовать все объекты, необходимо пройти по каждому из них хотя бы один раз. Если использовать R*-дерево или kd-дерево для определения соседних объектов со сложностью &amp;lt;math&amp;gt;O(\log n)&amp;lt;/math&amp;gt;, то сложность алгоритма &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt;. Если не использовать эти структуры, то в худшем случае алгоритм будет иметь сложность &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, так как придется считать полную матрицу расстояний между объектами.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
В настоящем алгоритме осуществляется параллелизм по данным. Ниже представлена общая структура данного алгоритма. &lt;br /&gt;
[[File:Dbscan_schema.jpg|1000px|thumb|center|Рис.1. Общая информационная структура алгоритма]]&lt;br /&gt;
Разбиение данных происходит с помощью пространственной структуры данных (R*-дерево, kd-дерево), которая разбивает все множество объектов &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; частей: &amp;lt;math&amp;gt;X_1,X_2,...,X_m&amp;lt;/math&amp;gt;.&lt;br /&gt;
[[File:dbscan_clusters_partitions.png|500px|thumb|center|Рис.2. Пример разбиения объектов на части на основе пространственной структуры&amp;lt;ref&amp;gt;https://github.com/bwoneill/pypardis/blob/master/plots/median_search_split/clusters_partitions.png&amp;lt;/ref&amp;gt;]]&lt;br /&gt;
На каждой части объектов применяется алгоритм PDBSCAN (каждая часть использует пространственную структуру данных, которая распределяется вместе с каждой частью данных). Данный алгоритм отличается от общего алгоритма DBSCAN тем, что применяется к части объектов и для каждой из этих частей определяет кандидатов на слияние. Если для ядрового объекта части &amp;lt;math&amp;gt;X_i&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-окрестности находится объект из другой части &amp;lt;math&amp;gt;X_j&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;O(m)&amp;lt;/math&amp;gt;, где m - количество частей, на которые разбиваются все входное множество объектов &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;. Высотой ярусно-параллельной формы алгоритма является &amp;lt;math&amp;gt;O(|X| \log |X|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\mid X \mid&amp;lt;/math&amp;gt; - максимальное количество среди числа объектов в каждой части разбиения. Именно такую сложность имеет алгоритм PDBSCAN, применяемый к каждой отдельной части разбиения.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: множество точек X из n-мерного пространства, на котором определена функция расстояния D. В наиболее распространенном случае пространственной кластеризации используется Евлидова метрика между векторами из &amp;lt;math&amp;gt;{R}^n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: n (размерность входящего множества)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: размеченное множество точек X, в котором каждой точке соответствует номер ее кластера. Обычно каждой точке из X сопоставляется ее номер, а на выходе алгоритм дает отображение номеров точек в номера соответствующих им кластеров, например в виде вектора размера |X|&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: n (размерность выходящего множества)&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительная мощность, как отношение числа операций к суммарному объему входных и выходных данных логарифмическая.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039; Преимущества алгоритма &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* алгоритм может обрабатывать большой объем данных и не зависит от порядка ввода данных;&lt;br /&gt;
* может определять кластера произвольной формы; &lt;br /&gt;
* параллельная реализация сбалансирована по количеству и виду производимых операций (вычисление расстояния, сравнение с &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;);&lt;br /&gt;
* не требуется задание числа кластеров;&lt;br /&gt;
* может выделять кластеры в присутствии «шума»и выбросов &amp;lt;ref&amp;gt;АЛГОРИТМЫ КЛАСТЕРИЗАЦИИ В ЗАДАЧАХ СЕГМЕНТАЦИИ&lt;br /&gt;
СПУТНИКОВЫХ ИЗОБРАЖЕНИЙ/ И. А. Пестунов, Ю. Н. Синявский// Вестник Кемеровского государственного университета. – 2012. – P. 263–&lt;br /&gt;
299.&amp;lt;/ref&amp;gt;;&lt;br /&gt;
* число итераций определяется заранее.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039; Недостатки алгоритма &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* не может выделять кластеры сложной структуры, например, имеющие разную плотность, так как параметры алгоритма не могут быть выбраны отдельно для каждого кластера;&lt;br /&gt;
* не может построить иерархическую структуру кластеров;&lt;br /&gt;
* не детерминирован, так как граничные точки, достижимые из более, чем одного кластера, могут быть частью любого из них в зависимости от порядка обрабатываемых данных. Однако такая ситуация возникает редко, а относительно ядровых точек и шума DBSCAN детерминирован.&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;
* [http://scikit-learn.org/stable/modules/generated/sklearn.cluster.DBSCAN.html Scikit learn (Python, последовательная реализация)]&lt;br /&gt;
* [http://cucis.ece.northwestern.edu/projects/Clustering/download_code_dbscan.html Northwestern University (C++, параллельная реализация kd-tree)]&lt;br /&gt;
* [https://github.com/ContinuumIO/parallel_dbscan github/ContinuumIO (Python, параллельная реализация)]&lt;br /&gt;
* [https://github.com/propanoid/DBSCAN github/propanoid (C++, последовательная реализация VP tree)]&lt;br /&gt;
* [https://github.com/dparks1134/DBSCAN github/dparks1134 (С++, последовательная реализация)]&lt;br /&gt;
* [https://github.com/ahbarnett/validspike/tree/master/contrib/dbscan_patwary Disjoint-Set Data Structure based Parallel DBSCAN (C++ параллельная реализация kd-tree)]&lt;br /&gt;
* [https://github.com/bwoneill/pypardis github/bwoneill (Spark/Python параллельная реализация kd-tree)]&lt;br /&gt;
* [https://github.com/alitouka/spark_dbscan github/alitouka (Spark/Scala параллельная реализация)]&lt;br /&gt;
* [https://github.com/mhahsler/dbscan CRAN (R, последовательная реализация)]&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;br /&gt;
&amp;lt;references \&amp;gt;[https://pdfs.semanticscholar.org/a3f8/a3948e5999def4a0819d0dbaef2ae05e1599.pdf (A Fast Parallel Clustering Algorithm for Large Spatial Databases, JOCHEN JAGER, HANS-PETER KRIEGEL)]&lt;br /&gt;
&amp;lt;references \&amp;gt;[http://cyberleninka.ru/article/n/algoritmy-klasterizatsii-v-zadachah-segmentatsii-sputnikovyh-izobrazheniy (АЛГОРИТМЫ КЛАСТЕРИЗАЦИИ В ЗАДАЧАХ СЕГМЕНТАЦИИ СПУТНИКОВЫХ ИЗОБРАЖЕНИЙ, Пестунов Игорь Алексеевич, Синявский Юрий Николаевич)]&lt;br /&gt;
&lt;br /&gt;
[[en:Cholesky decomposition]]&lt;br /&gt;
&lt;br /&gt;
[[Категория:Законченные статьи]]&lt;/div&gt;</summary>
		<author><name>Sleo</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:Dadrik/%D0%9F%D0%BB%D0%BE%D1%82%D0%BD%D0%BE%D1%81%D1%82%D0%BD%D1%8B%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8&amp;diff=16823</id>
		<title>Участник:Dadrik/Плотностный алгоритм кластеризации</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:Dadrik/%D0%9F%D0%BB%D0%BE%D1%82%D0%BD%D0%BE%D1%81%D1%82%D0%BD%D1%8B%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8&amp;diff=16823"/>
		<updated>2016-11-13T22:51:36Z</updated>

		<summary type="html">&lt;p&gt;Sleo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Преподаватель 1|Sleo}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Плотностный алгоритм кластеризации DBSCAN&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Авторы описания: [[Участник:Dadrik | Вашуров И.М.]], [[Участник:ramon93i7 | Шемякин Р.О.]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Задача кластеризации - это задача разбиения заданной входной выборки объектов на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из схожих объектов, а объекты разных кластеров существенно отличались.&lt;br /&gt;
&lt;br /&gt;
Алгоритм DBSCAN (Density-based spatial clustering of applications with noise)&amp;lt;ref&amp;gt;Ester, Martin, et al. &amp;quot;A density-based algorithm for discovering clusters in large spatial databases with noise.&amp;quot; Kdd. Vol. 96. No. 34. 1996.&amp;lt;/ref&amp;gt; был предложен Мартином Эстер, Гансом-Питером Кригель и коллегами в 1996 году как решение задачи кластеризации с кластерами произвольной формы. DBSCAN является непараметрическим плотностным алгоритмом кластеризации: для заданного набора точек в некотором пространстве, алгоритм группирует те точки, которые расположены достаточно близко друг к другу (точки с большим количеством соседей), и помечает как выбросы те, что располагаются далеко от ближайших соседей.&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;X&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;-мерного пространства, на котором определена функция расстояния &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Выход алгоритма: размеченное множество точек &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;, в котором каждой точке соответствует номер ее кластера.&lt;br /&gt;
&lt;br /&gt;
Параметры алгоритма: &lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; - максимальное расстояние между соседями;&lt;br /&gt;
* &amp;lt;math&amp;gt;MinPts&amp;lt;/math&amp;gt; - минимальное количество соседей для создания области связности.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Определения ===&lt;br /&gt;
&lt;br /&gt;
[[File:Cluster_scheme.png|thumb|right|400px| Рис. 1. [https://upload.wikimedia.org/wikipedia/commons/a/af/DBSCAN-Illustration.svg] Здесь &#039;&#039;MinPts&#039;&#039; = 4. Точка &#039;&#039;A&#039;&#039; и другие красные точки - ядровые и образуют единый кластер, так как достижимы друг из друга. Точки &#039;&#039;B&#039;&#039; и &#039;&#039;C&#039;&#039; не являются ядровыми, но достижимы из &#039;&#039;A&#039;&#039;, а значит также принадлежат кластеру. Точка &#039;&#039;N&#039;&#039; - не достижима из других точек и является шумом.]]&lt;br /&gt;
&lt;br /&gt;
Все заданные точки классифицируются на три группы:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;ядровые точки&#039;&#039;: точка &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; является ядровой, если количество &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей, включая саму точку &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, не меньше &amp;lt;math&amp;gt;MinPts&amp;lt;/math&amp;gt;. Под &#039;&#039;&amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседями&#039;&#039; точки &amp;lt;math&amp;gt;p \in X&amp;lt;/math&amp;gt; понимается множество точек, расстояние до которых не превышает &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;N_\varepsilon(p) = \{ x \in X | D(p, x) \le \varepsilon \}&amp;lt;/math&amp;gt;. Эти точки являются напрямую достижимыми из &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;достижимые точки&#039;&#039;: точка &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; достижима из &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, если  существует путь &amp;lt;math&amp;gt;p_1, \dots, p_n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;p_1 = p&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_n = q&amp;lt;/math&amp;gt;, для которого выполнено: &lt;br /&gt;
:&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
p_{i + 1} \in N_\varepsilon(p_i),  i = 1, \dots, n-1 \\&lt;br /&gt;
| N_\varepsilon(p_{i}) | \ge MinPts, i = 1, \dots, n-1 \\&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;шум&#039;&#039; (выбросы): все точки, недостижимые из какой-либо другой точки считаются шумом (выбросом).&lt;br /&gt;
&lt;br /&gt;
Так, если &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - ядровая точка, то она образует кластер вместе со всеми точками, достижимыми из неё. Каждый кластер содержит по крайней мере одну ядровую точку; неядровые точки могут быть частью кластера, образуя при этом его &amp;quot;границу&amp;quot;, так как они не могут быть использованы для достижения других точек.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Достижимость не является симметричным отношением, так как по определению никакая точка не может быть достижима из неядровой точки, независимо от расстояния. Поэтому в DBSCAN применяется следующий термин &#039;&#039;связности&#039;&#039;: две точки &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; связанны, если существует такая точка &amp;lt;math&amp;gt;o&amp;lt;/math&amp;gt;, что &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; достижимы из &amp;lt;math&amp;gt;o&amp;lt;/math&amp;gt;. Такое отношение связности симметрично.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Кластер&#039;&#039; в таком случае определяется двумя свойствами:&lt;br /&gt;
* Все точки внутри кластера взаимно связанны;&lt;br /&gt;
* Если точка достижима из любой точки кластера, она также является частью кластера.&lt;br /&gt;
&lt;br /&gt;
=== Шаги алгоритма ===&lt;br /&gt;
&lt;br /&gt;
#Выбирается произвольная непосещенная точка &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;.&lt;br /&gt;
#Точка &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; помечается как посещенная. &lt;br /&gt;
#У точки &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; определяется множество её &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей - &amp;lt;math&amp;gt;N_\varepsilon(p)&amp;lt;/math&amp;gt;.&lt;br /&gt;
#*Если точка &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; оказалась ядровой - &amp;lt;math&amp;gt;| N_\varepsilon(p) | \ \ge MinPts&amp;lt;/math&amp;gt;, то: &lt;br /&gt;
#**она становится началом нового кластера или сохраняет номер кластера, который был ей присвоен ранее; &lt;br /&gt;
#**все точки из &amp;lt;math&amp;gt;N_\varepsilon(p)&amp;lt;/math&amp;gt; добавляются в её кластер;&lt;br /&gt;
#**процесс продолжается рекурсивно для каждой новой добавленной непосещенной точки &amp;lt;math&amp;gt;p&#039; \in N_\varepsilon(p)&amp;lt;/math&amp;gt; c шага 2 (в качестве новой &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).&lt;br /&gt;
#*Если точка &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; оказалась не ядровой, то &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; объявляется шумом. Алгоритм продолжается с шага 4.&lt;br /&gt;
#Если остались непосещенные точки, то алгоритм продолжается с шага 1.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром алгоритма является нахождение &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей каждой точки входного множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для решения этой задачи требуется найти расстояния между любыми двумя точками множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; по заданной метрике. Например, если используется расстояние Минковского порядка &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, то расстояние между точками &amp;lt;math&amp;gt;p=(p_1,...,p_n) \in X&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q=(q_1,...,q_n) \in X&amp;lt;/math&amp;gt; вычисляется как &amp;lt;math&amp;gt;D(p, q) = (\sum_{i = 1}^{n}|p_i - q_i|^k)^{1 / k}&amp;lt;/math&amp;gt;, частным случаем которой при &amp;lt;math&amp;gt;k = 2&amp;lt;/math&amp;gt; является широко распространённая евклидова метрика &amp;lt;math&amp;gt;D(p, q) = \sqrt{\sum_{i = 1}^{n} (p_i - q_i)^2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как записано и в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть метода составляют вызовы функции &amp;lt;math&amp;gt;request\_neighbours&amp;lt;/math&amp;gt; получения &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей и нахождение расстояний между точками множества &amp;lt;math&amp;gt;X&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;DBSCAN&amp;lt;/math&amp;gt; проходит через все точки множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; и определяет, являются ли они шумом или началом нового кластера. &lt;br /&gt;
В последнем случае новому кластеру присваивается уникальный номер и вызывается функция расширения кластера.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;DBSCAN(\varepsilon, MinPts)&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;C = 0&amp;lt;/math&amp;gt;&lt;br /&gt;
   for &amp;lt;math&amp;gt;\forall p \in X&amp;lt;/math&amp;gt;&lt;br /&gt;
      if &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; is visited then&lt;br /&gt;
         continue&lt;br /&gt;
      mark &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; as visited&lt;br /&gt;
      &amp;lt;math&amp;gt;neighbours&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;request\_neighbours(p, \varepsilon)&amp;lt;/math&amp;gt;&lt;br /&gt;
      if &amp;lt;math&amp;gt;| neighbours | &amp;lt; MinPts&amp;lt;/math&amp;gt; then&lt;br /&gt;
         mark &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; as &amp;lt;math&amp;gt;NOISE&amp;lt;/math&amp;gt;&lt;br /&gt;
      else&lt;br /&gt;
         &amp;lt;math&amp;gt;C = next\_cluster&amp;lt;/math&amp;gt;&lt;br /&gt;
         &amp;lt;math&amp;gt;expand\_cluster(p, neighbours, C, \varepsilon, MinPts)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;expand\_cluster&amp;lt;/math&amp;gt; рекурсивно проходит через все точки множества &amp;lt;math&amp;gt;neighbours&amp;lt;/math&amp;gt; - соседей точки &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, &lt;br /&gt;
и определяет, принадлежат ли эти точки тому же кластеру &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, тем самым расширяя этот кластер.&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;math&amp;gt;expand\_cluster(p, neighbours, C, \varepsilon, MinPts)&amp;lt;/math&amp;gt;&lt;br /&gt;
   add &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; to cluster &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;&lt;br /&gt;
   for &amp;lt;math&amp;gt;\forall p&#039; \in neighbours&amp;lt;/math&amp;gt;&lt;br /&gt;
      if &amp;lt;math&amp;gt;p&#039;&amp;lt;/math&amp;gt; is not visited &lt;br /&gt;
         mark &amp;lt;math&amp;gt;p&#039;&amp;lt;/math&amp;gt; as visited&lt;br /&gt;
         &amp;lt;math&amp;gt;neighbours&#039;&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;request\_neighbours(p, \varepsilon)&amp;lt;/math&amp;gt;&lt;br /&gt;
         if &amp;lt;math&amp;gt;| neighbours&#039; | \ \ge MinPts&amp;lt;/math&amp;gt;&lt;br /&gt;
            &amp;lt;math&amp;gt;neighbours&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;neighbours \cup neighbours&#039;&amp;lt;/math&amp;gt;  &lt;br /&gt;
      if &amp;lt;math&amp;gt;p&#039;&amp;lt;/math&amp;gt; is not yet member of any cluster&lt;br /&gt;
         add &amp;lt;math&amp;gt;p&#039;&amp;lt;/math&amp;gt; to cluster &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;request\_neighbours&amp;lt;/math&amp;gt; возвращает для точки &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; множество всех её &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей, &lt;br /&gt;
используя функцию расстояния &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;&lt;br /&gt;
 &amp;lt;math&amp;gt;request\_neighbours(p, \varepsilon)&amp;lt;/math&amp;gt;&lt;br /&gt;
    return &amp;lt;math&amp;gt;\{ p&#039; \ | \ \forall p&#039; \in X: D(p, p&#039;) &amp;lt; \varepsilon \}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
DBSCAN проходит через каждую точку входного множества, возможно, по несколько раз. Временная сложность зависит в большей степени от вызова функции &amp;lt;math&amp;gt;request\_neighbours&amp;lt;/math&amp;gt; (нахождение &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей для заданной точки). Эта функция вызывается ровно один раз для каждой точки множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если использовать индексированную структуру данных (например, R-деревья), выполняющую операцию &amp;lt;math&amp;gt;request\_neighbours&amp;lt;/math&amp;gt; за &amp;lt;math&amp;gt;O(\log n)&amp;lt;/math&amp;gt;, то суммарная сложность алгоритма в среднем составит &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt;, с учётом хорошо подобранного параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;, такого что в среднем &amp;lt;math&amp;gt;request\_neighbours&amp;lt;/math&amp;gt; возвращает &amp;lt;math&amp;gt;O(\log n)&amp;lt;/math&amp;gt; точек. Без использования ускоряющих структур или на вырожденных данных (таких, что все точки находятся на расстоянии меньшем, чем &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; друг от друга) сложность по времени в худшем случае будет &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Расстояния между точками можно вычислить заранее за &amp;lt;math&amp;gt;O(\frac {n(n - 1)}{2})&amp;lt;/math&amp;gt;, например в виде матрицы расстояний, но это потребует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; памяти. Иначе, расстояния будут вычисляться при каждом запуске функции &amp;lt;math&amp;gt;request\_neighbours&amp;lt;/math&amp;gt; за &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; и потребуют &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; памяти. Итоговая сложность вычисления расстояний в таком случае составляет &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;. Сложность рассчета расстояний зависит от природы объектов из &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; и заданной метрики &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;. Например, если &amp;lt;math&amp;gt;X\subset\mathbb{R}^m&amp;lt;/math&amp;gt;, то сложность равна &amp;lt;math&amp;gt;O(m)&amp;lt;/math&amp;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;
[[File:Dbscan abstract.png |thumb|right|320px| Рис. 2. Внешний цикл алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На рис. 2 изображен информационный граф внешнего цикла алгоритма, который соответствует коду основной функции &amp;lt;math&amp;gt;DBSCAN&amp;lt;/math&amp;gt;:&lt;br /&gt;
*Макрооперация &#039;&#039;Init&#039;&#039; заключается в получении множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; и инициирования вспомогательных структур. &lt;br /&gt;
*Макрооперация &#039;&#039;Choose&#039;&#039; производит выбор непосещенной точки из &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Макрооперация &#039;&#039;Build cluster&#039;&#039; строит кластер, если точка ядровая, или объявляет ее шумом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Переход от &#039;&#039;Build cluster&#039;&#039; к &#039;&#039;Choose&#039;&#039; заключает в себе зависимость данных о принадлежности некоторых точек к текущему кластеру или шуму и об их посещенности.&lt;br /&gt;
&lt;br /&gt;
[[File:Expand cluster 2.png |thumb|right|600px| Рис. 3. Расширение кластера.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На рис. 3 изображен информационный граф алгоритма расширения кластера из начальной точки кластера:&lt;br /&gt;
*Макрооперация &#039;&#039;Init&#039;&#039; заключается в создании кластера из его начальной вершины.&lt;br /&gt;
*Макрооперация &#039;&#039;Nε&#039;&#039; вычисляет множество &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей.&lt;br /&gt;
*Желтым цветом обозначены узлы, в которых точки из &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей классифицируются на ядровые, граничные точки и шум. В рамках операции для конкретного соседа вычисляется множество его &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей.&lt;br /&gt;
*Макрооперации &#039;&#039;Ñε&#039;&#039;, &#039;&#039;Ňε&#039;&#039;, ... производят объединение входных множеств.&lt;br /&gt;
*Макрооперация &#039;&#039;Ø&#039;&#039; выполняется тогда, когда объединение входных множеств является пустым.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:N eps 3.png         |thumb|right|320px| Рис. 4. Подсчет &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей.]]&lt;br /&gt;
&lt;br /&gt;
На рис. 4 изображен информационный граф алгоритма вычисления множества &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей:&lt;br /&gt;
*Операция &#039;&#039;D&#039;&#039; - вычисление расстояния между точками.&lt;br /&gt;
*Операция &#039;&#039;ε&#039;&#039; - сравнение расстояния с ε.&lt;br /&gt;
*Операция &#039;&#039;U&#039;&#039; - объединение результатов.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Поиск &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей требует вычисления &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; расстояний (функция &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;) и выполнения &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений с &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Эти операции для каждой пары точек независимы и могут быть выполнены параллельно. Таким образом, при наличии неограниченного числа процессоров сложность поиска составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;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;
Вход алгоритма: множество точек X из n-мерного пространства, на котором определена функция расстояния D. В наиболее распространенном случае пространственной кластеризации используется Евлидово расстояние между векторами из &amp;lt;math&amp;gt;\mathbb{R}^n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Выход алгоритма: размеченное множество точек &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;, в котором каждой точке соответствует номер ее кластера. Обычно каждой точке из &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; сопоставляется ее номер, а на выходе алгоритм дает отображение номеров точек в номера соответствующих им кластеров, например в виде вектора размера &amp;lt;math&amp;gt;|X|&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;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
=== Недостатки алгоритма ===&lt;br /&gt;
&lt;br /&gt;
# не детерминирован: граничные точки, достижимые из более, чем одного кластера, могут быть частью любого из них в зависимости от порядка обрабатываемых данных. Однако такая ситуация возникает редко, а относительно ядровых точек и шума DBSCAN детерминирован. Впрочем, от недетерминизма можно избавиться, если считать все граничные точки шумом (алгоритм DBSCAN*);&lt;br /&gt;
# качество алгоритма зависит от используемой функции расстояния &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;. Наиболее часто используемое Евклидово расстояние в многомерных множествах может оказаться практически бесполезным из-за так называемого &amp;quot;проклятия размерности&amp;quot;, значительно затрудняя нахождение подходящего значения &amp;lt;math&amp;gt;\varepsilon&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;
!!! ЭКСПЕРИМЕНТЫ ДО 15 НОЯБРЯ !!!&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
* [http://scikit-learn.org/stable/modules/generated/sklearn.cluster.DBSCAN.html Scikit learn (Python)]&lt;br /&gt;
* [https://cran.r-project.org/web/packages/dbscan/dbscan.pdf R-project] ([https://github.com/mhahsler/dbscan github])&lt;br /&gt;
* [https://www.mathworks.com/matlabcentral/fileexchange/52905-dbscan-clustering-algorithm Matlab]&lt;br /&gt;
* P-DBSCAN (Parallel DBSCAN)&amp;lt;ref&amp;gt;Chen, Min, Xuedong Gao, and HuiFei Li. &amp;quot;Parallel DBSCAN with priority r-tree.&amp;quot; Information Management and Engineering (ICIME), 2010 The 2nd IEEE International Conference on. IEEE, 2010.&amp;lt;/ref&amp;gt;&lt;br /&gt;
* Parallel DBSCAN with MPI&amp;lt;ref&amp;gt;Savvas, Ilias K., and Dimitrios Tselios. &amp;quot;Parallelizing DBSCaN Algorithm Using MPI.&amp;quot; Enabling Technologies: Infrastructure for Collaborative Enterprises (WETICE), 2016 IEEE 25th International Conference on. IEEE, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
* PDSDBSCAN (Parallel Disjoint-Set DBSCAN)&amp;lt;ref&amp;gt;Patwary, Md Mostofa Ali, et al. &amp;quot;A new scalable parallel DBSCAN algorithm using the disjoint-set data structure.&amp;quot; High Performance Computing, Networking, Storage and Analysis (SC), 2012 International Conference for. IEEE, 2012.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sleo</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:Dadrik/%D0%9F%D0%BB%D0%BE%D1%82%D0%BD%D0%BE%D1%81%D1%82%D0%BD%D1%8B%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8&amp;diff=16822</id>
		<title>Участник:Dadrik/Плотностный алгоритм кластеризации</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:Dadrik/%D0%9F%D0%BB%D0%BE%D1%82%D0%BD%D0%BE%D1%81%D1%82%D0%BD%D1%8B%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8&amp;diff=16822"/>
		<updated>2016-11-13T22:50:05Z</updated>

		<summary type="html">&lt;p&gt;Sleo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Плотностный алгоритм кластеризации DBSCAN&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Авторы описания: [[Участник:Dadrik | Вашуров И.М.]], [[Участник:ramon93i7 | Шемякин Р.О.]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Задача кластеризации - это задача разбиения заданной входной выборки объектов на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из схожих объектов, а объекты разных кластеров существенно отличались.&lt;br /&gt;
&lt;br /&gt;
Алгоритм DBSCAN (Density-based spatial clustering of applications with noise)&amp;lt;ref&amp;gt;Ester, Martin, et al. &amp;quot;A density-based algorithm for discovering clusters in large spatial databases with noise.&amp;quot; Kdd. Vol. 96. No. 34. 1996.&amp;lt;/ref&amp;gt; был предложен Мартином Эстер, Гансом-Питером Кригель и коллегами в 1996 году как решение задачи кластеризации с кластерами произвольной формы. DBSCAN является непараметрическим плотностным алгоритмом кластеризации: для заданного набора точек в некотором пространстве, алгоритм группирует те точки, которые расположены достаточно близко друг к другу (точки с большим количеством соседей), и помечает как выбросы те, что располагаются далеко от ближайших соседей.&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;X&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;-мерного пространства, на котором определена функция расстояния &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Выход алгоритма: размеченное множество точек &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;, в котором каждой точке соответствует номер ее кластера.&lt;br /&gt;
&lt;br /&gt;
Параметры алгоритма: &lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; - максимальное расстояние между соседями;&lt;br /&gt;
* &amp;lt;math&amp;gt;MinPts&amp;lt;/math&amp;gt; - минимальное количество соседей для создания области связности.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Определения ===&lt;br /&gt;
&lt;br /&gt;
[[File:Cluster_scheme.png|thumb|right|400px| Рис. 1. [https://upload.wikimedia.org/wikipedia/commons/a/af/DBSCAN-Illustration.svg] Здесь &#039;&#039;MinPts&#039;&#039; = 4. Точка &#039;&#039;A&#039;&#039; и другие красные точки - ядровые и образуют единый кластер, так как достижимы друг из друга. Точки &#039;&#039;B&#039;&#039; и &#039;&#039;C&#039;&#039; не являются ядровыми, но достижимы из &#039;&#039;A&#039;&#039;, а значит также принадлежат кластеру. Точка &#039;&#039;N&#039;&#039; - не достижима из других точек и является шумом.]]&lt;br /&gt;
&lt;br /&gt;
Все заданные точки классифицируются на три группы:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;ядровые точки&#039;&#039;: точка &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; является ядровой, если количество &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей, включая саму точку &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, не меньше &amp;lt;math&amp;gt;MinPts&amp;lt;/math&amp;gt;. Под &#039;&#039;&amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседями&#039;&#039; точки &amp;lt;math&amp;gt;p \in X&amp;lt;/math&amp;gt; понимается множество точек, расстояние до которых не превышает &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;N_\varepsilon(p) = \{ x \in X | D(p, x) \le \varepsilon \}&amp;lt;/math&amp;gt;. Эти точки являются напрямую достижимыми из &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;достижимые точки&#039;&#039;: точка &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; достижима из &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, если  существует путь &amp;lt;math&amp;gt;p_1, \dots, p_n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;p_1 = p&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_n = q&amp;lt;/math&amp;gt;, для которого выполнено: &lt;br /&gt;
:&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
p_{i + 1} \in N_\varepsilon(p_i),  i = 1, \dots, n-1 \\&lt;br /&gt;
| N_\varepsilon(p_{i}) | \ge MinPts, i = 1, \dots, n-1 \\&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;шум&#039;&#039; (выбросы): все точки, недостижимые из какой-либо другой точки считаются шумом (выбросом).&lt;br /&gt;
&lt;br /&gt;
Так, если &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - ядровая точка, то она образует кластер вместе со всеми точками, достижимыми из неё. Каждый кластер содержит по крайней мере одну ядровую точку; неядровые точки могут быть частью кластера, образуя при этом его &amp;quot;границу&amp;quot;, так как они не могут быть использованы для достижения других точек.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Достижимость не является симметричным отношением, так как по определению никакая точка не может быть достижима из неядровой точки, независимо от расстояния. Поэтому в DBSCAN применяется следующий термин &#039;&#039;связности&#039;&#039;: две точки &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; связанны, если существует такая точка &amp;lt;math&amp;gt;o&amp;lt;/math&amp;gt;, что &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; достижимы из &amp;lt;math&amp;gt;o&amp;lt;/math&amp;gt;. Такое отношение связности симметрично.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Кластер&#039;&#039; в таком случае определяется двумя свойствами:&lt;br /&gt;
* Все точки внутри кластера взаимно связанны;&lt;br /&gt;
* Если точка достижима из любой точки кластера, она также является частью кластера.&lt;br /&gt;
&lt;br /&gt;
=== Шаги алгоритма ===&lt;br /&gt;
&lt;br /&gt;
#Выбирается произвольная непосещенная точка &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;.&lt;br /&gt;
#Точка &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; помечается как посещенная. &lt;br /&gt;
#У точки &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; определяется множество её &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей - &amp;lt;math&amp;gt;N_\varepsilon(p)&amp;lt;/math&amp;gt;.&lt;br /&gt;
#*Если точка &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; оказалась ядровой - &amp;lt;math&amp;gt;| N_\varepsilon(p) | \ \ge MinPts&amp;lt;/math&amp;gt;, то: &lt;br /&gt;
#**она становится началом нового кластера или сохраняет номер кластера, который был ей присвоен ранее; &lt;br /&gt;
#**все точки из &amp;lt;math&amp;gt;N_\varepsilon(p)&amp;lt;/math&amp;gt; добавляются в её кластер;&lt;br /&gt;
#**процесс продолжается рекурсивно для каждой новой добавленной непосещенной точки &amp;lt;math&amp;gt;p&#039; \in N_\varepsilon(p)&amp;lt;/math&amp;gt; c шага 2 (в качестве новой &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).&lt;br /&gt;
#*Если точка &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; оказалась не ядровой, то &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; объявляется шумом. Алгоритм продолжается с шага 4.&lt;br /&gt;
#Если остались непосещенные точки, то алгоритм продолжается с шага 1.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром алгоритма является нахождение &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей каждой точки входного множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для решения этой задачи требуется найти расстояния между любыми двумя точками множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; по заданной метрике. Например, если используется расстояние Минковского порядка &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, то расстояние между точками &amp;lt;math&amp;gt;p=(p_1,...,p_n) \in X&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q=(q_1,...,q_n) \in X&amp;lt;/math&amp;gt; вычисляется как &amp;lt;math&amp;gt;D(p, q) = (\sum_{i = 1}^{n}|p_i - q_i|^k)^{1 / k}&amp;lt;/math&amp;gt;, частным случаем которой при &amp;lt;math&amp;gt;k = 2&amp;lt;/math&amp;gt; является широко распространённая евклидова метрика &amp;lt;math&amp;gt;D(p, q) = \sqrt{\sum_{i = 1}^{n} (p_i - q_i)^2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как записано и в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть метода составляют вызовы функции &amp;lt;math&amp;gt;request\_neighbours&amp;lt;/math&amp;gt; получения &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей и нахождение расстояний между точками множества &amp;lt;math&amp;gt;X&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;DBSCAN&amp;lt;/math&amp;gt; проходит через все точки множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; и определяет, являются ли они шумом или началом нового кластера. &lt;br /&gt;
В последнем случае новому кластеру присваивается уникальный номер и вызывается функция расширения кластера.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;DBSCAN(\varepsilon, MinPts)&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;C = 0&amp;lt;/math&amp;gt;&lt;br /&gt;
   for &amp;lt;math&amp;gt;\forall p \in X&amp;lt;/math&amp;gt;&lt;br /&gt;
      if &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; is visited then&lt;br /&gt;
         continue&lt;br /&gt;
      mark &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; as visited&lt;br /&gt;
      &amp;lt;math&amp;gt;neighbours&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;request\_neighbours(p, \varepsilon)&amp;lt;/math&amp;gt;&lt;br /&gt;
      if &amp;lt;math&amp;gt;| neighbours | &amp;lt; MinPts&amp;lt;/math&amp;gt; then&lt;br /&gt;
         mark &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; as &amp;lt;math&amp;gt;NOISE&amp;lt;/math&amp;gt;&lt;br /&gt;
      else&lt;br /&gt;
         &amp;lt;math&amp;gt;C = next\_cluster&amp;lt;/math&amp;gt;&lt;br /&gt;
         &amp;lt;math&amp;gt;expand\_cluster(p, neighbours, C, \varepsilon, MinPts)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;expand\_cluster&amp;lt;/math&amp;gt; рекурсивно проходит через все точки множества &amp;lt;math&amp;gt;neighbours&amp;lt;/math&amp;gt; - соседей точки &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, &lt;br /&gt;
и определяет, принадлежат ли эти точки тому же кластеру &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, тем самым расширяя этот кластер.&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;math&amp;gt;expand\_cluster(p, neighbours, C, \varepsilon, MinPts)&amp;lt;/math&amp;gt;&lt;br /&gt;
   add &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; to cluster &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;&lt;br /&gt;
   for &amp;lt;math&amp;gt;\forall p&#039; \in neighbours&amp;lt;/math&amp;gt;&lt;br /&gt;
      if &amp;lt;math&amp;gt;p&#039;&amp;lt;/math&amp;gt; is not visited &lt;br /&gt;
         mark &amp;lt;math&amp;gt;p&#039;&amp;lt;/math&amp;gt; as visited&lt;br /&gt;
         &amp;lt;math&amp;gt;neighbours&#039;&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;request\_neighbours(p, \varepsilon)&amp;lt;/math&amp;gt;&lt;br /&gt;
         if &amp;lt;math&amp;gt;| neighbours&#039; | \ \ge MinPts&amp;lt;/math&amp;gt;&lt;br /&gt;
            &amp;lt;math&amp;gt;neighbours&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;neighbours \cup neighbours&#039;&amp;lt;/math&amp;gt;  &lt;br /&gt;
      if &amp;lt;math&amp;gt;p&#039;&amp;lt;/math&amp;gt; is not yet member of any cluster&lt;br /&gt;
         add &amp;lt;math&amp;gt;p&#039;&amp;lt;/math&amp;gt; to cluster &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;request\_neighbours&amp;lt;/math&amp;gt; возвращает для точки &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; множество всех её &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей, &lt;br /&gt;
используя функцию расстояния &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;&lt;br /&gt;
 &amp;lt;math&amp;gt;request\_neighbours(p, \varepsilon)&amp;lt;/math&amp;gt;&lt;br /&gt;
    return &amp;lt;math&amp;gt;\{ p&#039; \ | \ \forall p&#039; \in X: D(p, p&#039;) &amp;lt; \varepsilon \}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
DBSCAN проходит через каждую точку входного множества, возможно, по несколько раз. Временная сложность зависит в большей степени от вызова функции &amp;lt;math&amp;gt;request\_neighbours&amp;lt;/math&amp;gt; (нахождение &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей для заданной точки). Эта функция вызывается ровно один раз для каждой точки множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если использовать индексированную структуру данных (например, R-деревья), выполняющую операцию &amp;lt;math&amp;gt;request\_neighbours&amp;lt;/math&amp;gt; за &amp;lt;math&amp;gt;O(\log n)&amp;lt;/math&amp;gt;, то суммарная сложность алгоритма в среднем составит &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt;, с учётом хорошо подобранного параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;, такого что в среднем &amp;lt;math&amp;gt;request\_neighbours&amp;lt;/math&amp;gt; возвращает &amp;lt;math&amp;gt;O(\log n)&amp;lt;/math&amp;gt; точек. Без использования ускоряющих структур или на вырожденных данных (таких, что все точки находятся на расстоянии меньшем, чем &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; друг от друга) сложность по времени в худшем случае будет &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Расстояния между точками можно вычислить заранее за &amp;lt;math&amp;gt;O(\frac {n(n - 1)}{2})&amp;lt;/math&amp;gt;, например в виде матрицы расстояний, но это потребует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; памяти. Иначе, расстояния будут вычисляться при каждом запуске функции &amp;lt;math&amp;gt;request\_neighbours&amp;lt;/math&amp;gt; за &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; и потребуют &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; памяти. Итоговая сложность вычисления расстояний в таком случае составляет &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;. Сложность рассчета расстояний зависит от природы объектов из &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; и заданной метрики &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;. Например, если &amp;lt;math&amp;gt;X\subset\mathbb{R}^m&amp;lt;/math&amp;gt;, то сложность равна &amp;lt;math&amp;gt;O(m)&amp;lt;/math&amp;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;
[[File:Dbscan abstract.png |thumb|right|320px| Рис. 2. Внешний цикл алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На рис. 2 изображен информационный граф внешнего цикла алгоритма, который соответствует коду основной функции &amp;lt;math&amp;gt;DBSCAN&amp;lt;/math&amp;gt;:&lt;br /&gt;
*Макрооперация &#039;&#039;Init&#039;&#039; заключается в получении множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; и инициирования вспомогательных структур. &lt;br /&gt;
*Макрооперация &#039;&#039;Choose&#039;&#039; производит выбор непосещенной точки из &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Макрооперация &#039;&#039;Build cluster&#039;&#039; строит кластер, если точка ядровая, или объявляет ее шумом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Переход от &#039;&#039;Build cluster&#039;&#039; к &#039;&#039;Choose&#039;&#039; заключает в себе зависимость данных о принадлежности некоторых точек к текущему кластеру или шуму и об их посещенности.&lt;br /&gt;
&lt;br /&gt;
[[File:Expand cluster 2.png |thumb|right|600px| Рис. 3. Расширение кластера.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На рис. 3 изображен информационный граф алгоритма расширения кластера из начальной точки кластера:&lt;br /&gt;
*Макрооперация &#039;&#039;Init&#039;&#039; заключается в создании кластера из его начальной вершины.&lt;br /&gt;
*Макрооперация &#039;&#039;Nε&#039;&#039; вычисляет множество &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей.&lt;br /&gt;
*Желтым цветом обозначены узлы, в которых точки из &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей классифицируются на ядровые, граничные точки и шум. В рамках операции для конкретного соседа вычисляется множество его &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей.&lt;br /&gt;
*Макрооперации &#039;&#039;Ñε&#039;&#039;, &#039;&#039;Ňε&#039;&#039;, ... производят объединение входных множеств.&lt;br /&gt;
*Макрооперация &#039;&#039;Ø&#039;&#039; выполняется тогда, когда объединение входных множеств является пустым.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:N eps 3.png         |thumb|right|320px| Рис. 4. Подсчет &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей.]]&lt;br /&gt;
&lt;br /&gt;
На рис. 4 изображен информационный граф алгоритма вычисления множества &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей:&lt;br /&gt;
*Операция &#039;&#039;D&#039;&#039; - вычисление расстояния между точками.&lt;br /&gt;
*Операция &#039;&#039;ε&#039;&#039; - сравнение расстояния с ε.&lt;br /&gt;
*Операция &#039;&#039;U&#039;&#039; - объединение результатов.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Поиск &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей требует вычисления &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; расстояний (функция &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;) и выполнения &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений с &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Эти операции для каждой пары точек независимы и могут быть выполнены параллельно. Таким образом, при наличии неограниченного числа процессоров сложность поиска составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;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;
Вход алгоритма: множество точек X из n-мерного пространства, на котором определена функция расстояния D. В наиболее распространенном случае пространственной кластеризации используется Евлидово расстояние между векторами из &amp;lt;math&amp;gt;\mathbb{R}^n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Выход алгоритма: размеченное множество точек &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;, в котором каждой точке соответствует номер ее кластера. Обычно каждой точке из &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; сопоставляется ее номер, а на выходе алгоритм дает отображение номеров точек в номера соответствующих им кластеров, например в виде вектора размера &amp;lt;math&amp;gt;|X|&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;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
=== Недостатки алгоритма ===&lt;br /&gt;
&lt;br /&gt;
# не детерминирован: граничные точки, достижимые из более, чем одного кластера, могут быть частью любого из них в зависимости от порядка обрабатываемых данных. Однако такая ситуация возникает редко, а относительно ядровых точек и шума DBSCAN детерминирован. Впрочем, от недетерминизма можно избавиться, если считать все граничные точки шумом (алгоритм DBSCAN*);&lt;br /&gt;
# качество алгоритма зависит от используемой функции расстояния &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;. Наиболее часто используемое Евклидово расстояние в многомерных множествах может оказаться практически бесполезным из-за так называемого &amp;quot;проклятия размерности&amp;quot;, значительно затрудняя нахождение подходящего значения &amp;lt;math&amp;gt;\varepsilon&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;
!!! ЭКСПЕРИМЕНТЫ ДО 15 НОЯБРЯ !!!&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
* [http://scikit-learn.org/stable/modules/generated/sklearn.cluster.DBSCAN.html Scikit learn (Python)]&lt;br /&gt;
* [https://cran.r-project.org/web/packages/dbscan/dbscan.pdf R-project] ([https://github.com/mhahsler/dbscan github])&lt;br /&gt;
* [https://www.mathworks.com/matlabcentral/fileexchange/52905-dbscan-clustering-algorithm Matlab]&lt;br /&gt;
* P-DBSCAN (Parallel DBSCAN)&amp;lt;ref&amp;gt;Chen, Min, Xuedong Gao, and HuiFei Li. &amp;quot;Parallel DBSCAN with priority r-tree.&amp;quot; Information Management and Engineering (ICIME), 2010 The 2nd IEEE International Conference on. IEEE, 2010.&amp;lt;/ref&amp;gt;&lt;br /&gt;
* Parallel DBSCAN with MPI&amp;lt;ref&amp;gt;Savvas, Ilias K., and Dimitrios Tselios. &amp;quot;Parallelizing DBSCaN Algorithm Using MPI.&amp;quot; Enabling Technologies: Infrastructure for Collaborative Enterprises (WETICE), 2016 IEEE 25th International Conference on. IEEE, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
* PDSDBSCAN (Parallel Disjoint-Set DBSCAN)&amp;lt;ref&amp;gt;Patwary, Md Mostofa Ali, et al. &amp;quot;A new scalable parallel DBSCAN algorithm using the disjoint-set data structure.&amp;quot; High Performance Computing, Networking, Storage and Analysis (SC), 2012 International Conference for. IEEE, 2012.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sleo</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:Dadrik/%D0%9F%D0%BB%D0%BE%D1%82%D0%BD%D0%BE%D1%81%D1%82%D0%BD%D1%8B%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8&amp;diff=16821</id>
		<title>Участник:Dadrik/Плотностный алгоритм кластеризации</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:Dadrik/%D0%9F%D0%BB%D0%BE%D1%82%D0%BD%D0%BE%D1%81%D1%82%D0%BD%D1%8B%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8&amp;diff=16821"/>
		<updated>2016-11-13T22:48:41Z</updated>

		<summary type="html">&lt;p&gt;Sleo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Sleo}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Плотностный алгоритм кластеризации DBSCAN&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Авторы описания: [[Участник:Dadrik | Вашуров И.М.]], [[Участник:ramon93i7 | Шемякин Р.О.]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Задача кластеризации - это задача разбиения заданной входной выборки объектов на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из схожих объектов, а объекты разных кластеров существенно отличались.&lt;br /&gt;
&lt;br /&gt;
Алгоритм DBSCAN (Density-based spatial clustering of applications with noise)&amp;lt;ref&amp;gt;Ester, Martin, et al. &amp;quot;A density-based algorithm for discovering clusters in large spatial databases with noise.&amp;quot; Kdd. Vol. 96. No. 34. 1996.&amp;lt;/ref&amp;gt; был предложен Мартином Эстер, Гансом-Питером Кригель и коллегами в 1996 году как решение задачи кластеризации с кластерами произвольной формы. DBSCAN является непараметрическим плотностным алгоритмом кластеризации: для заданного набора точек в некотором пространстве, алгоритм группирует те точки, которые расположены достаточно близко друг к другу (точки с большим количеством соседей), и помечает как выбросы те, что располагаются далеко от ближайших соседей.&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;X&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;-мерного пространства, на котором определена функция расстояния &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Выход алгоритма: размеченное множество точек &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;, в котором каждой точке соответствует номер ее кластера.&lt;br /&gt;
&lt;br /&gt;
Параметры алгоритма: &lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; - максимальное расстояние между соседями;&lt;br /&gt;
* &amp;lt;math&amp;gt;MinPts&amp;lt;/math&amp;gt; - минимальное количество соседей для создания области связности.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Определения ===&lt;br /&gt;
&lt;br /&gt;
[[File:Cluster_scheme.png|thumb|right|400px| Рис. 1. [https://upload.wikimedia.org/wikipedia/commons/a/af/DBSCAN-Illustration.svg] Здесь &#039;&#039;MinPts&#039;&#039; = 4. Точка &#039;&#039;A&#039;&#039; и другие красные точки - ядровые и образуют единый кластер, так как достижимы друг из друга. Точки &#039;&#039;B&#039;&#039; и &#039;&#039;C&#039;&#039; не являются ядровыми, но достижимы из &#039;&#039;A&#039;&#039;, а значит также принадлежат кластеру. Точка &#039;&#039;N&#039;&#039; - не достижима из других точек и является шумом.]]&lt;br /&gt;
&lt;br /&gt;
Все заданные точки классифицируются на три группы:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;ядровые точки&#039;&#039;: точка &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; является ядровой, если количество &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей, включая саму точку &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, не меньше &amp;lt;math&amp;gt;MinPts&amp;lt;/math&amp;gt;. Под &#039;&#039;&amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседями&#039;&#039; точки &amp;lt;math&amp;gt;p \in X&amp;lt;/math&amp;gt; понимается множество точек, расстояние до которых не превышает &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;N_\varepsilon(p) = \{ x \in X | D(p, x) \le \varepsilon \}&amp;lt;/math&amp;gt;. Эти точки являются напрямую достижимыми из &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;достижимые точки&#039;&#039;: точка &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; достижима из &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, если  существует путь &amp;lt;math&amp;gt;p_1, \dots, p_n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;p_1 = p&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_n = q&amp;lt;/math&amp;gt;, для которого выполнено: &lt;br /&gt;
:&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
p_{i + 1} \in N_\varepsilon(p_i),  i = 1, \dots, n-1 \\&lt;br /&gt;
| N_\varepsilon(p_{i}) | \ge MinPts, i = 1, \dots, n-1 \\&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;шум&#039;&#039; (выбросы): все точки, недостижимые из какой-либо другой точки считаются шумом (выбросом).&lt;br /&gt;
&lt;br /&gt;
Так, если &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - ядровая точка, то она образует кластер вместе со всеми точками, достижимыми из неё. Каждый кластер содержит по крайней мере одну ядровую точку; неядровые точки могут быть частью кластера, образуя при этом его &amp;quot;границу&amp;quot;, так как они не могут быть использованы для достижения других точек.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Достижимость не является симметричным отношением, так как по определению никакая точка не может быть достижима из неядровой точки, независимо от расстояния. Поэтому в DBSCAN применяется следующий термин &#039;&#039;связности&#039;&#039;: две точки &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; связанны, если существует такая точка &amp;lt;math&amp;gt;o&amp;lt;/math&amp;gt;, что &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; достижимы из &amp;lt;math&amp;gt;o&amp;lt;/math&amp;gt;. Такое отношение связности симметрично.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Кластер&#039;&#039; в таком случае определяется двумя свойствами:&lt;br /&gt;
* Все точки внутри кластера взаимно связанны;&lt;br /&gt;
* Если точка достижима из любой точки кластера, она также является частью кластера.&lt;br /&gt;
&lt;br /&gt;
=== Шаги алгоритма ===&lt;br /&gt;
&lt;br /&gt;
#Выбирается произвольная непосещенная точка &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;.&lt;br /&gt;
#Точка &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; помечается как посещенная. &lt;br /&gt;
#У точки &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; определяется множество её &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей - &amp;lt;math&amp;gt;N_\varepsilon(p)&amp;lt;/math&amp;gt;.&lt;br /&gt;
#*Если точка &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; оказалась ядровой - &amp;lt;math&amp;gt;| N_\varepsilon(p) | \ \ge MinPts&amp;lt;/math&amp;gt;, то: &lt;br /&gt;
#**она становится началом нового кластера или сохраняет номер кластера, который был ей присвоен ранее; &lt;br /&gt;
#**все точки из &amp;lt;math&amp;gt;N_\varepsilon(p)&amp;lt;/math&amp;gt; добавляются в её кластер;&lt;br /&gt;
#**процесс продолжается рекурсивно для каждой новой добавленной непосещенной точки &amp;lt;math&amp;gt;p&#039; \in N_\varepsilon(p)&amp;lt;/math&amp;gt; c шага 2 (в качестве новой &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).&lt;br /&gt;
#*Если точка &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; оказалась не ядровой, то &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; объявляется шумом. Алгоритм продолжается с шага 4.&lt;br /&gt;
#Если остались непосещенные точки, то алгоритм продолжается с шага 1.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром алгоритма является нахождение &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей каждой точки входного множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для решения этой задачи требуется найти расстояния между любыми двумя точками множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; по заданной метрике. Например, если используется расстояние Минковского порядка &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, то расстояние между точками &amp;lt;math&amp;gt;p=(p_1,...,p_n) \in X&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q=(q_1,...,q_n) \in X&amp;lt;/math&amp;gt; вычисляется как &amp;lt;math&amp;gt;D(p, q) = (\sum_{i = 1}^{n}|p_i - q_i|^k)^{1 / k}&amp;lt;/math&amp;gt;, частным случаем которой при &amp;lt;math&amp;gt;k = 2&amp;lt;/math&amp;gt; является широко распространённая евклидова метрика &amp;lt;math&amp;gt;D(p, q) = \sqrt{\sum_{i = 1}^{n} (p_i - q_i)^2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как записано и в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть метода составляют вызовы функции &amp;lt;math&amp;gt;request\_neighbours&amp;lt;/math&amp;gt; получения &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей и нахождение расстояний между точками множества &amp;lt;math&amp;gt;X&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;DBSCAN&amp;lt;/math&amp;gt; проходит через все точки множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; и определяет, являются ли они шумом или началом нового кластера. &lt;br /&gt;
В последнем случае новому кластеру присваивается уникальный номер и вызывается функция расширения кластера.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;DBSCAN(\varepsilon, MinPts)&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;C = 0&amp;lt;/math&amp;gt;&lt;br /&gt;
   for &amp;lt;math&amp;gt;\forall p \in X&amp;lt;/math&amp;gt;&lt;br /&gt;
      if &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; is visited then&lt;br /&gt;
         continue&lt;br /&gt;
      mark &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; as visited&lt;br /&gt;
      &amp;lt;math&amp;gt;neighbours&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;request\_neighbours(p, \varepsilon)&amp;lt;/math&amp;gt;&lt;br /&gt;
      if &amp;lt;math&amp;gt;| neighbours | &amp;lt; MinPts&amp;lt;/math&amp;gt; then&lt;br /&gt;
         mark &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; as &amp;lt;math&amp;gt;NOISE&amp;lt;/math&amp;gt;&lt;br /&gt;
      else&lt;br /&gt;
         &amp;lt;math&amp;gt;C = next\_cluster&amp;lt;/math&amp;gt;&lt;br /&gt;
         &amp;lt;math&amp;gt;expand\_cluster(p, neighbours, C, \varepsilon, MinPts)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;expand\_cluster&amp;lt;/math&amp;gt; рекурсивно проходит через все точки множества &amp;lt;math&amp;gt;neighbours&amp;lt;/math&amp;gt; - соседей точки &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, &lt;br /&gt;
и определяет, принадлежат ли эти точки тому же кластеру &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, тем самым расширяя этот кластер.&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;math&amp;gt;expand\_cluster(p, neighbours, C, \varepsilon, MinPts)&amp;lt;/math&amp;gt;&lt;br /&gt;
   add &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; to cluster &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;&lt;br /&gt;
   for &amp;lt;math&amp;gt;\forall p&#039; \in neighbours&amp;lt;/math&amp;gt;&lt;br /&gt;
      if &amp;lt;math&amp;gt;p&#039;&amp;lt;/math&amp;gt; is not visited &lt;br /&gt;
         mark &amp;lt;math&amp;gt;p&#039;&amp;lt;/math&amp;gt; as visited&lt;br /&gt;
         &amp;lt;math&amp;gt;neighbours&#039;&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;request\_neighbours(p, \varepsilon)&amp;lt;/math&amp;gt;&lt;br /&gt;
         if &amp;lt;math&amp;gt;| neighbours&#039; | \ \ge MinPts&amp;lt;/math&amp;gt;&lt;br /&gt;
            &amp;lt;math&amp;gt;neighbours&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;neighbours \cup neighbours&#039;&amp;lt;/math&amp;gt;  &lt;br /&gt;
      if &amp;lt;math&amp;gt;p&#039;&amp;lt;/math&amp;gt; is not yet member of any cluster&lt;br /&gt;
         add &amp;lt;math&amp;gt;p&#039;&amp;lt;/math&amp;gt; to cluster &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;request\_neighbours&amp;lt;/math&amp;gt; возвращает для точки &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; множество всех её &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей, &lt;br /&gt;
используя функцию расстояния &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;&lt;br /&gt;
 &amp;lt;math&amp;gt;request\_neighbours(p, \varepsilon)&amp;lt;/math&amp;gt;&lt;br /&gt;
    return &amp;lt;math&amp;gt;\{ p&#039; \ | \ \forall p&#039; \in X: D(p, p&#039;) &amp;lt; \varepsilon \}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
DBSCAN проходит через каждую точку входного множества, возможно, по несколько раз. Временная сложность зависит в большей степени от вызова функции &amp;lt;math&amp;gt;request\_neighbours&amp;lt;/math&amp;gt; (нахождение &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей для заданной точки). Эта функция вызывается ровно один раз для каждой точки множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если использовать индексированную структуру данных (например, R-деревья), выполняющую операцию &amp;lt;math&amp;gt;request\_neighbours&amp;lt;/math&amp;gt; за &amp;lt;math&amp;gt;O(\log n)&amp;lt;/math&amp;gt;, то суммарная сложность алгоритма в среднем составит &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt;, с учётом хорошо подобранного параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;, такого что в среднем &amp;lt;math&amp;gt;request\_neighbours&amp;lt;/math&amp;gt; возвращает &amp;lt;math&amp;gt;O(\log n)&amp;lt;/math&amp;gt; точек. Без использования ускоряющих структур или на вырожденных данных (таких, что все точки находятся на расстоянии меньшем, чем &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; друг от друга) сложность по времени в худшем случае будет &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Расстояния между точками можно вычислить заранее за &amp;lt;math&amp;gt;O(\frac {n(n - 1)}{2})&amp;lt;/math&amp;gt;, например в виде матрицы расстояний, но это потребует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; памяти. Иначе, расстояния будут вычисляться при каждом запуске функции &amp;lt;math&amp;gt;request\_neighbours&amp;lt;/math&amp;gt; за &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; и потребуют &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; памяти. Итоговая сложность вычисления расстояний в таком случае составляет &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;. Сложность рассчета расстояний зависит от природы объектов из &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; и заданной метрики &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;. Например, если &amp;lt;math&amp;gt;X\subset\mathbb{R}^m&amp;lt;/math&amp;gt;, то сложность равна &amp;lt;math&amp;gt;O(m)&amp;lt;/math&amp;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;
[[File:Dbscan abstract.png |thumb|right|320px| Рис. 2. Внешний цикл алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На рис. 2 изображен информационный граф внешнего цикла алгоритма, который соответствует коду основной функции &amp;lt;math&amp;gt;DBSCAN&amp;lt;/math&amp;gt;:&lt;br /&gt;
*Макрооперация &#039;&#039;Init&#039;&#039; заключается в получении множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; и инициирования вспомогательных структур. &lt;br /&gt;
*Макрооперация &#039;&#039;Choose&#039;&#039; производит выбор непосещенной точки из &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Макрооперация &#039;&#039;Build cluster&#039;&#039; строит кластер, если точка ядровая, или объявляет ее шумом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Переход от &#039;&#039;Build cluster&#039;&#039; к &#039;&#039;Choose&#039;&#039; заключает в себе зависимость данных о принадлежности некоторых точек к текущему кластеру или шуму и об их посещенности.&lt;br /&gt;
&lt;br /&gt;
[[File:Expand cluster 2.png |thumb|right|600px| Рис. 3. Расширение кластера.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На рис. 3 изображен информационный граф алгоритма расширения кластера из начальной точки кластера:&lt;br /&gt;
*Макрооперация &#039;&#039;Init&#039;&#039; заключается в создании кластера из его начальной вершины.&lt;br /&gt;
*Макрооперация &#039;&#039;Nε&#039;&#039; вычисляет множество &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей.&lt;br /&gt;
*Желтым цветом обозначены узлы, в которых точки из &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей классифицируются на ядровые, граничные точки и шум. В рамках операции для конкретного соседа вычисляется множество его &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей.&lt;br /&gt;
*Макрооперации &#039;&#039;Ñε&#039;&#039;, &#039;&#039;Ňε&#039;&#039;, ... производят объединение входных множеств.&lt;br /&gt;
*Макрооперация &#039;&#039;Ø&#039;&#039; выполняется тогда, когда объединение входных множеств является пустым.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:N eps 3.png         |thumb|right|320px| Рис. 4. Подсчет &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей.]]&lt;br /&gt;
&lt;br /&gt;
На рис. 4 изображен информационный граф алгоритма вычисления множества &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей:&lt;br /&gt;
*Операция &#039;&#039;D&#039;&#039; - вычисление расстояния между точками.&lt;br /&gt;
*Операция &#039;&#039;ε&#039;&#039; - сравнение расстояния с ε.&lt;br /&gt;
*Операция &#039;&#039;U&#039;&#039; - объединение результатов.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Поиск &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей требует вычисления &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; расстояний (функция &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;) и выполнения &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений с &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Эти операции для каждой пары точек независимы и могут быть выполнены параллельно. Таким образом, при наличии неограниченного числа процессоров сложность поиска составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;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;
Вход алгоритма: множество точек X из n-мерного пространства, на котором определена функция расстояния D. В наиболее распространенном случае пространственной кластеризации используется Евлидово расстояние между векторами из &amp;lt;math&amp;gt;\mathbb{R}^n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Выход алгоритма: размеченное множество точек &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;, в котором каждой точке соответствует номер ее кластера. Обычно каждой точке из &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; сопоставляется ее номер, а на выходе алгоритм дает отображение номеров точек в номера соответствующих им кластеров, например в виде вектора размера &amp;lt;math&amp;gt;|X|&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;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
=== Недостатки алгоритма ===&lt;br /&gt;
&lt;br /&gt;
# не детерминирован: граничные точки, достижимые из более, чем одного кластера, могут быть частью любого из них в зависимости от порядка обрабатываемых данных. Однако такая ситуация возникает редко, а относительно ядровых точек и шума DBSCAN детерминирован. Впрочем, от недетерминизма можно избавиться, если считать все граничные точки шумом (алгоритм DBSCAN*);&lt;br /&gt;
# качество алгоритма зависит от используемой функции расстояния &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;. Наиболее часто используемое Евклидово расстояние в многомерных множествах может оказаться практически бесполезным из-за так называемого &amp;quot;проклятия размерности&amp;quot;, значительно затрудняя нахождение подходящего значения &amp;lt;math&amp;gt;\varepsilon&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;
!!! ЭКСПЕРИМЕНТЫ ДО 15 НОЯБРЯ !!!&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
* [http://scikit-learn.org/stable/modules/generated/sklearn.cluster.DBSCAN.html Scikit learn (Python)]&lt;br /&gt;
* [https://cran.r-project.org/web/packages/dbscan/dbscan.pdf R-project] ([https://github.com/mhahsler/dbscan github])&lt;br /&gt;
* [https://www.mathworks.com/matlabcentral/fileexchange/52905-dbscan-clustering-algorithm Matlab]&lt;br /&gt;
* P-DBSCAN (Parallel DBSCAN)&amp;lt;ref&amp;gt;Chen, Min, Xuedong Gao, and HuiFei Li. &amp;quot;Parallel DBSCAN with priority r-tree.&amp;quot; Information Management and Engineering (ICIME), 2010 The 2nd IEEE International Conference on. IEEE, 2010.&amp;lt;/ref&amp;gt;&lt;br /&gt;
* Parallel DBSCAN with MPI&amp;lt;ref&amp;gt;Savvas, Ilias K., and Dimitrios Tselios. &amp;quot;Parallelizing DBSCaN Algorithm Using MPI.&amp;quot; Enabling Technologies: Infrastructure for Collaborative Enterprises (WETICE), 2016 IEEE 25th International Conference on. IEEE, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
* PDSDBSCAN (Parallel Disjoint-Set DBSCAN)&amp;lt;ref&amp;gt;Patwary, Md Mostofa Ali, et al. &amp;quot;A new scalable parallel DBSCAN algorithm using the disjoint-set data structure.&amp;quot; High Performance Computing, Networking, Storage and Analysis (SC), 2012 International Conference for. IEEE, 2012.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sleo</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:Maria_rojas&amp;diff=14297</id>
		<title>Обсуждение участницы:Maria rojas</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:Maria_rojas&amp;diff=14297"/>
		<updated>2016-10-27T22:41:58Z</updated>

		<summary type="html">&lt;p&gt;Sleo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Замечание к оформлению статьи:&lt;br /&gt;
&lt;br /&gt;
1. Почему написано &amp;quot;авторы&amp;quot;, вы писали работы не одна? Если да, то укажите пару.&lt;br /&gt;
&lt;br /&gt;
2. Почему вторая часть не соответствует структуре примера? Указанные вами два заголовка имеют номера 2.4 и 2.7, а не 2.1 2.2. Восстановите требуемую структуру. &lt;br /&gt;
&lt;br /&gt;
3. Проверьте русский язык :) &amp;quot;При этом вычислительная мощность алгоритма, равная &#039;&#039;&#039;отношение&#039;&#039;&#039; числа операций к суммарному объему входных и выходных данных – O(\sqrt{n}).&amp;quot; И согласование слов.&lt;/div&gt;</summary>
		<author><name>Sleo</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:Maria_rojas&amp;diff=14296</id>
		<title>Обсуждение участницы:Maria rojas</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:Maria_rojas&amp;diff=14296"/>
		<updated>2016-10-27T22:41:23Z</updated>

		<summary type="html">&lt;p&gt;Sleo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Замечание к оформлению статьи:&lt;br /&gt;
&lt;br /&gt;
1. Почему написано &amp;quot;авторы&amp;quot;, вы писали работы не одна? Если да, то укажите пару.&lt;br /&gt;
&lt;br /&gt;
2. Почему часть не соответствует структуре примера? Указанные вами два заголовка имеют номера 2.4 и 2.7, а не 2.1 2.2. Восстановите требуемую структуру. &lt;br /&gt;
&lt;br /&gt;
3. Проверьте русский язык :) &amp;quot;При этом вычислительная мощность алгоритма, равная &#039;&#039;&#039;отношение&#039;&#039;&#039; числа операций к суммарному объему входных и выходных данных – O(\sqrt{n}).&amp;quot; И согласование слов.&lt;/div&gt;</summary>
		<author><name>Sleo</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:Maria_rojas&amp;diff=14295</id>
		<title>Обсуждение участницы:Maria rojas</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:Maria_rojas&amp;diff=14295"/>
		<updated>2016-10-27T22:40:26Z</updated>

		<summary type="html">&lt;p&gt;Sleo: Новая страница: «Замечание к оформлению статьи:  1. Почему написано &amp;quot;авторы&amp;quot;, вы писали работы не одна? Если…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Замечание к оформлению статьи:&lt;br /&gt;
&lt;br /&gt;
1. Почему написано &amp;quot;авторы&amp;quot;, вы писали работы не одна? Если да, то укажите пару.&lt;br /&gt;
&lt;br /&gt;
2. Почему часть не соответствует структуре примера? Указанные вами два заголовка имеют номера 2.4 и 2.7, а не 2.1 2.2. Восстановите требуемую структуру. &lt;br /&gt;
&lt;br /&gt;
3. Проверьте русский язык :) &amp;quot;При этом вычислительная мощность алгоритма, равная &#039;&#039;&#039;Полужирное начертание&#039;&#039;&#039;отношение  числа операций к суммарному объему входных и выходных данных – O(\sqrt{n}).&amp;quot; И согласование слов.&lt;/div&gt;</summary>
		<author><name>Sleo</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:%D0%9E%D0%B3%D0%BD%D0%B5%D0%B2%D0%B0_%D0%9C%D0%B0%D1%80%D0%B8%D1%8F/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=14200</id>
		<title>Участник:Огнева Мария/Метод встречи посередине</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:%D0%9E%D0%B3%D0%BD%D0%B5%D0%B2%D0%B0_%D0%9C%D0%B0%D1%80%D0%B8%D1%8F/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=14200"/>
		<updated>2016-10-27T13:31:55Z</updated>

		<summary type="html">&lt;p&gt;Sleo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:Maria rojas|М.С. Огнева]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Криптоанализом назвают науку восстановления (дешифрования) открытого (нешифрованного) текста без доступа к ключу. Попытка криптоанализа называется атакой.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Методом встречи посередине&#039;&#039;&#039; (англ. meet-in-the-middle attack) называется класс атак на криптографические алгоритмы (алгоритмы шифрования), которые асимптотически уменьшают время полного перебора по всем ключам, но при этом увеличивают объем требуемой памяти. Впервые данный метод был предложен Уитфилдом Диффи и Мартином Хеллманом в 1977 году &amp;lt;ref&amp;gt;Diffie Whitfield, Hellman Martin E. &#039;&#039;Exhaustive Cryptanalysis of the NBS Data Encryption Standard.&#039;&#039; - Journal Computer vol.10 pp.74–84 - June 1977&amp;lt;/ref&amp;gt; для блочных шифров.&lt;br /&gt;
=== История ===&lt;br /&gt;
Алгоритм шифрования [https://ru.wikipedia.org/wiki/DES DES] был принят в качестве стандарта в 1977 году. Длина ключа нового стандарта составляла 56 бит, довольно большое число по тем временам, но оставляла возможность полного перебора (&amp;lt;math&amp;gt;2^{56} &amp;lt;/math&amp;gt;). В 1977 Диффи и Хеллман предложили устройство, стоимостью примерно 20 млн. долларов, которое смогло бы найти ключ DES за один день. Поэтому появилась необходимость увеличить стойкость алгоритма DES, используя технику многократного шифрования. Этот способ позволяет искусственно увеличить длину ключа, применяя несколько раз операцию шифрования с разными ключами. Так для алгоритма 2DES (двойное шифрование) длина ключа равна 112 бит, то есть полный перебор становится бессмысленной затеей.&lt;br /&gt;
В 1981 году Ральф Меркл и Мартин Хеллман&amp;lt;ref&amp;gt;Merkle Ralph C., Hellman  Martin E. &#039;&#039;On the security of multiple encryption.&#039;&#039; - Journal Communications of the ACM, num.7 vol.24 pp.465-467 - July 1981&amp;lt;/ref&amp;gt; подробно разбирают безопасность двойного шифрования и описывают метод встречи посередине, позволяющий восстановить ключ шифрования не за &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt; операций шифрования, а за относительно пустяковые &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; за счет перебора не одного длинного ключа, а двух более коротких. Следующая модернизация DES - Triple DES с 168-битным ключом - требует от метода встречи посередине &amp;lt;math&amp;gt;2^{56} &amp;lt;/math&amp;gt; памяти и &amp;lt;math&amp;gt;2^{112}&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;
# Применимо для любого многократного шифрования одним алгоритмом по разным ключам, а также для случая, если множество ключей криптографического алгоритма замкнуто относительно композиции (для любых ключей k&#039; и k&amp;quot; найдется ключ k такой, что результат шифрования любого текста последовательно на k&#039; и k&amp;quot; равен результату шифрования того же текста на k).&lt;br /&gt;
&lt;br /&gt;
=== Описание метода для алгоритма двойного шифрования ===&lt;br /&gt;
На данной странице будет рассмотрен более простой вариант - двойное шифрование &amp;lt;ref&amp;gt;Грушо А.А., Применко Э.А., Тимонина Е.Е. &#039;&#039;Анализ и синтез криптоалгоритмов. Курс лекций.&#039;&#039; - Москва: 2000. - 110 с.&amp;lt;/ref&amp;gt; (две итерации шифрования). Пусть &amp;lt;math&amp;gt;p, c&amp;lt;/math&amp;gt; – открытый (plaintext) и шифрованный текст  (ciphertext) соответственно. Тогда сокращение полного перебора происходит следующим образом: &lt;br /&gt;
#Находим множество всех шифртекстов &amp;lt;math&amp;gt;W&amp;lt;/math&amp;gt;, получаемых одинарным шифрованием открытого текста p по всем возможным ключам первой итерации.&lt;br /&gt;
#Находим множество всех шифртекстов &amp;lt;math&amp;gt;Z&amp;lt;/math&amp;gt;, получаемых одинарным дешифрованием шифрованного текста c по всем возможным ключам второй итерации.&lt;br /&gt;
#Если множества &amp;lt;math&amp;gt;W&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;Z&amp;lt;/math&amp;gt; имеют непустое пересечение, то искомым ключом шифрования будет являться пара ключей, при помощи которых это пересечение было зашифровано из &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; и дешифровано из &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Пусть алгоритм шифрования описывается как &amp;lt;math&amp;gt;Enc(k, t) &amp;lt;/math&amp;gt;, дешифрования &amp;lt;math&amp;gt;Dec(k, t) &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; – ключ, &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; – текст. &lt;br /&gt;
Тогда получаемый двойным шифрованием по ключам &amp;lt;math&amp;gt;k_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k_2&amp;lt;/math&amp;gt; шифрованный текст равен: &amp;lt;math&amp;gt;c = Enc(k_2, Enc(k_1, p))&amp;lt;/math&amp;gt;. &lt;br /&gt;
Открытый текст получается из шифрованного двойным дешифрованием: &amp;lt;math&amp;gt;p=Dec(k_1, Dec(k_2, c))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; тексты &amp;lt;math&amp;gt;p, c&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039; ключ &amp;lt;math&amp;gt;k=(k_1, k_2)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
Предположим для упрощения, что для известной пары &amp;lt;math&amp;gt;(p, c)&amp;lt;/math&amp;gt; существует единственный ключ &amp;lt;math&amp;gt;(k_1, k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
Составим таблицы &amp;lt;math&amp;gt;W&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;Z&amp;lt;/math&amp;gt;:&lt;br /&gt;
*для всех &amp;lt;math&amp;gt;k^i_1 \in K_1&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;w(k^i_1) = Enc (k^i_1, p)&amp;lt;/math&amp;gt;&lt;br /&gt;
*для всех &amp;lt;math&amp;gt;k^j_2 \in K_2&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;z(k^j_2) = Dec (k^j_2, c)&amp;lt;/math&amp;gt;&lt;br /&gt;
Таблицы объединяются и сортируются по полученным промежуточным шифртекстам &amp;lt;math&amp;gt;z_i, w_j&amp;lt;/math&amp;gt;. Пара &amp;lt;math&amp;gt;z_i = w_j&amp;lt;/math&amp;gt;, которую можно найти одиночным просмотром объединенной таблицы, определяет искомый ключ &amp;lt;math&amp;gt;(k^i_1, k^j_2) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В более общем случае, может получиться не одна пара &amp;lt;math&amp;gt;z_i = w_j&amp;lt;/math&amp;gt;. Тогда необходимы еще пары &amp;lt;math&amp;gt;(p, c)&amp;lt;/math&amp;gt; для определения истинного ключа.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Основную сложность алгоритма составляет перебор ключей &amp;lt;math&amp;gt;k^i_1,k^j_2&amp;lt;/math&amp;gt;, а так же сортировка полученных массивов &amp;lt;math&amp;gt;W&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;Z&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Метод использует в качестве составных частей следующие алгоритмы:&lt;br /&gt;
# Алгоритм зашифрования/расшифрования&lt;br /&gt;
#*В качестве основных примем алгоритмы [https://ru.wikipedia.org/wiki/Blowfish Blowfish] и [https://ru.wikipedia.org/wiki/DES DES], сложность которых пропорциональна длине ключа. В связи с тем, что длина ключа не больше 64 бит, то будем считать, что эти алгоритмы выполняются за единицу времени.&lt;br /&gt;
# Алгоритм сортировки&lt;br /&gt;
#*Будем считать, что используется быстрая сортировка или сортировка слиянием, которые в среднем работают за &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
#Алгоритм поиска&lt;br /&gt;
#*Совпадающие значения матриц &amp;lt;math&amp;gt;W&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;Z&amp;lt;/math&amp;gt; будем искать одиночным просмотром всей таблицы.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Последовательность действий метода:&lt;br /&gt;
# Вычислить таблицы &amp;lt;math&amp;gt;W&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;Z&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления  и сохраняя соответствующие ключи для шифрования/дешифрования.&lt;br /&gt;
# Отсортировать массив &amp;lt;math&amp;gt;W \cup Z&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Найти совпадения в отсортированной таблице.&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
# Сложность вычисления таблиц &amp;lt;math&amp;gt;W&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;Z&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
# Объединение таблиц и их сортировка будет иметь сложность: &amp;lt;math&amp;gt;O([|K_1|+|K_2|]\log[|K_1|+|K_2|])&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Поиск совпадений: &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
Общая сложность всего метода равна: &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O([|K_1|+|K_2|]\log[|K_1|+|K_2|]) + O(|K_1|+|K_2|)=O([|K_1|+|K_2|]\log[|K_1|+|K_2|])&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= (k_1,k_2)&amp;lt;/math&amp;gt;. Если предположить, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;, то &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;.&lt;br /&gt;
Тогда сложность метода составляет &amp;lt;math&amp;gt;O(\sqrt n\log n) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
Опишем информационный граф алгоритма. &lt;br /&gt;
&lt;br /&gt;
На вход подаётся открытый и шифрованный тексты. После открытый текст шифруется (Enc) по всем ключам &amp;lt;math&amp;gt;k_1&amp;lt;/math&amp;gt;, а дешифрованный дешифруется (Dec) по всем ключам &amp;lt;math&amp;gt;k_2&amp;lt;/math&amp;gt;. Далее полученные тексты сравниваются между собой (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:Graph MITM.jpg|thumb|center|600px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Plaintext — открытый текст, ciphertext — шифрованный текст, Enc — операция шифрования, Dec — операция дешифрования, Cmp — операция сравнения, Key — полученный ключ]]&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Как видно из информационного графа, для реализации метода в параллельном варианте потребуются выполнение следующих двух ярусов ярусно-параллельной формы (ЯПФ):&lt;br /&gt;
# &amp;lt;math&amp;gt;2* \sqrt{n}&amp;lt;/math&amp;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;2&amp;lt;/math&amp;gt;, ширина – &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; (т.к. &amp;lt;math&amp;gt;n&amp;gt; 2* \sqrt n&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: открытый текст &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; и шифрованный текст &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt;,имеющие одинаковую длину.&lt;br /&gt;
&lt;br /&gt;
Так как рассматриваемые шифры являются блочными, то равенство длины текста длине ключа не является обязательным, текст может быть длиннее. В такой ситуации тексты являются последовательностью блоков, а для шифрования/дешифрования берётся один блок текстов для максимального ускорения операций.&lt;br /&gt;
&lt;br /&gt;
Примем, что длина ключей &amp;lt;math&amp;gt;k_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k_2&amp;lt;/math&amp;gt; равна 64 битам. То есть длина текста равна 64 битам или кратна этому числу.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: множество пар &amp;lt;math&amp;gt;(k_1,k_2)&amp;lt;/math&amp;gt;, для которых нашлись совпадения. &lt;br /&gt;
&lt;br /&gt;
Лишние пары могли получиться при шифровании/дешифровании одного блока текстов. Тогда для получения истинного ключа необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
Длина искомого ключа: 128 бит.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
Соотношение последовательной и параллельной сложности для данного метода равно &amp;lt;math&amp;gt;O(\sqrt n\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
При этом вычислительная мощность алгоритма, равная отношение числа операций к суммарному объему входных и выходных данных – &amp;lt;math&amp;gt;O(\sqrt{n})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм полностью детерминирован при условии корректности данных. &lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин, соответствующих операциям шифрования/дешифрования образуют пучки мощности &amp;lt;math&amp;gt;\sqrt{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;
В свободном доступе существуют коды для метода встречи по середине с использованием шифрования Blowfish и хэш-таблиц на [https://gist.github.com/dchest/1062437 C], а также с использованием шифрования 2DES на [https://github.com/le1ca/class-resources/blob/master/ddes/ddes.py питоне].&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Категория:Криптографические алгоритмы]]&lt;/div&gt;</summary>
		<author><name>Sleo</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Mikhail_Tsarev&amp;diff=14179</id>
		<title>Обсуждение участника:Mikhail Tsarev</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Mikhail_Tsarev&amp;diff=14179"/>
		<updated>2016-10-27T12:38:28Z</updated>

		<summary type="html">&lt;p&gt;Sleo: Новая страница: «Замечания к оформлению статьи:  1. в первой строке указать вклад каждого автора в статью.…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Замечания к оформлению статьи:&lt;br /&gt;
&lt;br /&gt;
1. в первой строке указать вклад каждого автора в статью.&lt;br /&gt;
&lt;br /&gt;
2. в пункте 1.9 указать чему соответствуют разные входные и выходные данные. Иначе непонятно будет человеку, который первый раз на сайте.&lt;br /&gt;
&lt;br /&gt;
3. Литературу не использовали?&lt;/div&gt;</summary>
		<author><name>Sleo</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:Khotkin/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0_%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE_%D1%80%D0%B0%D0%B7%D0%BC%D0%B5%D1%80%D0%B0&amp;diff=14175</id>
		<title>Участник:Khotkin/Построение матрицы Адамара произвольного размера</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:Khotkin/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0_%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE_%D1%80%D0%B0%D0%B7%D0%BC%D0%B5%D1%80%D0%B0&amp;diff=14175"/>
		<updated>2016-10-27T12:36:23Z</updated>

		<summary type="html">&lt;p&gt;Sleo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Построение матрицы Адамара&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(m2^{2m})&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(2^{2n})&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;2^{2n}&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: Хоткин Кирилл 623 гр., Царев Михаил 615 гр.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Матрица Адамара&#039;&#039;&#039; &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; представляет собой матрицу размера  &#039;&#039;n&#039;&#039;×&#039;&#039;n&#039;&#039; из элементов  &amp;lt;math&amp;gt;+1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;-1&amp;lt;/math&amp;gt;, такую, что: &amp;lt;math&amp;gt;H \cdot H^T = n \cdot E_n,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;E_n&amp;lt;/math&amp;gt; — это единичная матрица размера &#039;&#039;n&#039;&#039;×&#039;&#039;n&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Матрицы Адамара находят широкое применение в теории кодирования (коды, исправляющие ошибки), теории планирования многофакторных экспериментов (ортогональные блок-схемы), квантовой информатике и прочих областях.&lt;br /&gt;
&lt;br /&gt;
Матрица Адамара остаётся матрицей Адамара при следующих преобразованиях:&lt;br /&gt;
* умножение строчки или столбца на −1;&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;H_m&amp;lt;/math&amp;gt; подразумевается матрица порядка &amp;lt;math&amp;gt;2^m&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Примерами матриц Адамара различных размеров являются следующие матрицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_0 = (1);&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_1 = &lt;br /&gt;
\begin{pmatrix} 1 &amp;amp; 1&lt;br /&gt;
\\1 &amp;amp; -1 &lt;br /&gt;
\end{pmatrix};&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_2 = &lt;br /&gt;
\begin{pmatrix} 1 &amp;amp; 1 &amp;amp; 1 &amp;amp; 1&lt;br /&gt;
\\1 &amp;amp; -1 &amp;amp; 1 &amp;amp; -1&lt;br /&gt;
\\1 &amp;amp; 1 &amp;amp;- 1 &amp;amp; -1&lt;br /&gt;
\\1 &amp;amp; -1 &amp;amp; -1 &amp;amp; 1&lt;br /&gt;
\end{pmatrix}.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вообще, если &amp;lt;math&amp;gt;H_m&amp;lt;/math&amp;gt; матрица Адамара порядка &amp;lt;math&amp;gt;2^m&amp;lt;/math&amp;gt;, то матрица &lt;br /&gt;
&amp;lt;math&amp;gt;H_{m+1} = &lt;br /&gt;
\begin{pmatrix} H_m &amp;amp; H_m&lt;br /&gt;
\\H_m &amp;amp; -H_m&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
является матрицей Адамара порядка &amp;lt;math&amp;gt;2^{m+1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Кроме того, матрицу Адамара порядка &amp;lt;math&amp;gt;2^m&amp;lt;/math&amp;gt; можно получить по следующей формуле &amp;lt;math&amp;gt;H^{\otimes m} = H_1  \otimes ... \otimes H_1&amp;lt;/math&amp;gt;, где знак &amp;lt;math&amp;gt; \otimes &amp;lt;/math&amp;gt; означает тензорное произведение.&lt;br /&gt;
&lt;br /&gt;
Также существует недоказанная гипотеза Адамара, которая утверждает, что существуют матрицы Адамара порядка &amp;lt;math&amp;gt;4k&amp;lt;/math&amp;gt; для любого натурального &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, однако матрица Адамара порядка &amp;lt;math&amp;gt;268&amp;lt;/math&amp;gt;  до сих пор не построена, как и для ряда других порядков больше &amp;lt;math&amp;gt;268&amp;lt;/math&amp;gt;. Поэтому в данной работе будут рассматриваться матрицы Адамара порядка &amp;lt;math&amp;gt;2^m&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Описанные ранее способы построения матрицы Адамара не являются оптимальными, поэтому вычисление матрицы Адамара порядка &amp;lt;math&amp;gt;2^m&amp;lt;/math&amp;gt; будет производится поэлементно с помощью следующей формулы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
(H_m)_{ij}=(-1)^ {\sum_{k}{(i \&amp;amp; j)_k}},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;\&amp;amp; - &amp;lt;/math&amp;gt; побитовая операция И,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;(i \&amp;amp; j)_k - &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; -ый разряд в двоичном представлении числа &amp;lt;math&amp;gt;(i \&amp;amp; j)&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;&lt;br /&gt;
(H_m)_{ij}=(-1)^ {\sum_{k}{(i \&amp;amp; j)_k}}.&lt;br /&gt;
&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;(-1)^ {\sum_{k}{(i \&amp;amp; j)_k}}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Для вычисления очередного элемента матрицы Адамара нужно выполнить следующие шаги:&lt;br /&gt;
&lt;br /&gt;
1.  Побитовое умножение &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;:  &amp;lt;math&amp;gt;result = i \&amp;amp; j &amp;lt;/math&amp;gt; ;&lt;br /&gt;
&lt;br /&gt;
2. Нахождение числа единиц в двоичной записи числа &amp;lt;math&amp;gt;result &amp;lt;/math&amp;gt;:  &amp;lt;math&amp;gt; sum = \sum_{k}{(result)_k} &amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
3. Нахождение элемента матрицы Адамара: &amp;lt;math&amp;gt;(H_m)_{ij}=(-1)^{sum}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Возможная реализация на языке C++:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int get_sign(unsigned N) {&lt;br /&gt;
    int i;&lt;br /&gt;
    for (i=0; N; N&amp;gt;&amp;gt;=1) { i+=N&amp;amp;1;}&lt;br /&gt;
    return (i&amp;amp;1) ? -1 : 1;&lt;br /&gt;
}&lt;br /&gt;
void adamar(int **e, int size) {&lt;br /&gt;
    for (unsigned int i = 0; i &amp;lt; size; ++i)&lt;br /&gt;
        for (unsigned int j = 0; j &amp;lt; size; ++j)&lt;br /&gt;
            e[i][j]=get_sign(i&amp;amp;j);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Для выполнения первого шага алгоритма для всех элементов матрицы Адамара необходимо суммарно выполнить:&lt;br /&gt;
* &amp;lt;math&amp;gt;2^{2m}&amp;lt;/math&amp;gt; операций побитового умножения.&lt;br /&gt;
На втором шаге алгоритма необходимо выполнить для каждого элемента матрицы Адамара:&lt;br /&gt;
* от 0 до m или m логических сдвигов на один бит в зависимости от программной реализации;&lt;br /&gt;
* от 0 до m или m операций сложения в зависимости от программной реализации;&lt;br /&gt;
* от 0 до m или m операций логического умножения в зависимости от программной реализации.&lt;br /&gt;
На третьем шаге для всех элементов необходимо сумарно выполнить:&lt;br /&gt;
* &amp;lt;math&amp;gt;2^{2m}&amp;lt;/math&amp;gt; операций побитового умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;2^{2m}&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+2)2^{2m}&amp;lt;/math&amp;gt; операций логического умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;m\cdot2^{2m}&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
* &amp;lt;math&amp;gt;m\cdot2^{2m}&amp;lt;/math&amp;gt; операций логического сдвига на один бит;&lt;br /&gt;
* &amp;lt;math&amp;gt;2^{2m}&amp;lt;/math&amp;gt; операций сравнения с нулем.&lt;br /&gt;
Всего  &amp;lt;math&amp;gt;(3m+3)2^{2m}&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;i\&amp;amp;j&amp;lt;/math&amp;gt; - операция побитового умножения, где &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; соответствующие координаты элемента &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* NoO (number of ones) - вычисление количества единиц числа в двоичной системе. Состоит из последовательного применения операций сложения и побитового умножения;&lt;br /&gt;
* Sign - определение знака соответствующего элемента. Если результат предыдущего шага - чётное число, то знак положительный, иначе - отрицательный.  &lt;br /&gt;
&lt;br /&gt;
[[File:Hadamar matrix.png|thumb|center|1400px|Рисунок 1. Граф алгоритма построения матрицы Адамара.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Вычисление любого элемента можно производить независимо от других, то есть параллельно.&lt;br /&gt;
&lt;br /&gt;
Высота канонической ярусно-параллельной формы равна 3.&lt;br /&gt;
Ширина ЯПФ равна &amp;lt;math&amp;gt;2^{2m}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: m - размерность матрицы &amp;lt;math&amp;gt;H_m&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: 1 (число m).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица Адамара &amp;lt;math&amp;gt;H_{m}&amp;lt;/math&amp;gt; размерностью &amp;lt;math&amp;gt;2^m&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2^{2m}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
* &#039;&#039;Вычислительная мощность&#039;&#039; алгоритма построения матрицы Адамара, как отношение числа операций к суммарному объему входных и выходных данных: &lt;br /&gt;
:&amp;lt;math&amp;gt;\,\frac{(3m+3)2^{2m}}{1+2^{2m}}\, \approx 3m+3.&amp;lt;/math&amp;gt;;&lt;br /&gt;
* Алгоритм построения матрицы Адамара является &#039;&#039;недетерминированным&#039;&#039;, так как число операций меняется в зависимости от входных данных (числа m, которое формирует матрицу размерности 2&amp;lt;sup&amp;gt;&#039;&#039;m&#039;&#039;&amp;lt;/sup&amp;gt;&amp;amp;nbsp;&amp;amp;times;&amp;amp;nbsp;2&amp;lt;sup&amp;gt;&#039;&#039;m&#039;&#039;&amp;lt;/sup&amp;gt;);&lt;br /&gt;
* Данный алгоритм построения матрицы Адамара является &#039;&#039;несбалансированным&#039;&#039;. Так как каждый элемент матрицы может обрабатываться независимо от других, вычисление элементов можно распределить по процессам. В случае, когда количество элементов матрицы &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; не кратно количеству процессов &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, на некоторые процессы ложится дополнительная задача вычисления элементов матрицы в количестве &amp;lt;math&amp;gt;a=n\operatorname{mod}s&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Программная реализация алгоритма==&lt;br /&gt;
===Особенности реализации последовательного алгоритма===&lt;br /&gt;
&lt;br /&gt;
Учитывая, что рассматриваемый алгоритм строит симметричные матрицы Адамара, можно уменьшить количество вычисляемых элементов c &amp;lt;math&amp;gt;2^{2n}&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;\frac{2^n+2^{2n}}{2}&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;
# [http://www.exponenta.ru/soft/matlab/potemkin/book2/chapter5/hadamard.asp MATLAB];&lt;br /&gt;
# [https://reference.wolfram.com/language/ref/HadamardMatrix.html WOLFRAM];&lt;br /&gt;
# [http://pydoc.net/Python/rogues/0.3.0/rogues.matrices.hadamard/ Python];&lt;br /&gt;
# [http://www.obihiro.ac.jp/~suzukim/masuda/octave/html3/octave_97.html Octave];&lt;br /&gt;
&lt;br /&gt;
Стоит отметить, что во многих вычислительных пакетах встроена операция тензорного произведения матриц, которая позволяет строить матрицу Адамара по определению. Этот факт позволяет использовать матрицу Адамара в этих вычислительных пакетах: &lt;br /&gt;
# [https://ru.wikipedia.org/wiki/Maple MAPLE];&lt;br /&gt;
# [https://ru.wikipedia.org/wiki/Mathcad MATCATH];&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;/div&gt;</summary>
		<author><name>Sleo</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Nikita&amp;diff=14172</id>
		<title>Обсуждение участника:Nikita</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Nikita&amp;diff=14172"/>
		<updated>2016-10-27T12:18:25Z</updated>

		<summary type="html">&lt;p&gt;Sleo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Замечания к оформлению:&lt;br /&gt;
&lt;br /&gt;
1. Пункт 1.7 что обозначают серые вершины на графе?&lt;br /&gt;
&lt;br /&gt;
2. в пункте 1.9 указать чему соответствуют разные входные и выходные данные. Иначе непонятно будет человеку, который первый раз на сайте.&lt;br /&gt;
&lt;br /&gt;
3. Ссылки на литературу внутри текста статьи не нашел.&lt;/div&gt;</summary>
		<author><name>Sleo</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Nikita&amp;diff=14171</id>
		<title>Обсуждение участника:Nikita</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Nikita&amp;diff=14171"/>
		<updated>2016-10-27T12:16:56Z</updated>

		<summary type="html">&lt;p&gt;Sleo: Новая страница: «Замечания к оформлению:  1. Пункт 1.7 что обозначают серые вершины на графе?  2. в пункте 1.9 ук…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Замечания к оформлению:&lt;br /&gt;
&lt;br /&gt;
1. Пункт 1.7 что обозначают серые вершины на графе?&lt;br /&gt;
&lt;br /&gt;
2. в пункте 1.9 указать чему соответствуют разные входные и выходные данные. Иначе непонятно будет человеку, который первый раз на сайте.&lt;/div&gt;</summary>
		<author><name>Sleo</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:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=14168</id>
		<title>Участник:Nikita/Построение матрицы Адамара</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:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=14168"/>
		<updated>2016-10-27T12:13:36Z</updated>

		<summary type="html">&lt;p&gt;Sleo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Построение матрицы Адамара&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы статьи: [[Участник:Nikita|Иванов Н.В.]] (1.1,1.7,1.9,1.10,2.7), [[Участник:Tsyganov Nikita|Цыганов Н.И.]] (1.2,1.3,1.4,1.5,1.6,1.7,1.8).&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Матрицы Адамара были введены в математический обиход в конце прошлого века и играют важную роль в алгебре и комбинаторике. Они находят широкое применение в теории кодирования (коды, исправляющие ошибки), теории планирования многофакторных экспериментов (блок-схемы) и других областях математики. Сравнительно недавно (в 1960 г.) было замечено, что эти матрицы могут быть использованы для построения кодов с большим кодовым расстоянием.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Матрицей Адамара порядка n&#039;&#039;&#039;&#039;&#039; называется &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;, элементами которой являются +1 и −1 такая, что &amp;lt;math&amp;gt;H H^T = n E_n&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;E_n&amp;lt;/math&amp;gt; - единичная матрица размера n.&lt;br /&gt;
&lt;br /&gt;
Матрица Адамара обладает следующими &#039;&#039;свойствами&#039;&#039;:&lt;br /&gt;
* Различные строки матрицы ортогональны&lt;br /&gt;
* Скалярное произведение любой строки саму на себя равно n&lt;br /&gt;
* Умножение любой строки или столбца на -1 переводит H в другую матрицу Адамара&lt;br /&gt;
* Если все элементы первой строки и первого столбца равны +1, то матрица Адамара называется нормализованной&lt;br /&gt;
&lt;br /&gt;
Ниже показаны примеры нормализованных матриц Адамара порядка 1,2 и 4, причем нормализованность матриц сохраняется при перестановке любых строк и столбцов, кроме первых:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_1 = (1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_2 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1 &amp;amp; -1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_4 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; 1 &amp;amp; 1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; 1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; -1 &amp;amp; 1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Предполагается, что существуют матрицы Адамара порядка 1, 2 и всех порядков n, кратных 4, хотя это до сих пор еще не было доказано. Нет универсального алгоритма построения матрицы Адамара произвольного размера, но известно большое число методов для различных частных случаев, и наименьший порядок, для которого матрица Адамара еще не построена, равен 268 (на 1977 г.). Мы приведем метод построения Пейли, который важен для теории кодирования. &lt;br /&gt;
&lt;br /&gt;
====Метод Пейли====&lt;br /&gt;
Это построение дает матрицы Адамара любого порядка &amp;lt;math&amp;gt;n=p+1&amp;lt;/math&amp;gt;, кратного 4, где p-простое число.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Определение.&#039;&#039;&#039; Пусть p-простое число. Ненулевые квадраты чисел, приведенные по модулю p, называются квадратичными вычетами по модулю p или просто вычетами по модулю p.&lt;br /&gt;
&lt;br /&gt;
Функция &amp;lt;math&amp;gt;X(i)&amp;lt;/math&amp;gt;, называемая символом Лежандра, определяется на целых числах следующим образом:&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=0&amp;lt;/math&amp;gt;, если i кратно p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=1&amp;lt;/math&amp;gt;, если остаток от деления i на p является квадратным вычетом по модулю p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=-1&amp;lt;/math&amp;gt;, если остаток от деления i на p является невычетом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь мы построим матрицу Джекобстола &amp;lt;math&amp;gt;Q=(q_{ij})&amp;lt;/math&amp;gt;. Она представляет собой &amp;lt;math&amp;gt;(p*p)&amp;lt;/math&amp;gt;-матрицу, строки и столбцы которой пронумерованы числами 0,1,..., p-1, а элементы &amp;lt;math&amp;gt;q_{ij}=X(j-i)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Пусть теперь &amp;lt;math&amp;gt;&lt;br /&gt;
H =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1^T &amp;amp; Q-I\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Доказано, что такая матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; представляет собой нормализованную матрицу Адамара порядка p+1, которую называют матрицей типа Пейли.&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;gt;0&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число.&lt;br /&gt;
&lt;br /&gt;
Вспомогательные данные: &lt;br /&gt;
&lt;br /&gt;
* Число &amp;lt;math&amp;gt;p=n-1&amp;lt;/math&amp;gt;;&lt;br /&gt;
* Вектор квадратичных вычетов (по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;r_i&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;2p&amp;lt;/math&amp;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;h_{ij}&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;. Индексация строчек и столбцов идёт с нуля. &lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
:1. Строится вектор квадратичных вычетов &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt;.&lt;br /&gt;
:: Первые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов вектора &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;) определяются следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;i \in \{1^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, 2^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, ... , (\frac{p-1}{2})^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p\}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;, то есть если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; является квадратичным вычетом по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;;&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=-1&amp;lt;/math&amp;gt;, иначе.&lt;br /&gt;
::Вторые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов (&amp;lt;math&amp;gt;i=p,1,...,2p-1&amp;lt;/math&amp;gt;) являются копией первых &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов:&lt;br /&gt;
:::&amp;lt;math&amp;gt;r_i=r_{i-p}, i=p,1,...,2p-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
:2. Строится матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;.&lt;br /&gt;
::Элементы матрицы Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; находятся следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{0j}=1, j=0,1, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{i0}=1, i=1,2, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{ij}=r_{j-i+p}, i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро алгоритма состоит из &amp;lt;math&amp;gt;(n-1) \times (n-1)&amp;lt;/math&amp;gt; операций присваивания следующего вида:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;h_{ij}=r_{j-i+p},&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; i=1,2, ... ,n-1, j=1,2, ... ,n-1.&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;
Приведем процедуру на языке С++, реализующую описанный алгоритм. На вход процедуре подается порядок матрицы &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и ссылка на заполняемую матрицу &amp;lt;math&amp;gt;result&amp;lt;/math&amp;gt;. Считаем, что &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; положительно, делится на &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число, а размер матрицы &amp;lt;math&amp;gt;result&amp;lt;/math&amp;gt; равен &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void buildHadamardMatrix(int n, vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt; &amp;amp; result)&lt;br /&gt;
{&lt;br /&gt;
	// 1) Считаем вычеты по модулю p=n-1 и создаем вспомогательный массив вычетов residues&lt;br /&gt;
	// Достаточно посчитать значения (1^2 mod p), (2^2 mod p), ... , (((p-1)/2)^2 mod p) - эти значениями и будут являться вычетами.&lt;br /&gt;
	// Строим массив residues размера 2*p, в котором первые p элементов заполняются по следующей схеме: 1, если индекс элемента - вычет, -1 - иначе.&lt;br /&gt;
	// Вторая половина массива получается дублированием первой половины&lt;br /&gt;
	int p=n-1;&lt;br /&gt;
	vector&amp;lt;int&amp;gt; residues;&lt;br /&gt;
	residues.resize(2*p);&lt;br /&gt;
	// Заполняем массив&lt;br /&gt;
	for (int i=0; i&amp;lt;p; i++) {&lt;br /&gt;
		residue[i] = -1;&lt;br /&gt;
	}&lt;br /&gt;
	for (int i=1; i&amp;lt;= (p-1)/2; i++) {&lt;br /&gt;
		residue[i^2 % p] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	for (int i=p; i&amp;lt;2*p; i++) {&lt;br /&gt;
		residue[i] = residue[i-p];&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// 2) Построение матрицы Адамара&lt;br /&gt;
	// Заполнение первой строки 1-цами&lt;br /&gt;
	for (int j=0; j&amp;lt;n; j++) {&lt;br /&gt;
		result[0][j] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	// Заполнение первого столбца 1-цами&lt;br /&gt;
	for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
		result[i][0] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	// Заполнение оставшейся части матрицы с использованием вспомогательного массива вычетов residues&lt;br /&gt;
	for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
		for (int j=1; j&amp;lt;n; j++) {&lt;br /&gt;
			result[i][j] = residues[j-i+p];&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&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;
Основными операциями алгоритма являются:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций взятия остатка;&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2+\frac{5}{2}n-3&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;n-1&amp;lt;/math&amp;gt; параллельных ветвей, второй блок - &amp;lt;math&amp;gt;\frac{n}{2}-1&amp;lt;/math&amp;gt; параллельных ветвей, третий - &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; и четвёртый - &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Файл:i_graph2.png]]&lt;br /&gt;
&lt;br /&gt;
Каждая вершина из &amp;lt;math&amp;gt;A_1-A_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C_1-C_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;D_1-D_{n^2}&amp;lt;/math&amp;gt; соответствует операции присваивания. А каждая вершина из &amp;lt;math&amp;gt;B_1-B_{\frac{n}{2}-1}&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;n-1&amp;lt;/math&amp;gt; операций присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-1&amp;lt;/math&amp;gt; участков, состоящих из трёх операций: умножения, взятия остатка и присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операций присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; операций присваивания.&lt;br /&gt;
&lt;br /&gt;
Из этого можно сделать вывод, что высота ярусно-параллельной формы информационного графа равняется 6 (присваивание, умножение, взятие остатка, присваивание, присваивание, присваивание). Ширина ярусно-параллельной формы равняется &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;, что означает, что при использовании &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; процессоров матрица Адамара будет строиться за 6 операций.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; порядок матрицы Адамара &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Дополнительные ограничения на &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;:&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;gt;0&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число&lt;br /&gt;
&#039;&#039;&#039;Объем входных данных:&#039;&#039;&#039; 1 (число &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n^2&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;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов является квадратичным. &lt;br /&gt;
&lt;br /&gt;
Вычислительная мощность алгоритма является постоянной (&amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
Алгоритм является полностью детерминированным. &lt;br /&gt;
&lt;br /&gt;
Для вершин &amp;lt;math&amp;gt;A_1-A_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B_1-B_{\frac{n}{2}-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C_1-C_{n-1}&amp;lt;/math&amp;gt; информационного графа степени исхода являются линейными, что означает, что при возможности на этапе реализации необходимо позаботиться об эффективном доступе к элементам массива &amp;quot;&amp;lt;math&amp;gt;residues&amp;lt;/math&amp;gt;&amp;quot;.&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;
* [https://www.mathworks.com/help/matlab/ref/hadamard.html?requestedDomain=www.mathworks.com MATLAB] (вносятся дополнительные ограничения, когда n, или n/12, или n/20 являются степенями по основанию 2)&lt;br /&gt;
* [http://r-survey.r-forge.r-project.org/survey/html/hadamard.html R]&lt;br /&gt;
* [https://reference.wolframcloud.com/cloudplatform/ref/HadamardMatrix.html Wolfram Mathematica]&lt;br /&gt;
* [http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.linalg.hadamard.html SciPy для Python]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
[1] Воеводин В.В., Воеводин Вл. В. Параллельные вычисления. – СПб.: БХВ - Петербург, 2002.&lt;br /&gt;
&lt;br /&gt;
[2] Мак-Вильямс Ф. Дж., Слоэн Н. Дж. А. Теория кодов, исправляющих ошибки: Пер. с англ. — М: Связь, 1979. — c. 52-57&lt;/div&gt;</summary>
		<author><name>Sleo</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Katemeron&amp;diff=14167</id>
		<title>Обсуждение участника:Katemeron</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Katemeron&amp;diff=14167"/>
		<updated>2016-10-27T12:11:45Z</updated>

		<summary type="html">&lt;p&gt;Sleo: Новая страница: «0. Отсутствует структура документа, как указано в требованиях.  1. Пункт 1.1 - это не описани…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;0. Отсутствует структура документа, как указано в требованиях.&lt;br /&gt;
&lt;br /&gt;
1. Пункт 1.1 - это не описание алгоритма, это рассказ про матрицы Адамара. Надо исправить&lt;br /&gt;
&lt;br /&gt;
2. Отсутствует оглавление&lt;br /&gt;
&lt;br /&gt;
3. Отсутствует указания автора статьи в первой строке&lt;br /&gt;
&lt;br /&gt;
4. В начале статьи должна быть таблица со следующей информацией (Последовательная сложность, Объём входных данных, Объём выходных данных, Высота ярусно-параллельной формы, Ширина ярусно-параллельной формы).&lt;br /&gt;
&lt;br /&gt;
5. пункт 1.2 неполный, требуется подробное описание.&lt;br /&gt;
&lt;br /&gt;
6. пункт 1.3: &amp;quot;Вычислительное ядро рекурсивного алгоритма состоит из  \;N^2\; присвоений значений и .&amp;quot; Допишите до конца...&lt;br /&gt;
&lt;br /&gt;
7. пункт 1.4 более подробно.&lt;br /&gt;
&lt;br /&gt;
8. пункт 1.7 - не такой граф требовался, смотрите примеры. (см. пример: https://algowiki-project.org/ru/%D0%A0%D0%B0%D0%B7%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%A5%D0%BE%D0%BB%D0%B5%D1%86%D0%BA%D0%BE%D0%B3%D0%BE_(%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D0%BA%D0%B2%D0%B0%D0%B4%D1%80%D0%B0%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BA%D0%BE%D1%80%D0%BD%D1%8F)&lt;br /&gt;
&lt;br /&gt;
9. Вычислительная мощность не приведена.&lt;br /&gt;
&lt;br /&gt;
10. 2.7 требуется указать больше реализаций.&lt;br /&gt;
&lt;br /&gt;
11. Ссылки в самом тексте статьи указываются иначе. (см. пример: https://algowiki-project.org/ru/%D0%A0%D0%B0%D0%B7%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%A5%D0%BE%D0%BB%D0%B5%D1%86%D0%BA%D0%BE%D0%B3%D0%BE_(%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D0%BA%D0%B2%D0%B0%D0%B4%D1%80%D0%B0%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BA%D0%BE%D1%80%D0%BD%D1%8F)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Статья требует более подробного описания КАЖДОГО пунтка&lt;/div&gt;</summary>
		<author><name>Sleo</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:%D0%9C%D0%B0%D1%80%D0%BA%D0%BE%D0%B2%D0%B0_%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=14166</id>
		<title>Участник:Маркова Екатерина/Построение матрицы Адамара</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:%D0%9C%D0%B0%D1%80%D0%BA%D0%BE%D0%B2%D0%B0_%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=14166"/>
		<updated>2016-10-27T12:05:39Z</updated>

		<summary type="html">&lt;p&gt;Sleo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Свойства и структура алгоритма ==&lt;br /&gt;
&#039;&#039;&#039;1.1 Общее описание алгоритма&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; - это квадратная матрица размера &amp;lt;math&amp;gt;N\times N&amp;lt;/math&amp;gt;, составленная из чисел &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;-1&amp;lt;/math&amp;gt;, столбцы которой ортогональны, так что справедливо соотношение:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H*H^T = N*E_N&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;E_n&amp;lt;/math&amp;gt; - это единичная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. Матрицы Адамара применяются в различных областях, включая комбинаторику, численный анализ, обработку сигналов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1.2 Математическое описание алгоритма&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;H_N&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt; матрица Адамара порядка &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;-H_N&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt; матрица с противоположными элементами. Тогда матрица &amp;lt;math&amp;gt;H_{2N}&amp;lt;/math&amp;gt; получается следующим образом:&lt;br /&gt;
&amp;lt;math&amp;gt;H_{2N} = \begin{bmatrix}&lt;br /&gt;
         H_N &amp;amp; H_N \\&lt;br /&gt;
         H_N &amp;amp; -H_N&lt;br /&gt;
      \end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1.3 Вычислительное ядро алгоритма&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро рекурсивного алгоритма состоит из  &amp;lt;math&amp;gt;\;N^2\;&amp;lt;/math&amp;gt;  присвоений значений и .&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1.4 Макроструктура алгоритма&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Алгоритм не использует в качестве составных частей другие алгоритмы. Как это было описано в вычислительном ядре, в пустые блоки дублируются со сменой или без смены знака значения первого блока матрицы. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1.5 Схема реализации последовательного алгоритма&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
В описанном  виде алгоритм представляет из себя примитивное дублирование элементов матрицы, полученной на предыдущем этапе, в пустующие блоки новой матрицы.&lt;br /&gt;
&lt;br /&gt;
Сначала заполняется правый верхний блок матрицы &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_{ij} = H_{i(j - \frac{N}{2})}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;i = 1..\frac{N}{2}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;j = \frac{N}{2}+1..N&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
затем левый нижний блок&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_{ij} = H_{(i-\frac{N}{2})j}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;i = \frac{N}{2}+1..N&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;j = 1.. \frac{N}{2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Последним заполняется нижний правый блок матрицы&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_{ij} = H_{(i-\frac{N}{2})(j-\frac{N}{2})}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;i = \frac{N}{2}+1..N &amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;j = \frac{N}{2}+1..N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1.6 Последовательная сложность алгоритма&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Для заполнения  матрицы &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;N\times N&amp;lt;/math&amp;gt; необходимо &amp;lt;math&amp;gt;\;N^2\;&amp;lt;/math&amp;gt;  присвоений значений. Из чего можно сделать вывод, что рекурсивный метод построения матрицы Адамара является алгоритмом с &#039;&#039;квадратичной сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1.7 Информационный граф&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Зависимость данных для матрицы размерностью &amp;lt;math&amp;gt;4*4&amp;lt;/math&amp;gt; можно увидеть на рис.1.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Pic_hadamard.png|border|500px|Some text]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1.8 Ресурс параллелизма алгоритма&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Логически алгоритм можно разделить на три части, которые на каждом шаге выполняются независимо.&lt;br /&gt;
Внутри каждой части происходит &amp;lt;math&amp;gt;2^{2N}-2^{2(N-1)}&amp;lt;/math&amp;gt; независимых присвоений, где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; - номер шага алгоритма, причем размерность матрицы на шаге &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; равна &amp;lt;math&amp;gt;2^N&amp;lt;/math&amp;gt;. При этом необходимо ждать завершения предыдущего шага, то есть необходимы синхронизирующие блокировки.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1.9 Входные и выходные данные алгоритма&#039;&#039;&#039;&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\times N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Объем выходных данных: &amp;lt;math&amp;gt; N^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1.10 Свойства алгоритма&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Алгоритм полностью детерминирован.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2.7 Существующие реализации алгоритма&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Нахождение матрицы Адамара доступно в среде &#039;&#039;MATLAB&#039;&#039; и реализовано через функцию &#039;&#039;hadamard(n)&#039;&#039;.[https://www.mathworks.com/help/matlab/ref/hadamard.html?requestedDomain=www.mathworks.com]&lt;br /&gt;
&lt;br /&gt;
На языке &#039;&#039;Java&#039;&#039; реализован класс &#039;&#039;Hadamard&#039;&#039; не входящий в стандарт языка. С кодом можно ознакомиться по ссылке[https://gist.github.com/guitarkitten/3937264].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
1. Мак-Вильямс Ф., Слоэн Н. — &amp;quot;Теория кодов, исправляющих ошибки&amp;quot; (1979)&lt;br /&gt;
&lt;br /&gt;
2. Кронберг, Ю.И. Ожигов, А.Ю. Чернявский — &amp;quot;Алгебраический аппарат квантовой информатики 2&amp;quot;&lt;br /&gt;
&lt;br /&gt;
3. М. Н. Аршинов, Л. Е. Садовский — &amp;quot;Коды и математика&amp;quot; (1983)&lt;/div&gt;</summary>
		<author><name>Sleo</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:%D0%95%D0%B2%D0%B3%D0%B5%D0%BD%D0%B8%D0%B9_%D0%A0%D0%B0%D0%B5%D0%B2&amp;diff=14165</id>
		<title>Участник:Евгений Раев</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:%D0%95%D0%B2%D0%B3%D0%B5%D0%BD%D0%B8%D0%B9_%D0%A0%D0%B0%D0%B5%D0%B2&amp;diff=14165"/>
		<updated>2016-10-27T11:59:01Z</updated>

		<summary type="html">&lt;p&gt;Sleo: Новая страница: «Замечания по оформлению:  1. В пункте 1.6 явно укажите общую сложность посл. алгоритма.  2. Ин…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Замечания по оформлению:&lt;br /&gt;
&lt;br /&gt;
1. В пункте 1.6 явно укажите общую сложность посл. алгоритма.&lt;br /&gt;
&lt;br /&gt;
2. Информационный граф требует доработки, посмотрите пример. (см. пример: https://algowiki-project.org/ru/%D0%A0%D0%B0%D0%B7%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%A5%D0%BE%D0%BB%D0%B5%D1%86%D0%BA%D0%BE%D0%B3%D0%BE_(%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D0%BA%D0%B2%D0%B0%D0%B4%D1%80%D0%B0%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BA%D0%BE%D1%80%D0%BD%D1%8F)&lt;br /&gt;
&lt;br /&gt;
3. в пункте 1.9 указать чему соответствуют разные входные и выходные данные. Иначе непонятно будет человеку, который первый раз на сайте.&lt;br /&gt;
&lt;br /&gt;
4. Вычислительная мощность не приведена. (см. пример: https://algowiki-project.org/ru/%D0%A0%D0%B0%D0%B7%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%A5%D0%BE%D0%BB%D0%B5%D1%86%D0%BA%D0%BE%D0%B3%D0%BE_(%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D0%BA%D0%B2%D0%B0%D0%B4%D1%80%D0%B0%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BA%D0%BE%D1%80%D0%BD%D1%8F)&lt;/div&gt;</summary>
		<author><name>Sleo</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:%D0%95%D0%B2%D0%B3%D0%B5%D0%BD%D0%B8%D0%B9_%D0%A0%D0%B0%D0%B5%D0%B2/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0_%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE_%D1%80%D0%B0%D0%B7%D0%BC%D0%B5%D1%80%D0%B0&amp;diff=14163</id>
		<title>Участник:Евгений Раев/Построение матрицы Адамара произвольного размера</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:%D0%95%D0%B2%D0%B3%D0%B5%D0%BD%D0%B8%D0%B9_%D0%A0%D0%B0%D0%B5%D0%B2/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0_%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE_%D1%80%D0%B0%D0%B7%D0%BC%D0%B5%D1%80%D0%B0&amp;diff=14163"/>
		<updated>2016-10-27T11:54:16Z</updated>

		<summary type="html">&lt;p&gt;Sleo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Построение матрицы Адамара произвольного размера&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(2^n)^2&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Работу выполнил студент 611 группы Раев Евгений.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Матрица Адамара&#039;&#039;&#039; &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; — это квадратная матрица размера &#039;&#039;n&#039;&#039;×&#039;&#039;n&#039;&#039;, составленная из чисел 1 и −1, столбцы которой ортогональны, так что справедливо соотношение &lt;br /&gt;
: &amp;lt;math&amp;gt;H \cdot H^T = n \cdot E_n,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;E_n&amp;lt;/math&amp;gt; — это единичная матрица размера &#039;&#039;n&#039;&#039;. Матрицы Адамара применяются в различных областях, включая комбинаторику, численный анализ, обработку сигналов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Матрица оператора Адамара&#039;&#039;&#039; имееет вид&lt;br /&gt;
:&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
  H = \frac{1}{\sqrt2}&lt;br /&gt;
   &amp;amp;\begin{pmatrix}\begin{array}{rr}&lt;br /&gt;
    1 &amp;amp; 1\\&lt;br /&gt;
    1 &amp;amp; -1&lt;br /&gt;
   \end{array}\end{pmatrix}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Соответственно, существует итерационная формула нахождения матриц Адамара, через тензорное произведение матрицы оператора Адамара на матрицу Адамара меньшего порядка:&lt;br /&gt;
:&amp;lt;math&amp;gt;H_n = H_{1} \otimes H_{n-1}&amp;lt;/math&amp;gt;, где знак &amp;lt;math&amp;gt; \otimes &amp;lt;/math&amp;gt; означает тензорное произведение.&lt;br /&gt;
&lt;br /&gt;
Мы будем использовать в дальнейшем нормализованную матрицу оператора Адамара, без коэффицента (для удобности вывода):&lt;br /&gt;
:&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
  H = &lt;br /&gt;
   &amp;amp;\begin{pmatrix}\begin{array}{rr}&lt;br /&gt;
    1 &amp;amp; 1\\&lt;br /&gt;
    1 &amp;amp; -1&lt;br /&gt;
   \end{array}\end{pmatrix}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Представим пример высчитывания матриц Адамара:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
    H_{0} = 1,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
    H_{1} = H_{1} \otimes H_{0} = \begin{pmatrix}\begin{array}{rr}&lt;br /&gt;
    1 &amp;amp; 1\\&lt;br /&gt;
    1 &amp;amp; -1&lt;br /&gt;
   \end{array}\end{pmatrix} \otimes 1 = \begin{pmatrix}\begin{array}{rr}&lt;br /&gt;
    1 &amp;amp; 1\\&lt;br /&gt;
    1 &amp;amp; -1&lt;br /&gt;
   \end{array}\end{pmatrix},&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
    H_{2} = H_{1} \otimes H_{1} = \begin{pmatrix}\begin{array}{rr}&lt;br /&gt;
    1 &amp;amp; 1\\&lt;br /&gt;
    1 &amp;amp; -1&lt;br /&gt;
   \end{array}\end{pmatrix} \otimes \begin{pmatrix}\begin{array}{rr}&lt;br /&gt;
    1 &amp;amp; 1\\&lt;br /&gt;
    1 &amp;amp; -1&lt;br /&gt;
   \end{array}\end{pmatrix} =    \begin{pmatrix}\begin{array}{rrrr}&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp;  1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  1&lt;br /&gt;
    \end{array}\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
    H_{3} = H_{1} \otimes H_{2} = \begin{pmatrix}\begin{array}{rr}&lt;br /&gt;
    1 &amp;amp; 1\\&lt;br /&gt;
    1 &amp;amp; -1&lt;br /&gt;
   \end{array}\end{pmatrix} \otimes \begin{pmatrix}\begin{array}{rrrr}&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp;  1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  1&lt;br /&gt;
    \end{array}\end{pmatrix} =    \begin{pmatrix}\begin{array}{rrrrrrrr}&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp;  1 &amp;amp;  1 &amp;amp; 1 &amp;amp;  1 &amp;amp;  1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1 &amp;amp; 1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1 &amp;amp; 1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  1 &amp;amp; 1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1 &amp;amp; -1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp;  1 &amp;amp;  1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  -1 &amp;amp; -1 &amp;amp;  1 &amp;amp;  1 &amp;amp; -1\\&lt;br /&gt;
    \end{array}\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом, получаем последовательность матриц Адамамра размерностью &amp;lt;math&amp;gt;2^n&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H^{\otimes n} = H_1  \otimes ... \otimes H_1&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;H_{i,j} = (-1)^{\sum ij}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; - битовые представляения значений индексов, а &amp;lt;math&amp;gt;i j&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_{i,j} = (-1)^{\sum i  j}&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;
1. Определение индексов находимого элемента матрицы Адамара: &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2. Побитовое умножение индексов : &amp;lt;math&amp;gt;res = ij&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
3. Подсчет количества значащих единиц в &amp;lt;math&amp;gt;res&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;count = \sum res&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
4. Получение знака элемента по его четности: &amp;lt;math&amp;gt;sign = (-1)^{count}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Данному алгоритму соответствует приведенный ниже код на языке С++:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;lt;cmath&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
int get_sign(int i, int j) //Get sign Hadamard matrix&#039;s element by indices&lt;br /&gt;
{&lt;br /&gt;
    int res = i &amp;amp; j;&lt;br /&gt;
    int count;&lt;br /&gt;
    for (count=0; res; res&amp;gt;&amp;gt;=1) &lt;br /&gt;
        { &lt;br /&gt;
            if (res &amp;amp; 1)&lt;br /&gt;
                count++;&lt;br /&gt;
        }&lt;br /&gt;
    if (count &amp;amp; 1 ==1)&lt;br /&gt;
        return -1;&lt;br /&gt;
    else&lt;br /&gt;
        return 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int print_HadamardMatrix(int N) //print Hadamard matrix 2^n size&lt;br /&gt;
{&lt;br /&gt;
    int matr_size(pow(2,N));&lt;br /&gt;
    for (int i = 0; i &amp;lt; matr_size; i++)&lt;br /&gt;
    {&lt;br /&gt;
        for (int j = 0; j &amp;lt; matr_size; j++) &lt;br /&gt;
        {&lt;br /&gt;
&lt;br /&gt;
            if (get_sign(i,j)==1) &lt;br /&gt;
                    cout &amp;lt;&amp;lt;&amp;quot; 1 &amp;quot;;&lt;br /&gt;
            else &lt;br /&gt;
                    cout &amp;lt;&amp;lt;&amp;quot;-1 &amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        cout &amp;lt;&amp;lt; endl;&lt;br /&gt;
    }&lt;br /&gt;
    cout &amp;lt;&amp;lt; endl;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, const char * argv[]) &lt;br /&gt;
{&lt;br /&gt;
    if(argc!=2) &lt;br /&gt;
    {&lt;br /&gt;
        printf(&amp;quot;Matrix size missing\n&amp;quot;);&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int N(atoi(argv[1]));&lt;br /&gt;
    print_HadamardMatrix(N);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Построение матрицы Адамара порядка &amp;lt;math&amp;gt;N = 2^n&amp;lt;/math&amp;gt; требует:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;N^2&amp;lt;/math&amp;gt; побитовых умножений &amp;lt;math&amp;gt;ij&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Не детерменированное значение операций для каждого элемента на шаге вычисления значащих единиц.От 2 до &amp;lt;math&amp;gt;2N&amp;lt;/math&amp;gt; операций сдвига(и, соответственно, побитовых умножений с 1) на каждый элемент.&lt;br /&gt;
&lt;br /&gt;
3. &amp;lt;math&amp;gt;N^2&amp;lt;/math&amp;gt; побитовых умножений количества значащих единиц с 1 для определения четности числа&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
На рисунке ниже изображен информационный граф алгоритма. Всего возможно &amp;lt;math&amp;gt;(2^n)^2&amp;lt;/math&amp;gt; параллельных ветвей, так как каждый элемент матрицы может считаться независимо друг от друга.&lt;br /&gt;
[[File:GraphHamadard.jpg|thumb|center|800px|Рисунок 1. Граф алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
1. Побитовое умножение индексов.&amp;lt;math&amp;gt;ij&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; соответствующие координаты элемента &amp;lt;math&amp;gt;h_{kl}&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
2. Подсчет количества значащих единиц. Состоит из последовательных сдвигов и побитового &amp;quot;И&amp;quot; с 1.&lt;br /&gt;
&lt;br /&gt;
3. Определение четности количества - побитовое &amp;quot;И&amp;quot; количества значащих единиц с 1.&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения матрицы Адамара необходимы операции сдивга и побитового умножения. Расчет каждого элемента независим друг от друга, следовательно расчет каждого элемента будет являться параллельной ветвью. При расчете элемента все операции внутри параллельной ветви выполняются последовательно, ожидая окончания предыдущей.&lt;br /&gt;
&lt;br /&gt;
Основной вклад в высоту ярусно-параллельной формы вносит 2 шаг, осуществляющий подсчет количества значащих единиц.&lt;br /&gt;
&lt;br /&gt;
Ширина ярусно-параллельной формы будет равна &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: n - размерность матрицы &amp;lt;math&amp;gt;H_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: 1 (число n).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица Адамара &amp;lt;math&amp;gt;H_{n}&amp;lt;/math&amp;gt; размерностью &amp;lt;math&amp;gt;2^n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2^{n+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;
&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;
* [https://reference.wolframcloud.com/cloudplatform/ref/HadamardMatrix.html Wolfram]&lt;br /&gt;
* [https://www.mathworks.com/help/matlab/ref/hadamard.html?requestedDomain=www.mathworks.com MATLAB]&lt;br /&gt;
* [http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.linalg.hadamard.html SciPy]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
[1] Кронберг, Ю.И. Ожигов, А.Ю. Чернявский — Алгебраический аппарат квантовой информатики 2&lt;br /&gt;
&lt;br /&gt;
[2] Википедия – свободная энциклопедия [Электронный ресурс]. -  https://en.wikipedia.org/wiki/Hadamard_transform. - (дата обращения: 15.10.2016).&lt;/div&gt;</summary>
		<author><name>Sleo</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:%D0%91%D1%83%D0%B3%D0%B0%D0%BA%D0%BE%D0%B2_%D0%AE%D1%80%D0%B8%D0%B9&amp;diff=14162</id>
		<title>Обсуждение участника:Бугаков Юрий</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:%D0%91%D1%83%D0%B3%D0%B0%D0%BA%D0%BE%D0%B2_%D0%AE%D1%80%D0%B8%D0%B9&amp;diff=14162"/>
		<updated>2016-10-27T11:54:00Z</updated>

		<summary type="html">&lt;p&gt;Sleo: Новая страница: «Замечания к оформлению статьи:  1. в первой строке указать авторов и их вклад в статью.  2. в…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Замечания к оформлению статьи:&lt;br /&gt;
&lt;br /&gt;
1. в первой строке указать авторов и их вклад в статью.&lt;br /&gt;
&lt;br /&gt;
2. в пункте 1.6 перенесите Т(n) в одну строку с концом предложения.&lt;br /&gt;
&lt;br /&gt;
3. в пункте 1.9 указать чему соответствуют разные входные и выходные данные. Иначе непонятно будет человеку, который первый раз на сайте.&lt;br /&gt;
&lt;br /&gt;
4. в пункте 2.7 убрать многоточия или заменить их на другие реализации&lt;/div&gt;</summary>
		<author><name>Sleo</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:%D0%91%D1%83%D0%B3%D0%B0%D0%BA%D0%BE%D0%B2_%D0%AE%D1%80%D0%B8%D0%B9/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0_%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D1%80%D0%B0%D0%B7%D0%BC%D0%B5%D1%80%D0%BD%D0%BE%D1%81%D1%82%D0%B8&amp;diff=14161</id>
		<title>Участник:Бугаков Юрий/Построение матрицы Адамара произвольной размерности</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:%D0%91%D1%83%D0%B3%D0%B0%D0%BA%D0%BE%D0%B2_%D0%AE%D1%80%D0%B8%D0%B9/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0_%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D1%80%D0%B0%D0%B7%D0%BC%D0%B5%D1%80%D0%BD%D0%BE%D1%81%D1%82%D0%B8&amp;diff=14161"/>
		<updated>2016-10-27T11:53:52Z</updated>

		<summary type="html">&lt;p&gt;Sleo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Построение матрицы Адамара&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O( \left[ \frac{n}{4}\right]\,2^{2n})&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(2^{2n})&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;2^{2n}&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;
Важную роль в алгебре и комбинаторике играют матрицы Адамара, которые впервые были введены в математический обиход в конце прошлого века одним из крупнейших французских математиков [https://ru.wikipedia.org/wiki/%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80,_%D0%96%D0%B0%D0%BA Жаком Адамаром (1865-1963)]. Их применение в науке и технике посвящены тысячи публикаций. Они предоставляют эффективные возможности для организации хранения, обработки и передачи информации.&lt;br /&gt;
&lt;br /&gt;
Квадратная матрица Н порядка &#039;&#039;m&#039;&#039; с элементами ±1 называется матрицей Адамара, если выполняется условие&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt; H_m\,H_m^T = m\,E_m &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нетрудно заметить, что различные строки матрицы Адамара попарно ортогональны [1]. Также, можно увидеть из определения, что m четно и&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
H_{2m} =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
H_{m} &amp;amp;  H_{m}\\&lt;br /&gt;
H_{m} &amp;amp; -H_{m}\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
С матрицами Адамара связан ряд нерешенных проблем, одна из которых состоит в следующем. Мы уже видели, что порядок &#039;&#039;m&#039;&#039; матрицы Адамара при &#039;&#039;m&#039;&#039; ≥ 3 может быть лишь четным. Более того, при &#039;&#039;m&#039;&#039; ≥ 4 порядок обязан делиться на 4. До сих пор остается открытым вопрос: для любого ли &#039;&#039;m&#039;&#039;, кратного 4, существует матрица Адамара порядка m? Неизвестно, в частности, существует ли матрица Адамара порядка 268 (это наименьший порядок, кратный 4, для которого матрица Адамара еще не построена).&lt;br /&gt;
&lt;br /&gt;
Часто матрицу Адамара нормализуют и рассматривают размерности степени 2 (например [2],[3] и [4]). В дальнейшем будем рассматривать только такие случаи. Переопределим матрицу Адамара следующим образом:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Матрица Адамара &#039;&#039;H&#039;&#039;&amp;lt;sub&amp;gt;&#039;&#039;n&#039;&#039;&amp;lt;/sub&amp;gt;  - это матрица размера 2&amp;lt;sup&amp;gt;&#039;&#039;n&#039;&#039;&amp;lt;/sup&amp;gt;&amp;amp;nbsp;&amp;amp;times;&amp;amp;nbsp;2&amp;lt;sup&amp;gt;&#039;&#039;n&#039;&#039;&amp;lt;/sup&amp;gt;, для которой справедливо равенство&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;H_n = H_{1} \otimes H_{n-1}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
  H_1 = \frac{1}{\sqrt2}&lt;br /&gt;
   &amp;amp;\begin{pmatrix}\begin{array}{rr}&lt;br /&gt;
    1 &amp;amp; 1\\&lt;br /&gt;
    1 &amp;amp; -1&lt;br /&gt;
   \end{array}\end{pmatrix}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&#039;&#039;&#039;где &amp;lt;math&amp;gt; \otimes &amp;lt;/math&amp;gt; представляет собой [https://ru.wikipedia.org/wiki/%D0%A2%D0%B5%D0%BD%D0%B7%D0%BE%D1%80%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5 тензорное произведение].&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Представим некоторые частные примеры матриц Адамара:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
    H_0 = +1,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
  H_1 = \frac{1}{\sqrt2}&lt;br /&gt;
   \begin{pmatrix}\begin{array}{rr}&lt;br /&gt;
    1 &amp;amp; 1\\&lt;br /&gt;
    1 &amp;amp; -1&lt;br /&gt;
   \end{array}\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
  H_2 = \frac{1}{2}&lt;br /&gt;
   \begin{pmatrix}\begin{array}{rrrr}&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp;  1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  1&lt;br /&gt;
    \end{array}\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
  H_3 = \frac{1}{2^{\frac{3}{2}}}&lt;br /&gt;
   \begin{pmatrix}\begin{array}{rrrrrrrr}&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp;  1 &amp;amp;  1 &amp;amp; 1 &amp;amp;  1 &amp;amp;  1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1 &amp;amp; 1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1 &amp;amp; 1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  1 &amp;amp; 1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1 &amp;amp; -1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp;  1 &amp;amp;  1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  -1 &amp;amp; -1 &amp;amp;  1 &amp;amp;  1 &amp;amp; -1\\&lt;br /&gt;
    \end{array}\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;H_n&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;2^n\times 2^n&amp;lt;/math&amp;gt; можно вычислить поэлементно ([3], [4]):&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;h_{k,l} = \frac{1}{2^\frac{n}{2}} (-1)^{\sum_j k_j l_j}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
где &#039;&#039;k&#039;&#039;&amp;lt;sub&amp;gt;&#039;&#039;j&#039;&#039;&amp;lt;/sub&amp;gt; и &#039;&#039;l&#039;&#039;&amp;lt;sub&amp;gt;&#039;&#039;j&#039;&#039;&amp;lt;/sub&amp;gt; коэффициенты двоичного разложения чисел &#039;&#039;k&#039;&#039; и &#039;&#039;l&#039;&#039; (1 или 0):&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;k = \sum^{n}_{i=0} {k_i 2^i} = k_{n} 2^{n} + k_{n-1} 2^{n-1} + \cdots + k_1 2 + k_0&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
и&lt;br /&gt;
: &amp;lt;math&amp;gt;l = \sum^{n}_{i=0} {l_i 2^i} = l_{n} 2^{n} + l_{n-1} 2^{n-1} + \cdots + l_1 2 + l_0&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_{k,l} = \frac{1}{2^\frac{n}{2}} (-1)^{\sum_j k_j l_j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Основную часть метода составляют вычисления значений степени -1 для каждого элемента:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;\sum_{j=0}^n k_j l_j&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Как видно по формуле, получаемое значение равна количеству единиц в двоичной записи результата побитового умножения &#039;&#039;k&#039;&#039; и &#039;&#039;l&#039;&#039;. Существует эффективный метод вычисления количества единиц , сложность которого равна &#039;&#039;m&#039;&#039; операций вычитания и &#039;&#039;m&#039;&#039; операций побитового умножения, где &#039;&#039;m&#039;&#039;-искомое количество единиц.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
&lt;br /&gt;
1. Побитовое умножение &amp;lt;math&amp;gt;k\&amp;amp;l&amp;lt;/math&amp;gt;;  &lt;br /&gt;
&lt;br /&gt;
2. Вычисление количества единиц двоичной записи;&lt;br /&gt;
&lt;br /&gt;
3. Определение знака элемента по степени.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения матрицы Адамара порядка &amp;lt;math&amp;gt;N=2^n&amp;lt;/math&amp;gt; в первом шаге потребуется &amp;lt;math&amp;gt;N^2&amp;lt;/math&amp;gt; побитовых умножений &#039;&#039;k&amp;amp;l&#039;&#039;.&lt;br /&gt;
Во втором шаге, как говорилось выше, сложность метода вычисления количества единиц  числа в двоичном представлении равна удвоенному количеству единиц. В наихудшем случае сложность равна &amp;lt;math&amp;gt;2log_2N&amp;lt;/math&amp;gt;, при &#039;&#039;k=l=N-1&#039;&#039;, а в наилучшем 0. Для нахождения  степени всех элементов матрицы потребуются &amp;lt;math&amp;gt; 2N^2\left[\frac{log_2N}{4}\right]&amp;lt;/math&amp;gt; операций. В третьем шаге для определения знака потребуется &amp;lt;math&amp;gt;N^2&amp;lt;/math&amp;gt; операций, то есть сложность алгоритма&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
T(n) = 2\,(1+\left[\frac{n}{4}\right])\,2^{2n}.&lt;br /&gt;
&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;k\&amp;amp;l&amp;lt;/math&amp;gt; - операция побитового умножения, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt; соответствующие координаты элемента &amp;lt;math&amp;gt;h_{kl}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* OP - вычисление количества единиц числа в двоичной системе. Состоит из последовательного применения операций вычитания и побитового умножения;&lt;br /&gt;
* SGN - определение знака соответствующего элемента. Если результат предыдущего шага четное, то знак положительный, иначе отрицательный.  &lt;br /&gt;
&lt;br /&gt;
[[file:Hadamar.png|thumb|center|1400px|Рисунок 1. Граф алгоритма.]]&lt;br /&gt;
[[file:OP3.png|thumb|center|1400px|Рисунок 2. Граф OP.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения матрицы порядка &amp;lt;math&amp;gt;N=2^n&amp;lt;/math&amp;gt; требуется последовательно выполнить следующие шаги:&lt;br /&gt;
* &amp;lt;math&amp;gt;N^2&amp;lt;/math&amp;gt;  вычислений побитового умножения,&lt;br /&gt;
* для каждого элемента от &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; операций вычитания и побитового умножения, в зависимости от результата предыдущего шага,&lt;br /&gt;
* &amp;lt;math&amp;gt;N^2&amp;lt;/math&amp;gt;  для определения знака значения элемента.&lt;br /&gt;
 &lt;br /&gt;
Таким образом для построения необходимы лишь простые операции вычитания и побитового умножения выполняемые с целыми положительными числами. Стоит заметить что вычисления для каждого элемента не зависят друг от друга. Также можно воспользоваться либо симметричностью матрицы Адамара либо закономерностью областей показанная в пункте 1.1.&lt;br /&gt;
Таким образом, основной вклад в высотe ЯПФ вносит операция вычисления количества единиц. Ширина ЯПФ будет равна &amp;lt;math&amp;gt;O(2^{2n})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: n - размерность матрицы &amp;lt;math&amp;gt;H_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: 1 (число n).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица Адамара &amp;lt;math&amp;gt;H_n&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;2^n\times 2^n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2^{2n}&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;P\in \mathbb{N}&amp;lt;/math&amp;gt;. Считается, что каждый процесс &#039;&#039;P&#039;&#039; обрабатывает не более чем &amp;lt;math&amp;gt;\left[\frac{2^{2n}}{P}\right]\geq 1&amp;lt;/math&amp;gt; элементов. Тогда качественная формула может быть записана таким образом:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;T(n,P)=2\,(1+\left[ \frac{n}{4} \right])\,\frac{2^{2n}}{P}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Неравенство &amp;lt;math&amp;gt;\left[\frac{2^{2n}}{P}\right]\geq 1&amp;lt;/math&amp;gt; можно переписать, как &amp;lt;math&amp;gt;log_2\,\sqrt{P}\leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Легко увидеть, что минимум функции &#039;&#039;T(n,P)&#039;&#039; будет при максимально возможном &#039;&#039;P&#039;&#039; : &amp;lt;math&amp;gt;log_2\,\sqrt{P}\leq n&amp;lt;/math&amp;gt;. Такое &#039;&#039;P&#039;&#039; будет оптимальным числом процессов для алгоритма. В частности, для &amp;lt;math&amp;gt;P=2^p,\,p\in\mathbb{N}&amp;lt;/math&amp;gt; оптимальное &amp;lt;math&amp;gt;P = 2^{2n}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:&amp;lt;math&amp;gt;\frac{T(n)}{T(n,P)}=P&amp;lt;/math&amp;gt;.&lt;br /&gt;
то есть, отношение последовательной и параллельной сложности будет &#039;&#039;линейно&#039;&#039; зависеть от &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;Вычислительная мощность&#039;&#039; алгоритма построения матрицы Адамара, как отношение числа операций к суммарному объему входных и выходных данных: &lt;br /&gt;
:&amp;lt;math&amp;gt;\,\frac{2^{2n}(2+[\frac{n}{4}])}{1+2^{2n}}\left( \sim [\frac{n}{4}],\,n\to+\infty \right)&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* Алгоритм построения матрицы Адамара является &#039;&#039;не детерминированным&#039;&#039;, так как число операций меняется в зависимости от входных данных (числа n, которое формирует матрицу размера 2&amp;lt;sup&amp;gt;&#039;&#039;n&#039;&#039;&amp;lt;/sup&amp;gt;&amp;amp;nbsp;&amp;amp;times;&amp;amp;nbsp;2&amp;lt;sup&amp;gt;&#039;&#039;n&#039;&#039;&amp;lt;/sup&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
* Степень исхода вершины информационного графа равна 1;&lt;br /&gt;
&lt;br /&gt;
* Алгоритм построения матрицы Адамара является &#039;&#039;сбалансированным&#039;&#039;. Так как количество вершин на разных процессорах одинаково, то алгоритм является сбалансированным по числу операций на каждом процессоре.&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;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void adamar(int** H, int n) // N = 2^n - размерность матрицы&lt;br /&gt;
{     &lt;br /&gt;
    int i,j,N;&lt;br /&gt;
    float h;&lt;br /&gt;
    h = pow(1/2,n/2); // h - нормализующий множитель&lt;br /&gt;
    N = pow(2,n);&lt;br /&gt;
&lt;br /&gt;
    for(i=0;i&amp;lt;N;++i) &lt;br /&gt;
    {&lt;br /&gt;
	for(j=0;j&amp;lt;N;++j)&lt;br /&gt;
	{&lt;br /&gt;
		ij = i &amp;amp; j;&lt;br /&gt;
    		for (l=0;ij;++l) ij&amp;amp;=ij-1; // l - количество единиц бинарного представления ij&lt;br /&gt;
		if(l%2==0) H[i][j] = h;&lt;br /&gt;
		else H[i][j] = -h;&lt;br /&gt;
	}&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Также существует рекурсивная реализация метода построения матрицы Адамара&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void adamar_recursion(int** H, int N, int i, int j, int h) // h - нормализующий множитель&lt;br /&gt;
{&lt;br /&gt;
    if(n==1) H[i][j] = h;&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        adamar(H, N/2, i, j, h);&lt;br /&gt;
        adamar(H, N/2, i, N/2+j, h);&lt;br /&gt;
        adamar(H, N/2, N/2+i, j, h);&lt;br /&gt;
        adamar(H, N/2, N/2+i, N/2+j, -h);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Или эквивалентный безрекурсивный вариант:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void adamar_not_recursion(int** H, int n) // N = 2^n - размерность матрицы&lt;br /&gt;
{     &lt;br /&gt;
    int i,j,N;&lt;br /&gt;
    float h;&lt;br /&gt;
    h = pow(1/2,n/2);&lt;br /&gt;
    N = pow(2,n);&lt;br /&gt;
    k=2;&lt;br /&gt;
    H[0][0] = h;&lt;br /&gt;
	&lt;br /&gt;
    while(k&amp;lt;=N)&lt;br /&gt;
    {&lt;br /&gt;
	for (i=0; i&amp;lt;k; ++i)&lt;br /&gt;
	{&lt;br /&gt;
		for (j=0; j&amp;lt;k; ++j)&lt;br /&gt;
		{&lt;br /&gt;
			if (i&amp;lt;k/2 &amp;amp;&amp;amp; j&amp;lt;k/2)&lt;br /&gt;
			{&lt;br /&gt;
			}&lt;br /&gt;
			else&lt;br /&gt;
			{&lt;br /&gt;
				if(i&amp;gt;=k/2 &amp;amp;&amp;amp; j&amp;gt;=k/2)&lt;br /&gt;
				{&lt;br /&gt;
					H[i][j] = -(H[i-k/2][j-k/2]);&lt;br /&gt;
				}&lt;br /&gt;
				else&lt;br /&gt;
				{&lt;br /&gt;
					if (i&amp;gt;j)&lt;br /&gt;
					{&lt;br /&gt;
						H[i][j] = H[i-k/2][j];&lt;br /&gt;
					}&lt;br /&gt;
					else&lt;br /&gt;
					{&lt;br /&gt;
						H[i][j] = H[i][j-k/2];&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
		&lt;br /&gt;
        k=k*2;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для данного случая, рекурсия является менее эффективной для генерации матрицы Адамара ([https://habrahabr.ru/post/256351/ Хабрахабр. О бедной рекурсии замолвите слово, или всё, что вы не знали и не хотите о ней знать.]). С точки зрения последовательной реализации, генерация матрицы Адамара с помощью adamar_not_recursion будет выигрывать у adamar, так как adamar_not_recursion будет выполнять меньшее количество операций. С точки зрения параллельной реализации adamar имеет 100% парализацию и при определенных условиях будет выигрывать по времени у распараллелинной adamar_not_recursion (пусть в adamar и будет выполняться большее количество операций, но они являются [https://ru.wikipedia.org/wiki/%D0%91%D0%B8%D1%82%D0%BE%D0%B2%D1%8B%D0%B5_%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%B8 битовыми операциями]).&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
Задача данного раздела - показать пределы [[глоссарий#Масштабируемость|&#039;&#039;масштабируемости&#039;&#039;]] алгоритма на различных платформах. Очень важный раздел. Нужно выделить, описать и оценить влияние точек барьерной синхронизации, глобальных операций, операций сборки/разборки данных, привести оценки или провести исследование [[глоссарий#Сильная масштабируемость|&#039;&#039;сильной&#039;&#039;]] и [[глоссарий#Слабая масштабируемость|&#039;&#039;слабой&#039;&#039;]] масштабируемости алгоритма и его реализаций.&lt;br /&gt;
&lt;br /&gt;
Масштабируемость алгоритма определяет свойства самого алгоритма безотносительно конкретных особенностей используемого компьютера. Она показывает, насколько параллельные свойства алгоритма позволяют использовать возможности растущего числа процессорных элементов. Масштабируемость параллельных программ определяется как относительно конкретного компьютера, так и относительно используемой технологии программирования, и в этом случае она показывает, насколько может вырасти реальная производительность данного компьютера на данной программе, записанной с помощью данной технологии программирования, при использовании бóльших вычислительных ресурсов (ядер, процессоров, вычислительных узлов).&lt;br /&gt;
&lt;br /&gt;
Ключевой момент данного раздела заключается в том, чтобы показать &#039;&#039;реальные параметры масштабируемости программы&#039;&#039; для данного алгоритма на различных вычислительных платформах в зависимости от числа процессоров и размера задачи  [4]. При этом важно подобрать такое соотношение между числом процессоров и размером задачи, чтобы отразить все характерные точки в поведении параллельной программы, в частности, достижение максимальной производительности, а также тонкие эффекты, возникающие, например, из-за блочной структуры алгоритма или иерархии памяти.&lt;br /&gt;
&lt;br /&gt;
На рис.5. показана масштабируемость классического алгоритма умножения плотных матриц в зависимости от числа процессоров и размера задачи. На графике хорошо видны области с большей производительностью, отвечающие уровням кэш-памяти.&lt;br /&gt;
[[file:Масштабируемость перемножения матриц производительность.png|thumb|center|700px|Рис.5 Масштабируемость классического алгоритма умножения плотных матриц в зависимости от числа процессоров и размера задачи]]&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;
# [http://www.exponenta.ru/soft/matlab/potemkin/book2/chapter5/hadamard.asp MATLAB];&lt;br /&gt;
# [https://reference.wolfram.com/language/ref/HadamardMatrix.html WOLFRAM];&lt;br /&gt;
# [http://pydoc.net/Python/rogues/0.3.0/rogues.matrices.hadamard/ Python];&lt;br /&gt;
# [http://www.obihiro.ac.jp/~suzukim/masuda/octave/html3/octave_97.html Octave];&lt;br /&gt;
# ...&lt;br /&gt;
&lt;br /&gt;
Стоит отметить, что во многих вычислительных пакетах встроена операция тензорного произведения матриц, которая позволяет строить матрицу Адамара по определению. Этот факт позволяет использовать матрицу Адамара в этих вычислительных пакетах: &lt;br /&gt;
# [https://ru.wikipedia.org/wiki/Maple MAPLE];&lt;br /&gt;
# [https://ru.wikipedia.org/wiki/Mathcad MATCATH]; &lt;br /&gt;
# ...&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
[1] Мак-Вильямс Ф.Дж., Слоэн Н.Дж.А. Теория кодов, исправляющих ошибки: Пер. с англ. — М: Связь, 1979. — 744 с.&lt;br /&gt;
&lt;br /&gt;
[2] Кронберг, Ю.И. Ожигов, А.Ю. Чернявский — Алгебраический аппарат квантовой информатики 2&lt;br /&gt;
&lt;br /&gt;
[3] Kunz H.O.. On the Equivalence Between One-Dimensional Discrete Walsh-Hadamard and Multidimensional Discrete Fourier Transforms. IEEE Transactions on Computers. 28 (3): 267–8. [https://en.wikipedia.org/wiki/Digital_object_identifier doi]:[http://ieeexplore.ieee.org/document/1675334/ 10.1109/TC.1979.1675334]&lt;br /&gt;
&lt;br /&gt;
[4] Википедия – свободная энциклопедия [Электронный ресурс]. -  https://en.wikipedia.org/wiki/Hadamard_transform. - (дата обращения: 15.10.2016).&lt;br /&gt;
&lt;br /&gt;
[5] Воеводин В.В.. Воеводин Вл.В. Параллельные вычисления. - СПб.: БХВ-Петербург, 2002. - 608 с.&lt;br /&gt;
&lt;br /&gt;
[6] Воронцов К.В.. Математические методы обучения по прецедентам (теория обучения машин)&lt;/div&gt;</summary>
		<author><name>Sleo</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:%D0%A0%D1%83%D1%81%D0%BB%D0%B0%D0%BD&amp;diff=14159</id>
		<title>Обсуждение участника:Руслан</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:%D0%A0%D1%83%D1%81%D0%BB%D0%B0%D0%BD&amp;diff=14159"/>
		<updated>2016-10-27T11:30:01Z</updated>

		<summary type="html">&lt;p&gt;Sleo: Новая страница: «Замечания к оформлению статьи:  0. Укажите свои ФИО, номер группы.  1. В начале статьи должн…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Замечания к оформлению статьи:&lt;br /&gt;
&lt;br /&gt;
0. Укажите свои ФИО, номер группы.&lt;br /&gt;
&lt;br /&gt;
1. В начале статьи должна быть таблица со следующей информацией (Последовательная сложность, Объём входных данных, Объём выходных данных, Высота ярусно-параллельной формы, Ширина ярусно-параллельной формы).&lt;br /&gt;
&lt;br /&gt;
2. В пункте 1.7 должен быть понятный и наглядный рисунок информационного графа (&#039;&#039;&#039;ациклический&#039;&#039;&#039; граф, вершины - операции, дуги - информационные зависимости). (см. пример: https://algowiki-project.org/ru/%D0%A0%D0%B0%D0%B7%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%A5%D0%BE%D0%BB%D0%B5%D1%86%D0%BA%D0%BE%D0%B3%D0%BE_(%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D0%BA%D0%B2%D0%B0%D0%B4%D1%80%D0%B0%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BA%D0%BE%D1%80%D0%BD%D1%8F)&lt;br /&gt;
&lt;br /&gt;
3. Вычислительная мощность не приведена. (см. пример: https://algowiki-project.org/ru/%D0%A0%D0%B0%D0%B7%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%A5%D0%BE%D0%BB%D0%B5%D1%86%D0%BA%D0%BE%D0%B3%D0%BE_(%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D0%BA%D0%B2%D0%B0%D0%B4%D1%80%D0%B0%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BA%D0%BE%D1%80%D0%BD%D1%8F)&lt;br /&gt;
&lt;br /&gt;
4. В пункте 1.1 не приведено ни одного свойства алгоритма.&lt;br /&gt;
&lt;br /&gt;
5. Пункт 1.3 стоит расписать подробнее. Например, привести основные операции, которые применяются выч. ядре алгоритма. Описать, почему как использование специального вида деревьев улучшает алгоритм.&lt;/div&gt;</summary>
		<author><name>Sleo</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:%D0%A0%D1%83%D1%81%D0%BB%D0%B0%D0%BD/%D0%9F%D0%BB%D0%BE%D1%82%D0%BD%D0%BE%D1%81%D1%82%D0%BD%D1%8B%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8&amp;diff=14158</id>
		<title>Участник:Руслан/Плотностный алгоритм кластеризации</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:%D0%A0%D1%83%D1%81%D0%BB%D0%B0%D0%BD/%D0%9F%D0%BB%D0%BE%D1%82%D0%BD%D0%BE%D1%81%D1%82%D0%BD%D1%8B%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8&amp;diff=14158"/>
		<updated>2016-10-27T11:19:56Z</updated>

		<summary type="html">&lt;p&gt;Sleo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
Алгоритм &#039;&#039;&#039;DBSCAN (Density Based Spatial Clustering of Applications with Noise)&#039;&#039;&#039; -  плотностный алгоритм для кластеризации пространственных данных с присутствием шума), был предложен Мартином Эстер, Гансом-Питером Кригель и коллегами в 1996 году как решение проблемы разбиения (изначально пространственных) данных на кластеры произвольной формы. Большинство алгоритмов, производящих плоское разбиение, создают кластеры по форме близкие к сферическим, так как минимизируют расстояние до центра кластера. Авторы DBSCAN экспериментально показали, что их алгоритм способен распознать кластеры различной формы.&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритма =&lt;br /&gt;
Кластеризация – это процесс разбиения множества элементов на непересекающиеся кластеры, так, чтобы в каждом кластере все элементы были схожи в каком-то смысле, а объекты разных кластеров существенно отличались.&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Идея, положенная в основу алгоритма, заключается в том, что внутри каждого кластера наблюдается типичная плотность точек (объектов), которая заметно выше, чем плотность снаружи кластера, а также плотность в областях с шумом ниже плотности любого из кластеров. Ещё точнее, что для каждой точки кластера её соседство заданного радиуса должно содержать не менее некоторого числа точек, это число точек задаётся пороговым значением. Алгоритм DBSCAN для заданных значений параметров &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и MinPts исследует кластер следующим образом: сначала выбирает случайную точку, являющуюся ядровой, в качестве затравки, затем помещает в кластер саму затравку и все точки, плотно-достижимые из неё.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Исходные данные: объекты, которые нужно кластеризовать, параметры &amp;lt;math&amp;gt;MinPts, \ \varepsilon&amp;lt;/math&amp;gt; . Между объектами можно считать расстояния.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: разбиение объектов по кластерам. Количество кластеров зависит от исходных данных.&lt;br /&gt;
&lt;br /&gt;
Для построения оценки плотности, на основе соседства точек вводятся понятия достижимости и связности. Под &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; -соседями точки &amp;lt;math&amp;gt;x \in X&amp;lt;/math&amp;gt; понимается множество точек, расстояние до которых не превышает &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; , т. е. &amp;lt;math&amp;gt;N_\varepsilon (x) = \{y \in X | D(x, y) \le \varepsilon\}.&amp;lt;/math&amp;gt; Тогда точка y достижима из точки &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, если существует последовательность точек &amp;lt;math&amp;gt;x^{(1)}=x, x^{(2)},... , x^{(p-1)}, x^{(p)}=y&amp;lt;/math&amp;gt;, для которой выполнено:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
x^{(i+1)} \in N_\varepsilon (x^{(i)}), i=1,... ,p-1 \\&lt;br /&gt;
\mid N_\varepsilon (x^{(i)}) \mid \ge MinPts, i=1,... ,p-1&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здесь значение &amp;lt;math&amp;gt;MinPts&amp;lt;/math&amp;gt; задаётся пользователем и регулирует порог «шума». Согласно второму условию, у точек, находящихся внутри кластера, должно быть не менее &amp;lt;math&amp;gt;MinPts \ \varepsilon&amp;lt;/math&amp;gt; -соседей. Такие точки называются «ядрами». Остальные точки разделяются на граничные (имеющие менее &amp;lt;math&amp;gt;MinPts \ \varepsilon&amp;lt;/math&amp;gt; -cоседей, но достижимые из какого-либо «ядра») и шумовые. Две точки связны, если существует «ядро», из которого они обе достижимы. При такой постановке задачи, под кластером понимается максимальное связное подмножество множества X . Точки, не попавшие в какой-либо кластер (не принадлежащие &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; -окрестности какого-либо «ядра»), относятся к классу «шум».&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательной версии зависти от поиска всех точек в &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-окрестности конкретной точки. Из-за поиска &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседства алгоритм имеет квадратичную вычислительную сложность &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; (где n - количество точек). Но если задействовать K-мерное дерево, то можно снизить сложность до &amp;lt;math&amp;gt;O(\text{n log n})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм DBSCAN использует пространственную структуру данных для определения соседних объектов. Это может быть R*-дерево или k-d дерево. Такие структуры данных позволяют найти все объекты в пределах определенного расстояния от текущего объекта. Также для построения этих деревьев нужно уметь находить расстояние между объектами &amp;lt;math&amp;gt;\rho(u, v)&amp;lt;/math&amp;gt; , в, это расстояние можно вводить разными способами. Например, если &amp;lt;math&amp;gt;\rho(u,v)&amp;lt;/math&amp;gt; - метрика в евклидовом пространстве, &amp;lt;math&amp;gt;u=(u_1,...,u_n)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(v_1,...,v_n)&amp;lt;/math&amp;gt;, то расстояние вычисляется следующим образом: &amp;lt;math&amp;gt;\rho(u,v)=\sqrt{(u_1-v_1)^2+(u_2-v_2)^2+...+(u_n-v_n)^2} = \sqrt{\sum_{k=1}^n(u_k-v_k)^2}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм начинает работу с произвольной точки &amp;lt;math&amp;gt;x \in X&amp;lt;/math&amp;gt; и возвращает &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; -окрестность(строка 4). Если &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-окрестность содержит, как минимум minpts точек, процедура выдает новый кластер C. Алгоритм извлекает все точки в X, которые являются плотность достижима из x и добавляет их в кластер C(строки 8-17). Если в &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-окрестности x точек меньше, чем minpts, то x помечается как шум(строка 6). Однако, х все еще может быть добавлены в кластер, если она определится как пограничная точка во время изучения других основных точек(строки 16-17). Поиск точек в &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-окрестности(функция GETNEIGHBORS)известен, как запрос в диапазоне значений и получает все плотностно достижимые точки от главной точки(строки 8-17) известный как алгоритм наращивания областей. Заметим что кластер может быть определен однозначно, начиная с любой &amp;quot;ядровой&amp;quot; точки.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    1: procedure DBSCAN(X, eps, minpts)&lt;br /&gt;
    2:     for each unvisited point x ∈ X do&lt;br /&gt;
    3:         mark x as visited&lt;br /&gt;
    4:         N ← GETNEIGHBORS(x, eps)&lt;br /&gt;
    5:         if |N| &amp;lt; minpts then&lt;br /&gt;
    6:             mark x as noise&lt;br /&gt;
    7:         else&lt;br /&gt;
    8:             C ← {x}&lt;br /&gt;
    9:             for each point x&#039; ∈ N do&lt;br /&gt;
    10:                N ← N \ x&#039;&lt;br /&gt;
    11:                if x&#039; is not visited then&lt;br /&gt;
    12:                    mark x&#039; as visited&lt;br /&gt;
    13:                    N&#039; ← GETNEIGHBORS(x&#039;, eps)&lt;br /&gt;
    14:                    if |N&#039;| ≥ minpts then&lt;br /&gt;
    15:                        N ← N ∪ N&#039;&lt;br /&gt;
    16:                if x&#039; is not yet member of any cluster then&lt;br /&gt;
    17:                    C ← C ∪ {x&#039;}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
В общем случае алгоритм DBSCAN имеет квадратичную вычислительную сложность &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;(где n это количество точек в X) из-за поиска &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседства. Но если использовать пространственную индексацию (например, использую k-мерное дерево[5] или R-дерево) для поиска &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседства, сложность снижается до &amp;lt;math&amp;gt;O(n log n)&amp;lt;/math&amp;gt;[6].&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
На рисунке 1 представлен информационный граф алгоритма кластеризации DBSCAN. На входе у нас множество точек &amp;lt;math&amp;gt;P_i&amp;lt;/math&amp;gt; и мы пробегаем по всем непосещенным точкам. Далее мы, для каждой непосещенной точки, маркируем ее как посещенную и находим всех её &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей(на графике это узел &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;). Добавляем точку к кластеру(узел &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;). Затем, пробегаем по всем плотностно-достижимых точках(&amp;lt;math&amp;gt;P_j&amp;lt;/math&amp;gt;) к нашей точке, и для каждой такой точки ищем &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-сосдей и добавляем их в кластер, если они ещё не принадлежат никакому кластеру.&lt;br /&gt;
&lt;br /&gt;
[[file:Информационный_граф.png|thumb|center|700px|Рис.1  Граф алгоритма без отображения входных и выходных данных. &amp;lt;math&amp;gt;P_i&amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt;P_j&amp;lt;/math&amp;gt; - точки данного множества, &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt; - поиск &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - добавление элемента к кластеру.]]&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Поиск &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей требует вычисления n расстояний и выполнения n сравнений с &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Эти операции для каждой пары точек независимы и могут быть выполнены параллельно. Таким образом, при наличии неограниченного числа процессоров сложность поиска составит O(1). Так как поиск выполняется для каждой точки ровно один раз, параллельная сложность всего алгоритма составит O(n).&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Входные данные: набор точек x, пороговое расстояние &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;, а также минимальное количество точек, необходимых для формирования кластера, minpts.&lt;br /&gt;
&lt;br /&gt;
Выход: множество кластеров С.&lt;br /&gt;
&lt;br /&gt;
Если указать маленькое значение &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;, то все точки будут шумом. Если наоборот, сделать большое значение, то кластер не будет разбит, возьмет один кластер и включит в него все точки. Также, если взять minpts слишком большое или слишком маленькое, будет либо один кластер, либо все точки шумовые. Оптимальные значения находятся опытным путем.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
Соотношение последовательной и параллельной сложностей алгоритма является линейным (отношение квадратичной к линейной). При этом вычислительная мощность, как отношение числа операций к суммарному объему входных и выходных данных линейна.&lt;br /&gt;
&lt;br /&gt;
=== Преимущества алгоритма ===&lt;br /&gt;
* не требует указать априори количество кластеров, в отличие от K-средства&lt;br /&gt;
&lt;br /&gt;
* алгоритм может разбить на произвольной формы кластеры. Даже может выявить кластер находящийся внутри другого, но не пересекающийся с ним. Из-за параметра MinPts снижается так называемый эффект однолокальности(single-link)&lt;br /&gt;
&lt;br /&gt;
* алгоритм имеет понятие &amp;quot;шума&amp;quot; и устойчив к выбросам&lt;br /&gt;
&lt;br /&gt;
* алгоритм требует всего два параметра и в основном нечувствительны к упорядоченности изначально данных точек&lt;br /&gt;
&lt;br /&gt;
* параметры MinPts и &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; могут быть установлены, экспертами в какой-либо области, если данные хорошо изучены.&lt;br /&gt;
&lt;br /&gt;
=== Недостатки алгоритма ===&lt;br /&gt;
&lt;br /&gt;
* алгоритм не совсем детерминирован: пограничные точки, которые доступны из более чем одного кластера могут быть частью любого кластера, в зависимости от того, как происходит обработка данных. К счастью, эта ситуация не часто возникают, и мало влияет на результат кластеризации. На основных точках и точках &amp;quot;шума&amp;quot;, алгоритм детерминирован. Есть DBSCAN[7] который представляет собой вариант, который рассматривает пограничные пункты как шум, и таким образом достигается полностью детерминированный результат, а также более последовательной статистической интерпретации плотности соединенных компонентов.&lt;br /&gt;
&lt;br /&gt;
* качество алогоритма зависит от меры, которую мы рассматриваем в пространстве. Наиболее распространенная мера использует евклидово расстояние. &lt;br /&gt;
 &lt;br /&gt;
* если данные и масштаб не очень хорошо поняты, выбирание значимого расстояния порогового &amp;lt;math&amp;gt;\varepsilon&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;span class=&amp;quot;plainlinks&amp;quot;&amp;gt;[//en.wikipedia.org/wiki/ELKI ELKI]&amp;lt;/span&amp;gt; предлагает реализацию DBSCAN, а также GDBSCAN и другие варианты. Эта реализация может использовать различные структуры индексов для поквадратного выполнения и поддерживает произвольное расстояние функции и произвольные типы данных, но это можно обогнать низкоуровневой оптимизацией реализации на небольших наборах данных.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class=&amp;quot;plainlinks&amp;quot;&amp;gt;[//en.wikipedia.org/wiki/Scikit-learn Scikit-Learn]&amp;lt;/span&amp;gt; включает в себя реализацию Python для DBSCAN для произвольной метрики Минковского, который может быть ускорен с помощью KD-деревьев и шаровых деревьев, но который использует в худшем случае квадратичную память.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class=&amp;quot;plainlinks&amp;quot;&amp;gt;[//en.wikipedia.org/wiki/R_(programming_language) GNU R]&amp;lt;/span&amp;gt; содержит DBSCAN в [//cran.r-project.org/web/packages/fpc/index.html fpc] пакете с поддержкой произвольных функций расстояния через матриц. Однако он не имеет поддержки индекса (и, соответственно, имеет квадратичное время выполнения и сложность по памяти) и довольно медленно из-за интерпретации R. Более быстрая версия реализована на языке C++ с использованием KD-деревьев (только когда расстояние Евклидово ) в пакете R [//cran.r-project.org/web/packages/dbscan/index.html dbscan].&lt;br /&gt;
&lt;br /&gt;
[//www.philippe-fournier-viger.com/spmf/SPMF SPMF] предлагает GPL-V3 java-реализацию алгоритма DBSCAN с поддержкой KD-дерева (только для параметра расстояние Евклида).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class=&amp;quot;plainlinks&amp;quot;&amp;gt;[//en.wikipedia.org/wiki/Weka_(machine_learning) Weka]&amp;lt;/span&amp;gt; содержит (как дополнительный пакет в последних версиях) базовую реализацию DBSCAN, которая работает за квадратичное время и линейную память.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class=&amp;quot;plainlinks&amp;quot;&amp;gt;[//en.wikipedia.org/wiki/Apache_Commons Apache Commons Мath]&amp;lt;/span&amp;gt; содержит java-реализацию алгоритма выполняющегося за квадратичное время.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&lt;br /&gt;
* Ester, Martin, et al. &amp;quot;A density-based algorithm for discovering clusters in large spatial databases with noise.&amp;quot; Kdd. Vol. 96. No. 34. 1996.&lt;br /&gt;
&lt;br /&gt;
* Воеводин В.В. Математические основы параллельных вычислений// М.: Изд. Моск. ун-та, 1991. 345 с.&lt;br /&gt;
&lt;br /&gt;
* Воеводин В.В., Воеводин Вл.В. Параллельные вычисления. – СПб.: БХВ - Петербург, 2002. – 608 с.&lt;br /&gt;
&lt;br /&gt;
* Фролов А.В.. Принципы построения и описание языка Сигма. Препринт ОВМ АН N 236. М.: ОВМ АН СССР, 1989.&lt;br /&gt;
&lt;br /&gt;
* A. Zhou, S. Zhou, J. Cao, Y. Fan, and Y. Hu, “Approaches for scaling DBSCAN algorithm to large spatial databases,” Journal of computer science and technology, vol. 15, no. 6, pp. 509–526, 2000.&lt;br /&gt;
&lt;br /&gt;
*J. Bentley, “Multidimensional binary search trees used for associative searching,” Communications of the ACM, vol. 18, no. 9, pp. 509–517, 1975.&lt;br /&gt;
&lt;br /&gt;
*Campello, R. J. G. B.; Moulavi, D.; Sander, J. (2013). Density-Based Clustering Based on Hierarchical Density Estimates. Proceedings of the 17th Pacific-Asia Conference on Knowledge Discovery in Databases, PAKDD 2013. Lecture Notes in Computer Science. p. 160.&lt;/div&gt;</summary>
		<author><name>Sleo</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:Igor.orpanen/%D0%9F%D0%BB%D0%BE%D1%82%D0%BD%D0%BE%D1%81%D1%82%D0%BD%D1%8B%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_(DBSCAN)&amp;diff=14157</id>
		<title>Участник:Igor.orpanen/Плотностный алгоритм кластеризации (DBSCAN)</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:Igor.orpanen/%D0%9F%D0%BB%D0%BE%D1%82%D0%BD%D0%BE%D1%81%D1%82%D0%BD%D1%8B%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_(DBSCAN)&amp;diff=14157"/>
		<updated>2016-10-27T11:19:45Z</updated>

		<summary type="html">&lt;p&gt;Sleo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Плотностный алгоритм кластеризации (DBSCAN)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(|S| \log S)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(k)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
Автор описания: [[Участник:Igor.orpanen|Орпанен И.С.]]&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;
Плотностный алгоритм кластеризации DBSCAN (Density-based spatial clustering of applications with noise) является алгоритмом кластеризации, позволяющим находить кластеры произвольной формы в метрическом пространстве. Он был предложен учёными Martin Ester, Hans-Peter Kriegel, Jörg Sander и Xiaowei Xu в 1996 году.&amp;lt;ref name=&amp;quot;dbscan&amp;quot;&amp;gt;Ester M. et al. A density-based algorithm for discovering clusters in large spatial databases with noise //Kdd. – 1996. – Т. 96. – №. 34. – С. 226-231.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Основной идеей алгоритма DBSCAN является представление объектов кластера в виде группы точек в метрическом пространстве, являющихся вершинами одного связного графа. Причём две точки в таком графе соединеняются ребром только в том случае, если расстояние между ними в заданной метрике не превышает определённого расстояния. Если рядом с некоторым объектом нет достаточно близких соседей, то он признаётся выбросом. &lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Входные данные: множество объектов &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;, для которых задана метрическая функция расстояния &amp;lt;math&amp;gt;\rho&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;\varepsilon&amp;lt;/math&amp;gt; - максимальное расстояния между соседними объектами,&lt;br /&gt;
* &amp;lt;math&amp;gt;minPts&amp;lt;/math&amp;gt; - минимальное количество соседних объектов, необходимых для образования кластера.&lt;br /&gt;
&lt;br /&gt;
=== Определения ===&lt;br /&gt;
* Объект &amp;lt;math&amp;gt;p \in X&amp;lt;/math&amp;gt; называется ядровым, если в &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-окрестности точки &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; находятся &amp;lt;math&amp;gt;MinPts&amp;lt;/math&amp;gt; объектов (включая сам объект &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;). Эти объекты называются напрямую достижимыми из &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Объект &amp;lt;math&amp;gt;q \in X&amp;lt;/math&amp;gt; называется достижимым из &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, если существует путь &amp;lt;math&amp;gt;p_1,...,p_n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;p_1 = p&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_n = q&amp;lt;/math&amp;gt;, а каждый объект &amp;lt;math&amp;gt;p_{i+1}&amp;lt;/math&amp;gt; напрямую достижим из &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Таким образом вся объекты в пути, кроме объекта &amp;lt;math&amp;gt;q&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;p&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Отмечаем объект &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; как обработанный.&lt;br /&gt;
# Находим соседние объекты в &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-окрестности объекта &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Сравниваем количество соседних объектов с &amp;lt;math&amp;gt;MinPts&amp;lt;/math&amp;gt;, определяя, является ли &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; ядровым объектом&lt;br /&gt;
#* Если объект &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; является ядровым, то создаём новый кластер и запускаем поиск в ширину из данного объекта по другим непосещённым объектам, находя все объекты кластера.&lt;br /&gt;
#* Если объект &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; не является ядровым, то отмечаем его как выброс (или шум).&lt;br /&gt;
# Если присутствуют необработанные объекты, то возвращаемся к шагу 1.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительное ядро алгоритма представляет собой поиск соседних объектов, попадающих в &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-окрестность каждого объекта из множества &amp;lt;math&amp;gt;X&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;\rho&amp;lt;/math&amp;gt; между двумя объектами из кластеризуемого множества используется метрика. В большинстве случаев вычисляется метрика Евклида: &amp;lt;math&amp;gt;\rho(\mathbf{p}, \mathbf{q})=\sqrt{(p_1-q_1)^2+(p_2-q_2)^2+\dots+(p_n-q_n)^2} = \sqrt{\sum_{k=1}^n (p_k-q_k)^2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В качестве альтернативного примера можно привести метрику Манхэттена, введённую Германом Минковским:&lt;br /&gt;
&amp;lt;math&amp;gt;\rho(\mathbf{p}, \mathbf{q}) = \sum_{i=1}^n |p_i-q_i|,&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Поиск соседних объектов в &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-окрестности ===&lt;br /&gt;
Для поиска соседних объектов может быть использован простой перебор всех известных объектов, однако последовательная сложность такого алгоритма будет равна &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;. Для ускорения работы алгоритма обычно используются специальные структуры данных, такие как r-tree, k-d tree, ball tree, vantage-point tree и т.д. Эти структуры данных могут быть построены за время &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt;, тем самым снизив общую временную сложность алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Схема реализации алгоритма DBScan может быть описана на псевдокоде в терминах оригинальной статьи:&amp;lt;ref name=&amp;quot;dbscan&amp;quot; /&amp;gt;&lt;br /&gt;
 DBSCAN(X, Eps, MinPts) {&lt;br /&gt;
    C = 0&lt;br /&gt;
    for P ∈ X {&lt;br /&gt;
       if P is visited&lt;br /&gt;
          continue&lt;br /&gt;
       mark P as visited&lt;br /&gt;
       PNeighbors = regionQuery(P, Eps)&lt;br /&gt;
       if len(PNeighbors) &amp;lt; MinPts&lt;br /&gt;
          mark P as noise&lt;br /&gt;
       else {&lt;br /&gt;
          C = next cluster&lt;br /&gt;
          expandCluster(P, PNeighbors, C, Eps, MinPts)&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 expandCluster(P, PNeighbors, C, Eps, MinPts) {&lt;br /&gt;
    add P to cluster C&lt;br /&gt;
    for each point Q ∈ PNeighbors { &lt;br /&gt;
       if Q is not visited {&lt;br /&gt;
          mark Q as visited&lt;br /&gt;
          QNeighbors = regionQuery(Q, Eps)&lt;br /&gt;
          if len(QNeighbors) &amp;gt;= MinPts&lt;br /&gt;
             PNeighbors = PNeighbors ∪ QNeighbors&lt;br /&gt;
       }&lt;br /&gt;
       if Q is not in any cluster&lt;br /&gt;
          add Q to cluster C&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 regionQuery(P, Eps)&lt;br /&gt;
    return all points within P&#039;s Eps-neighborhood (including P)&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Последовательная сложность алгоритма DBSCAN определяется сложностью его вычислительного ядра, то есть поиска соседних объектов в &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-окрестности для каждого объекта из исходного множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;. Алгоритм посешает каждый объект из множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; ровно один раз, и это приводит к вызову функции regionQuery. В случае подсчёта расстояний до каждого объекта вызов функции regionQuery имеет последовательную сложность &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;, а значит общая последовательная сложность равна &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;. В случае использования вспомогательной структуры данных функция regionQuery может иметь сложность &amp;lt;math&amp;gt;O(\log n)&amp;lt;/math&amp;gt;, таким образом снизив общую последовательную сложность алгоритма до &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
Параллельные реализации алгоритма DBSCAN всегда используют специальные пространственные структуры данных, такие как k-d tree, r-tree и vantage-point tree. Построение этих структур данных может быть распараллелено путём разделения множества объектов &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на части &amp;lt;math&amp;gt;X_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;i=\overline{1,k}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== PDBSCAN ===&lt;br /&gt;
Первый рассматриваемый параллельный алгоритм PDBSCAN был предложен ещё в 1999 году.&amp;lt;ref name=&amp;quot;pdbscan&amp;quot;&amp;gt;Xu X., Jäger J., Kriegel H. P. A fast parallel clustering algorithm for large spatial databases //High Performance Data Mining. – Springer US, 1999. – С. 263-290.&amp;lt;/ref&amp;gt;. Его основной особенностью является master-slave архитектура. Используются распределённые dR*-деревья, которые позволяют разбить метрическое пространств на области и распределить вычисления между slave-машинами. Затем в каждой из этих областей происходит поиск кластеров, а также определяется необходимость слияния с кластерами из других областей с помощью алгоритма PartDBSCAN. Затем slave-машины отправляют результаты своих вычислений на master-машину, которая сливает необходимые кластеры вместе и завершает выполнение распределённого алгоритма. Информационный граф изображён на рисунке 1.&lt;br /&gt;
[[file:PDBSCAN.png|thumb|center|600px|Рис.1. Информационная структура алгоритма PDBSCAN]]&lt;br /&gt;
&lt;br /&gt;
=== PDSDBSCAN ===&lt;br /&gt;
Другой параллельный алгоритм PDSDBSCAN был предложен в 2012 году.&amp;lt;ref name=&amp;quot;pdsdbscan&amp;quot;&amp;gt;Patwary M. M. A. et al. A new scalable parallel DBSCAN algorithm using the disjoint-set data structure //High Performance Computing, Networking, Storage and Analysis (SC), 2012 International Conference for. – IEEE, 2012. – С. 1-11.&amp;lt;/ref&amp;gt; Его авторы отмечают недостатки master-slave архитектуры и предлагают полностью распределённый алгоритм, основанный на структуре данных из непересекаюшихся множеств, которая позволяет операцию слияния этих множеств. Это позволяет производить слияние кластеров без master-машины и значительно повысить производительность распределённого алгоритма. Информационный граф изображён на рисунке 2.&lt;br /&gt;
[[file:PDSDBSCAN.png|thumb|center|600px|Рис.2. Информационная структура алгоритма PDSDBSCAN]]&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Ширина ярусно-параллельной формы обоих алгоритмов PDBSCAN и PDSDBSCAN равна &amp;lt;math&amp;gt;O(k)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - это количество частей, на которые разбивается исходный набор объектов. &lt;br /&gt;
Высота ярусно-параллельной платформы у обоих алгоритмов одинакова и равна &amp;lt;math&amp;gt;O(|S| \log S)&amp;lt;/math&amp;gt;&amp;lt;ref name=&amp;quot;pdbscan&amp;quot; /&amp;gt;&amp;lt;ref name=&amp;quot;pdsdbscan&amp;quot; /&amp;gt;, где &amp;lt;math&amp;gt;S=\max_{1 \leq i \leq k} |X_i|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
Входные данные: множество объектов &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;, для которых задана метрическая функция расстояния &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;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;.&lt;br /&gt;
&lt;br /&gt;
Количество кластеров и шума в выходных данных зависят от входных данных и параметров алгоритма. Более компактное расположение объектов, меньшие значения параметра &amp;lt;math&amp;gt;MinPts&amp;lt;/math&amp;gt;, большие значения параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; ведут к образования меньшего числа кластеров, вплоть до одного единственного кластера. Если варьировать данные параметры в противоположную сторону, то количество кластеров и шумовых объектов будет расти, вплоть до момента, когда все объекты будут являться шумом.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
* Алгоритм находит заранее неизвестное число кластеров произвольной формы.&lt;br /&gt;
* Алгоритм работает в условиях зашумлённых данных, выделяя выбросы в отдельную категорию объектов.&lt;br /&gt;
* Алгоритм обладает сбалансированностью вычислительного процесса относительно всех типов операций при разбиении входных данных на части примерно одинакового размера.&lt;br /&gt;
* Алгоритм не является детерминированным, так как в некоторых случаях граничные точки могут попасть в несколько различных кластеров, что зависит от порядка их формирования. Однако это не оказывает значительного влияния на результаты работы алгоритма. Существует вариация алгоритма DBSCAN*, которая относит все граничные точки к шуму, тем самым достигая полной детерминированности.&lt;br /&gt;
* Качество работы алгоритма сильно зависит от используемой метрики, а также от правильно выбранных параметров &amp;lt;math&amp;gt;MinPts&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; для заданной предметной области. В частности для объектов в пространстве большой размерности при использовании метрики Евклида имеет место проклятие размерности.&lt;br /&gt;
* Алгоритм плохо работает для разнородных данных, состоящих из кластеров разной плотности, так как тогда параметры алгоритмы &amp;lt;math&amp;gt;MinPts&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\varepsilon&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;
{| class=&amp;quot;wikitable&amp;quot;&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;
| [http://scikit-learn.org/stable/modules/generated/sklearn.cluster.DBSCAN.html Scikit learn]&lt;br /&gt;
| Python&lt;br /&gt;
| BSD 3&lt;br /&gt;
| &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| k-d tree, ball tree&lt;br /&gt;
| Любые&lt;br /&gt;
| style=&amp;quot;background: #9F9;&amp;quot; | Есть&lt;br /&gt;
|-&lt;br /&gt;
| [https://github.com/alitouka/spark_dbscan alitouka/spark_dbscan]&lt;br /&gt;
| Scala, Spark&lt;br /&gt;
| GPLv2&lt;br /&gt;
| &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| r-tree&lt;br /&gt;
| Euclidean&lt;br /&gt;
| style=&amp;quot;background: #9F9;&amp;quot; | Есть&lt;br /&gt;
|-&lt;br /&gt;
| [https://github.com/irvingc/dbscan-on-spark irvingc/dbscan-on-spark]&lt;br /&gt;
| Scala, Spark&lt;br /&gt;
| GPLv2&lt;br /&gt;
| &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| r-tree&lt;br /&gt;
| Euclidean&lt;br /&gt;
| style=&amp;quot;background: #9F9;&amp;quot; | Есть&lt;br /&gt;
|-&lt;br /&gt;
| [https://github.com/propanoid/DBSCAN propanoid/DBSCAN]&lt;br /&gt;
| C++, Boost, OpenMP&lt;br /&gt;
| ABRMS&lt;br /&gt;
| &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| vantage-point tree&lt;br /&gt;
| Euclidean&lt;br /&gt;
| style=&amp;quot;background: #9F9;&amp;quot; | Есть&lt;br /&gt;
|-&lt;br /&gt;
| [https://cran.r-project.org/web/packages/dbscan/index.html CRAN]&lt;br /&gt;
| R, C++&lt;br /&gt;
| GPLv3&lt;br /&gt;
| &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| k-d tree&lt;br /&gt;
| Euclidean&lt;br /&gt;
| style=&amp;quot;background: #F99;&amp;quot; | Нет&lt;br /&gt;
|-&lt;br /&gt;
| [http://weka.sourceforge.net/doc.packages/optics_dbScan/weka/clusterers/DBScan.html Weka]&lt;br /&gt;
| Java&lt;br /&gt;
| GPLv3&lt;br /&gt;
| &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| -&lt;br /&gt;
| Euclidean, Manhattan&lt;br /&gt;
| style=&amp;quot;background: #F99;&amp;quot; | Нет&lt;br /&gt;
|-&lt;br /&gt;
| [https://commons.apache.org/proper/commons-math/javadocs/api-3.1/org/apache/commons/math3/stat/clustering/DBSCANClusterer.html Apache Commons]&lt;br /&gt;
| Java&lt;br /&gt;
| Apache 2.0&lt;br /&gt;
| &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| -&lt;br /&gt;
| Euclidean&lt;br /&gt;
| style=&amp;quot;background: #F99;&amp;quot; | Нет&lt;br /&gt;
|-&lt;br /&gt;
| [https://github.com/choffstein/dbscan choffstein/dbscan]&lt;br /&gt;
| Python&lt;br /&gt;
| -&lt;br /&gt;
| &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| -&lt;br /&gt;
| Euclidean&lt;br /&gt;
| style=&amp;quot;background: #F99;&amp;quot; | Нет&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sleo</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Igor.orpanen&amp;diff=14156</id>
		<title>Обсуждение участника:Igor.orpanen</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Igor.orpanen&amp;diff=14156"/>
		<updated>2016-10-27T11:19:04Z</updated>

		<summary type="html">&lt;p&gt;Sleo: Новая страница: «Замечания к оформлению статьи:  0. Если рисунок не ваш, то требуется указать ссылку на рес…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Замечания к оформлению статьи:&lt;br /&gt;
&lt;br /&gt;
0. Если рисунок не ваш, то требуется указать ссылку на ресурс, откуда он был взят.&lt;br /&gt;
&lt;br /&gt;
1. В пункте 1.3 расшифруйте фразу: &amp;quot;построение специальных структур данных&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
3. Пункт 1.5 стоит подписать комментарии к блоку псевдокода.&lt;br /&gt;
&lt;br /&gt;
4. В пункте 1.7 написать пояснение к информационным графам и сделать их более подробными (особенно требуется расписать более подробно оранжевые блоки).&lt;br /&gt;
&lt;br /&gt;
5. Вычислительная мощность не приведена. (см. пример: https://algowiki-project.org/ru/%D0%A0%D0%B0%D0%B7%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%A5%D0%BE%D0%BB%D0%B5%D1%86%D0%BA%D0%BE%D0%B3%D0%BE_(%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D0%BA%D0%B2%D0%B0%D0%B4%D1%80%D0%B0%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BA%D0%BE%D1%80%D0%BD%D1%8F)&lt;/div&gt;</summary>
		<author><name>Sleo</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Elmon&amp;diff=14037</id>
		<title>Обсуждение участника:Elmon</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Elmon&amp;diff=14037"/>
		<updated>2016-10-26T14:43:33Z</updated>

		<summary type="html">&lt;p&gt;Sleo: Новая страница: «Замечания к оформлению статьи:  0. Если рисунок не ваш, то требуется указать ссылку на рес…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Замечания к оформлению статьи:&lt;br /&gt;
&lt;br /&gt;
0. Если рисунок не ваш, то требуется указать ссылку на ресурс, откуда он был взят.&lt;br /&gt;
&lt;br /&gt;
1. В пунтке 1.1 не указано ни одного свойства алгоритма. &lt;br /&gt;
&lt;br /&gt;
2. Пункт 1.3 стоит расписать подробнее. Например, привести основные операции, которые применяются выч. ядре алгоритма.&lt;br /&gt;
2.1 Пункт 1.4 стоит расписать подробнее. Опишите термин: &amp;quot;пространственной структуры данных&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
3. Пункт 1.5 стоит подписать комментарии к блоку псевдокода.&lt;br /&gt;
&lt;br /&gt;
4. Почему в пункте 1.9 два описания входных и выходных данных?&lt;br /&gt;
&lt;br /&gt;
5. В пункте 1.7 написать пояснение к информационному графу.&lt;br /&gt;
&lt;br /&gt;
6. Вычислительная мощность не приведена. (см. пример: https://algowiki-project.org/ru/%D0%A0%D0%B0%D0%B7%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%A5%D0%BE%D0%BB%D0%B5%D1%86%D0%BA%D0%BE%D0%B3%D0%BE_(%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D0%BA%D0%B2%D0%B0%D0%B4%D1%80%D0%B0%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BA%D0%BE%D1%80%D0%BD%D1%8F)&lt;br /&gt;
&lt;br /&gt;
7. В пункте 2.7 добавить описание, хотя бы пару слов о каждой реализации, а не просто ссылки.&lt;/div&gt;</summary>
		<author><name>Sleo</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%96%D0%B0%D0%BD%D0%BD%D0%B0%D1%82_%D0%A1%D0%B0%D0%B3%D0%B8%D0%BE%D0%BB%D0%B4%D0%B0%D0%BD%D0%BE%D0%B2%D0%B0&amp;diff=14036</id>
		<title>Обсуждение участницы:Жаннат Сагиолданова</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%96%D0%B0%D0%BD%D0%BD%D0%B0%D1%82_%D0%A1%D0%B0%D0%B3%D0%B8%D0%BE%D0%BB%D0%B4%D0%B0%D0%BD%D0%BE%D0%B2%D0%B0&amp;diff=14036"/>
		<updated>2016-10-26T14:39:20Z</updated>

		<summary type="html">&lt;p&gt;Sleo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Замечания к оформлению статьи:&lt;br /&gt;
&lt;br /&gt;
0. Если рисунок не ваш, то требуется указать ссылку на ресурс, откуда он был взят. &lt;br /&gt;
&lt;br /&gt;
1. Пункт 1.3 стоит расписать подробнее. Например, привести основные операции, которые применяются выч. ядре алгоритма.&lt;br /&gt;
&lt;br /&gt;
2. Пункт 1.6: &amp;quot;Если использовать специальную пространственную структуру данных&amp;quot; - поясните термин.&lt;br /&gt;
&lt;br /&gt;
3. Пункт 1.5 стоит подписать комментарии к всем трем блокам псевдокода.&lt;br /&gt;
&lt;br /&gt;
4. Почему в пункте 1.9 два описания входных и выходных данных?&lt;br /&gt;
&lt;br /&gt;
5. В постановке задачи имелось ввиду более подробное графическое описание информационного графа. (см. пример: https://algowiki-project.org/ru/%D0%A0%D0%B0%D0%B7%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%A5%D0%BE%D0%BB%D0%B5%D1%86%D0%BA%D0%BE%D0%B3%D0%BE_(%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D0%BA%D0%B2%D0%B0%D0%B4%D1%80%D0%B0%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BA%D0%BE%D1%80%D0%BD%D1%8F). Информационный граф - ациклический.&lt;br /&gt;
&lt;br /&gt;
6. Не указан вклад каждого из авторов статьи. &lt;br /&gt;
&lt;br /&gt;
7. Вычислительная мощность не приведена. (см. пример: https://algowiki-project.org/ru/%D0%A0%D0%B0%D0%B7%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%A5%D0%BE%D0%BB%D0%B5%D1%86%D0%BA%D0%BE%D0%B3%D0%BE_(%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D0%BA%D0%B2%D0%B0%D0%B4%D1%80%D0%B0%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BA%D0%BE%D1%80%D0%BD%D1%8F)&lt;/div&gt;</summary>
		<author><name>Sleo</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:Elmon/%D0%9F%D0%BB%D0%BE%D1%82%D0%BD%D0%BE%D1%81%D1%82%D0%BD%D1%8B%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_DBSCAN&amp;diff=14035</id>
		<title>Участник:Elmon/Плотностный алгоритм кластеризации DBSCAN</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:Elmon/%D0%9F%D0%BB%D0%BE%D1%82%D0%BD%D0%BE%D1%81%D1%82%D0%BD%D1%8B%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_DBSCAN&amp;diff=14035"/>
		<updated>2016-10-26T14:34:27Z</updated>

		<summary type="html">&lt;p&gt;Sleo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Плотностный алгоритм кластеризации DBSCAN&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(|H| \log |H|)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(w)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основной автор описания: [[User:Elmon|Гилевич В.В.]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Кластеризация — это процедура, упорядочивающая элементы из некоторого множества в сравнительно однородные группы (кластеры). Элементы могут содержать числовые, категориальные или смешанные данные. Плотностные методы выделяют кластеры на основе следующей идеи: кластером считается регион с высокой плотностью объектов, которые разделены разреженными регионами (с низкой плотностью объектов)&lt;br /&gt;
&lt;br /&gt;
Алгоритм DBSCAN (Density Based Spatial Clustering of Applications with Noise) &amp;lt;ref&amp;gt;A density-based algorithm for discovering clusters in large spatial database / M. Ester, H.-P. Kriegel,&lt;br /&gt;
J. Sander, X. Xu // Proc. 1996 Intern. Conf. on Knowledge Discovery and Data Mining. – 1996.&amp;lt;/ref&amp;gt; — плотностной алгоритм для кластеризации пространственных данных с присутствием шума, был предложен Мартином Эстер, Гансом-Питером Кригель и их коллегами в 1996 году как решение проблемы разбиения данных на кластеры произвольной формы.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Исходные данные ===&lt;br /&gt;
Множество &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;, на котором определена функция расстояния &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
=== Вычисляемые данные===&lt;br /&gt;
Множество пар из элемента множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;, и соответствующий ему номер кластера.&lt;br /&gt;
&lt;br /&gt;
=== Параметры алгоритма ===&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; — максимальное расстояние между соседями;&lt;br /&gt;
* &amp;lt;math&amp;gt;MinPts&amp;lt;/math&amp;gt; — минимальное количество элементов находящихся &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-окрестности данного элемента для создания кластера.&lt;br /&gt;
&lt;br /&gt;
=== Определения ===&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;ядровой элемент&#039;&#039;: элемент &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; является ядровым, если количество элементов в &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-окрестности, включая сам элемент &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; больше или равно &amp;lt;math&amp;gt;MinPts&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;достижимость напрямую элемента &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; из элемента q&#039;&#039;: элемент &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; считается достижимым напрямую из элемента &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt;, если элемент &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; является ядровым, а элемент &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; находится в &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-окрестности элемента q;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;достижимость элемента &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; из элемента &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt;&#039;&#039;: элемент &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; достижим из элемента &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt;, если существует путь &amp;lt;math&amp;gt;p_1, \dots, p_n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;p_1 = p&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_n = q&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;p_{i + 1}&amp;lt;/math&amp;gt; напрямую достижим из &amp;lt;math&amp;gt;p_{i}&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;шум&#039;&#039;: все элементы, недостижимые из какого-либо другого считаются шумом.&lt;br /&gt;
&lt;br /&gt;
Так как достижимость не является симметричным отношением (никакой элемент не может быть достижим из неядрового, вне зависимости от расстояния), то предлагается ввести следующее отношение:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;связанность элемента p и элемента q&#039;&#039;: элемент &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; считается связанным с &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt;, если существует такой элемент &amp;lt;math&amp;gt;o&amp;lt;/math&amp;gt;, что &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; достижимы из него.&lt;br /&gt;
&lt;br /&gt;
Таким образом &#039;&#039;кластер&#039;&#039; должен удовлетворять двум условиям:&lt;br /&gt;
* Все элементы внутри кластера взаимно связанны;&lt;br /&gt;
* Если элемент связан с каким-либо элементом кластера, то он тоже является частью кластера.&lt;br /&gt;
&lt;br /&gt;
[[File:DBSCAN-Illustration.svg|thumb|right|400px| Рис. 1&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/DBSCAN Density-based spatial clustering of applications with noise (DBSCAN)&amp;lt;/ref&amp;gt;. Для &#039;&#039;MinPts&#039;&#039; = 4. Красные элементы соответствуют ядровым, желтые — достижимым, синяя — шуму.]]&lt;br /&gt;
&lt;br /&gt;
=== Пошаговое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
#Выбирается произвольная непосещенный элемент &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;.&lt;br /&gt;
#Элемент &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; помечается как посещенный. &lt;br /&gt;
#Проверяется, является ли элемент &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; ядровым.&lt;br /&gt;
#*Если элемент &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; является ядровым, то: &lt;br /&gt;
#**Он становится началом нового кластера или сохраняет номер кластера, который был присвоен элементу ранее; &lt;br /&gt;
#**Все элементы из &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-окрестности элемента &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; добавляются в его кластер (им присваевается номер кластера элемента &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;);&lt;br /&gt;
#**Процесс продолжается рекурсивно для каждого непосещенного элемента текущего кластера c шага 2.&lt;br /&gt;
#*Если элемент &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; не является ядровым, то &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; объявляется шумом. Алгоритм продолжается с шага 4.&lt;br /&gt;
#Если остались непосещенные точки, то алгоритм продолжается с шага 1.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром алгоритма является поиск элементов в &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-окрестности каждого элемента входного множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;. На эту часть алгоритма приходится основное время работы алгоритма, так как для каждого элемента необходимо выполнить эту операцию.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма == &lt;br /&gt;
Алгоритм DBSCAN предполагает использование пространственной структуры данных: такие структуры позволяют найти все элементы в пределах определенного расстояния от текущего за &amp;lt;math&amp;gt;O(\log n)&amp;lt;/math&amp;gt;. Сложность построения таких структур &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt;, таким образом, использование такой структуры не увеличивает сложность всего алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;DBSCAN(X, \varepsilon, MinPts)&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;C = 0&amp;lt;/math&amp;gt;&lt;br /&gt;
   for &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; in &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;:&lt;br /&gt;
     if &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; is &amp;lt;math&amp;gt;visited&amp;lt;/math&amp;gt;:&lt;br /&gt;
       continue&lt;br /&gt;
     mark &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; as &amp;lt;math&amp;gt;visited&amp;lt;/math&amp;gt;&lt;br /&gt;
     &amp;lt;math&amp;gt;neighbours&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;\{ o \ | \ \forall o \in X: D(p, o) \le \varepsilon \}&amp;lt;/math&amp;gt;&lt;br /&gt;
     if &amp;lt;math&amp;gt;| neighbours | \ge MinPts&amp;lt;/math&amp;gt;:&lt;br /&gt;
       &amp;lt;math&amp;gt;C = C + 1&amp;lt;/math&amp;gt;&lt;br /&gt;
       add &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; to cluster &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;&lt;br /&gt;
       for &amp;lt;math&amp;gt;q \in neighbours&amp;lt;/math&amp;gt;:&lt;br /&gt;
         if &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; is not &amp;lt;math&amp;gt;visited&amp;lt;/math&amp;gt;:&lt;br /&gt;
           mark &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; as &amp;lt;math&amp;gt;visited&amp;lt;/math&amp;gt;&lt;br /&gt;
           &amp;lt;math&amp;gt;q\_neighbours&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;\{ o \ | \ \forall o \in X: D(q, o) \le \varepsilon \}&amp;lt;/math&amp;gt;&lt;br /&gt;
           if &amp;lt;math&amp;gt;| q\_neighbours | \ge MinPts&amp;lt;/math&amp;gt;:&lt;br /&gt;
             &amp;lt;math&amp;gt;neighbours&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;neighbours \cup q\_neighbours&amp;lt;/math&amp;gt;  &lt;br /&gt;
         if &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; has no cluster mark:&lt;br /&gt;
           mark &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; as part of cluster &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;&lt;br /&gt;
     else:&lt;br /&gt;
       mark &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; as &amp;lt;math&amp;gt;noise&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Для того, чтобы проверить принадлежность элемента множества к кластеру необходимо получить список соседей в его &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-окрестности. При использовании пространственной структуры данных данная операция может быть выполнена со сложностью &amp;lt;math&amp;gt;O(\log n)&amp;lt;/math&amp;gt;. Так как для необходимо определить принадлежность к кластеру всех элементов множества, то сложность самого алгоритма &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt;. При отказе от использования таких сткрутр сложность возрастает до &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, так как для каждого элемента требуется проверить на нахождение в &amp;lt;math&amp;gt;\varepsilon&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;
Первой группе вершин соответствует операция Neighbours. Естественно введённые координаты области таковы:&lt;br /&gt;
* &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; — меняется от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;k + f&amp;lt;/math&amp;gt;, принимая все целочисленные значения, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; — число результирующих кластеров, &amp;lt;math&amp;gt;f&amp;lt;/math&amp;gt; — число элементов помеченных, как шум&lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, принимая все целочисленные значения, где &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; — число вершин в кластере &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;&lt;br /&gt;
Второй группе вершин соответствует операция Check. Естественно введённые координаты области аналогичны предыдущей.&lt;br /&gt;
&lt;br /&gt;
[[File:DBSCAN algo graph.png|thumb|center|800px| Граф алгоритма DBSCAN]]&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Так как в данном алгоритме присутствует параллелизм по данным, ширина ярусно-параллельной формы алгоритма &amp;lt;math&amp;gt;O(w)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; — количество частей, на которые разбиваются все входное множество объектов &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;. Высотой ярусно-параллельной формы алгоритма является &amp;lt;math&amp;gt;O(|H| \log |H|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|H|&amp;lt;/math&amp;gt; — максимальное количество элементов в области среди всех частей разбиения. Именно такую сложность имеет алгоритм PDBSCAN&amp;lt;ref&amp;gt;[http://www.ece.northwestern.edu/~choudhar/Publications/ANewScalableParallelDBSCANAlgorithmUsingDisjointSetDataStructure.pdf A New Scalable Parallel DBSCAN Algorithm Using the Disjoint-Set Data Structure \ Md. Mostofa Ali Patwary, Diana Palsetia, Ankit Agrawal, Wei-keng Liao, Fredrik Manne, Alok Choudhary]&amp;lt;/ref&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;X&amp;lt;/math&amp;gt;, на котором определена функция расстояния &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; (размерность входящего множества)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: размеченное множество точек &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;, в котором каждому элементу соответствует номер его кластера.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;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;
* [https://github.com/ContinuumIO/parallel_dbscan]&lt;br /&gt;
* [https://github.com/propanoid/DBSCAN]&lt;br /&gt;
* [https://github.com/ahbarnett/validspike/tree/master/contrib/dbscan_patwary]&lt;br /&gt;
* [https://github.com/bwoneill/pypardis]&lt;br /&gt;
* [https://github.com/mhahsler/dbscan]&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:DBSCAN]]&lt;/div&gt;</summary>
		<author><name>Sleo</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:Elena777mc/%D0%9F%D0%BB%D0%BE%D1%82%D0%BD%D0%BE%D1%81%D1%82%D0%BD%D1%8B%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_DBSCAN&amp;diff=14032</id>
		<title>Участник:Elena777mc/Плотностный алгоритм кластеризации DBSCAN</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:Elena777mc/%D0%9F%D0%BB%D0%BE%D1%82%D0%BD%D0%BE%D1%81%D1%82%D0%BD%D1%8B%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_DBSCAN&amp;diff=14032"/>
		<updated>2016-10-26T14:33:12Z</updated>

		<summary type="html">&lt;p&gt;Sleo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Плотностный алгоритм кластеризации DBSCAN&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(|X| \log |X|)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(m)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:Elena777mc|Малахова Е.С.]], [[Участник:Жаннат_Сагиолданова|Сагиолданова Ж.]]&lt;br /&gt;
&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;x_1, x_2, ... , x_n (x_n&amp;lt;/math&amp;gt; имеет размерность  &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;) на &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; кластеров, так, чтобы в каждом кластере все элементы были схожи&lt;br /&gt;
в каком-то смысле. &amp;lt;math&amp;gt;x_i&amp;lt;/math&amp;gt; могут быть числовыми, категориальными или смешанными данными.  В плотностных методах кластеры рассматриваются как регионы пространства данных с высокой плотностью объектов, которые разделены регионами с низкой плотностью объектов.&lt;br /&gt;
&lt;br /&gt;
Алгоритм DBSCAN (Density Based Spatial Clustering of Applications with Noise) &amp;lt;ref&amp;gt;A density-based algorithm for discovering clusters in large spatial database / M. Ester, H.-P. Kriegel,&lt;br /&gt;
J. Sander, X. Xu // Proc. 1996 Intern. Conf. on Knowledge Discovery and Data Mining. – 1996. – P. 226 –&lt;br /&gt;
231.&amp;lt;/ref&amp;gt; –плотностной алгоритм для кластеризации пространственных данных с присутствием шума, был предложен Мартином Эстер, Гансом-Питером Кригель и их коллегами в 1996 году как решение проблемы разбиения (изначально пространственных) данных на кластеры произвольной формы. &lt;br /&gt;
&lt;br /&gt;
Большинство алгоритмов, производящих плоское разбиение, создают кластеры по форме близкие к сферическим, так как минимизируют расстояние точки до центра кластера.&lt;br /&gt;
&lt;br /&gt;
Авторы DBSCAN экспериментально показали, что их алгоритм способен распознать кластеры различной формы.&lt;br /&gt;
Идея, положенная в основу алгоритма, заключается в том, что внутри каждого кластера плотность точек (объектов) заметно выше, чем плотность снаружи кластера, а также плотность в областях с шумом ниже плотности любого из кластеров. Еще точнее, для каждой точки кластера ее окрестность в диапазоне заданного радиуса должна содержать не менее некоторого числа точек, которое задается пороговым значением.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
[[File:dbscan_osn.png|thumb|right|500px| Рис. 1. Пример ядровых, граничных и шумовых точек алгоритма]]&lt;br /&gt;
&lt;br /&gt;
Исходные данные: объекты, которые нужно кластеризовать, параметры &amp;lt;math&amp;gt;MinPts, \  \varepsilon&amp;lt;/math&amp;gt; . Между объектами можно считать расстояния.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: разбиение объектов по кластерам. Количество кластеров зависит от исходных данных.  &amp;lt;ref&amp;gt;&amp;quot;Xu, X. A fast parallel clustering algorithm for large spatial databases / X. Xu, M. Ester, H.-P. Kriegel // Proc. 1999 Intern. Conf. on Knowledge Discovery and Data Mining. – 1999. – Vol. 3, is. 3. – P. 263 – 290.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для построения оценки плотности, на основе соседства точек вводятся понятия&lt;br /&gt;
достижимости и связности. Под &amp;lt;math&amp;gt;\varepsilon &amp;lt;/math&amp;gt; -соседями точки &amp;lt;math&amp;gt;x \in X&amp;lt;/math&amp;gt; понимается множество точек, расстояние до которых не превышает &amp;lt;math&amp;gt;\varepsilon &amp;lt;/math&amp;gt;, т. е.&lt;br /&gt;
 &amp;lt;math&amp;gt;N_\varepsilon (x) = \{y \in X | D(x, y) \le \varepsilon\}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Тогда точка &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; достижима из точки &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, если существует последовательность точек &amp;lt;math&amp;gt;x^{(1)}=x, x^{(2)},... , x^{(p-1)}, x^{(p)}=y&amp;lt;/math&amp;gt;, для которой выполнено:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
  \begin{align}&lt;br /&gt;
x^{(i+1)} \in N_\varepsilon (x^{(i)}), i=1,... ,p-1 \\&lt;br /&gt;
\mid  N_\varepsilon (x^{(i)}) \mid \ge MinPts, i=1,... ,p-1&lt;br /&gt;
  \end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здесь значение &amp;lt;math&amp;gt;MinPts&amp;lt;/math&amp;gt; задаётся пользователем и регулирует порог «шума». Согласно второму условию, у точек, находящихся внутри кластера, должно быть не менее &amp;lt;math&amp;gt;MinPts \   \varepsilon&amp;lt;/math&amp;gt; -соседей. Такие точки называются «ядрами». Остальные точки разделяются на граничные (имеющие менее &amp;lt;math&amp;gt;MinPts \   \varepsilon &amp;lt;/math&amp;gt; -cоседей, но достижимые из какого-либо «ядра») и шумовые. Две точки связны, если существует «ядро», из которого они обе достижимы.&lt;br /&gt;
При такой постановке задачи, под кластером понимается максимальное связное подмножество множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; . Точки, не попавшие в какой-либо кластер (не принадлежащие &amp;lt;math&amp;gt;\varepsilon&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;\varepsilon&amp;lt;/math&amp;gt;-соседей каждого объекта входного множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;. На эту часть алгоритма приходится основное время работы алгоритма, так как требуется найти всех соседей для каждого объекта заданного множества.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма == &lt;br /&gt;
Алгоритм DBSCAN использует пространственную структуру данных для определения соседних объектов. Это может быть R*-дерево или kd-дерево. Такие структуры данных позволяют найти все объекты в пределах определенного расстояния от текущего объекта. Сложность построения таких структур &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt; и использование такой структуры не увеличит сложность всего алгоритма (если сложность самого алгоритма &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt;). Также для построения этих деревьев нужно уметь находить расстояние между объектами &amp;lt;math&amp;gt;\rho(u,v)&amp;lt;/math&amp;gt;, в, это расстояние можно вводить разными способами. Например, если &amp;lt;math&amp;gt;\rho(u,v)&amp;lt;/math&amp;gt; - метрика в евклидовом пространстве, &amp;lt;math&amp;gt;u=(u_1,...,u_n)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(v_1,...,v_n)&amp;lt;/math&amp;gt;, то расстояние вычисляется следующим образом: &amp;lt;math&amp;gt;\rho(u,v)=\sqrt{(u_1-v_1)^2+(u_2-v_2)^2+...+(u_n-v_n)^2} = \sqrt{\sum_{k=1}^n(u_k-v_k)^2}&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;DBSCAN(X, \varepsilon, MinPts)&amp;lt;/math&amp;gt;&lt;br /&gt;
 //Изначально все объекты в &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;не кластеризованы&lt;br /&gt;
    &amp;lt;math&amp;gt;FORALL&amp;lt;/math&amp;gt;  objects  &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; in &amp;lt;math&amp;gt;X\  DO&amp;lt;/math&amp;gt;&lt;br /&gt;
       &amp;lt;math&amp;gt;IF\  x&amp;lt;/math&amp;gt; is unclassified&lt;br /&gt;
         call function &amp;lt;math&amp;gt;expand\_cluster&amp;lt;/math&amp;gt; to construct a cluster wrt. &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;MinPts&amp;lt;/math&amp;gt; containing &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;FUNCTION\ expand\_cluster(x,X,\varepsilon, MinPts):&amp;lt;/math&amp;gt;&lt;br /&gt;
    &amp;lt;math&amp;gt;retrive\_\varepsilon neighborhood(x, \varepsilon)&amp;lt;/math&amp;gt;;&lt;br /&gt;
    &amp;lt;math&amp;gt;IF \mid N_{\varepsilon}(x) \mid &amp;lt; MinPts&amp;lt;/math&amp;gt; //т.е. &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; - не ядровой объект&lt;br /&gt;
       mark &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; as &amp;lt;math&amp;gt;noise&amp;lt;/math&amp;gt;  and &amp;lt;math&amp;gt;RETURN&amp;lt;/math&amp;gt;;&lt;br /&gt;
    &amp;lt;math&amp;gt;ELSE&amp;lt;/math&amp;gt;//т.е. &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; - ядровой объект&lt;br /&gt;
       select a new cluster-id and mark all objects in &amp;lt;math&amp;gt;N_{\varepsilon}(x)&amp;lt;/math&amp;gt; with this current &amp;lt;math&amp;gt;cluster-id&amp;lt;/math&amp;gt;; &lt;br /&gt;
       push all objects from &amp;lt;math&amp;gt;N_{\varepsilon}(x)&amp;lt;/math&amp;gt;\&amp;lt;math&amp;gt;(x)&amp;lt;/math&amp;gt; onto the stack seeds;&lt;br /&gt;
       &amp;lt;math&amp;gt;WHILE\ NOT&amp;lt;/math&amp;gt; seeds.empty() &amp;lt;math&amp;gt;DO&amp;lt;/math&amp;gt; &lt;br /&gt;
         &amp;lt;math&amp;gt;currentObject&amp;lt;/math&amp;gt; := seeds.top();&lt;br /&gt;
         seeds.pop();&lt;br /&gt;
         &amp;lt;math&amp;gt;retrive\_\varepsilon neighborhood(currentObject, \varepsilon)&amp;lt;/math&amp;gt;;&lt;br /&gt;
         &amp;lt;math&amp;gt;IF \mid N_{\varepsilon}(currentObjects) \mid \ge MinPts&amp;lt;/math&amp;gt;&lt;br /&gt;
           select all objects in &amp;lt;math&amp;gt;N_{\varepsilon}(currentObject)&amp;lt;/math&amp;gt; not yet classified or marked as &amp;lt;math&amp;gt;noise&amp;lt;/math&amp;gt;,&lt;br /&gt;
           push the unclassified objects onto seeds and mark all of these objects with current &amp;lt;math&amp;gt;cluster-id&amp;lt;/math&amp;gt;;&lt;br /&gt;
     &amp;lt;math&amp;gt;RETURN&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;FUNCTION\ retrive\_\varepsilon neighborhood(x, \varepsilon)&amp;lt;/math&amp;gt; //функция возвращает соседей на основе пространственной структуры данных&lt;br /&gt;
   return &amp;lt;math&amp;gt;\{ x&#039; \ | \ \forall x&#039; \in X: \rho(x, x&#039;) &amp;lt; \varepsilon \}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Для того, чтобы алгоритм мог кластеризовать все объекты, необходимо пройти по каждому из них хотя бы один раз. Если использовать специальную пространственную структуру данных для определения соседних объектов со сложностью &amp;lt;math&amp;gt;O(\log n)&amp;lt;/math&amp;gt;, то сложность алгоритма &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt;. Если не использовать  пространственную структуру данных, то в худшем случае алгоритм будет иметь сложность &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, так как придется считать полную матрицу расстояний между объектами.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
В настоящем алгоритме осуществляется параллелизм по данным. Ниже представлена общая структура данного алгоритма. &lt;br /&gt;
[[File:dbscan_schema1.jpg|500px|thumb|center|Рис.1. Общая информационная структура алгоритма]]&lt;br /&gt;
Разбиение данных происходит с помощью пространственной структуры данных (R*-дерево, kd-дерево), которая разбивает все множество объектов &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; частей: &amp;lt;math&amp;gt;X_1,X_2,...,X_m&amp;lt;/math&amp;gt;.&lt;br /&gt;
[[File:dbscan_clusters_partitions.png|500px|thumb|center|Рис.2. Пример разбиения объектов на части на основе пространственной структуры]]&lt;br /&gt;
Далее на каждой части объектов применяется алгоритм PDBSCAN (каждая часть использует пространственную структуру данных, которая распределяется вместе с каждой частью данных), структура которого представлена ниже.&lt;br /&gt;
[[File:dbscan_schema2.jpg|500px|thumb|center|Рис.3. Информационная структура алгоритма PDBSCAN]]&lt;br /&gt;
Данный алгоритм отличается от общего алгоритма DBSCAN тем, что применяется к части объектов и для каждой из этих частей определяет кандидатов на слияние. Если для ядрового объекта части &amp;lt;math&amp;gt;X_i&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-окрестности находится объект из другой части &amp;lt;math&amp;gt;X_j&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;O(m)&amp;lt;/math&amp;gt;, где m - количество частей, на которые разбиваются все входное множество объектов &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;. Высотой ярусно-параллельной формы алгоритма является &amp;lt;math&amp;gt;O(|X| \log |X|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\mid X \mid&amp;lt;/math&amp;gt; - максимальное количество среди числа объектов в каждой части разбиения. Именно такую сложность имеет алгоритм PDBSCAN, применяемый к каждой отдельной части разбиения.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: множество точек X из n-мерного пространства, на котором определена функция расстояния D. В наиболее распространенном случае пространственной кластеризации используется Евлидова метрика между векторами из &amp;lt;math&amp;gt;{R}^n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: n (размерность входящего множества)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: размеченное множество точек X, в котором каждой точке соответствует номер ее кластера. Обычно каждой точке из X сопоставляется ее номер, а на выходе алгоритм дает отображение номеров точек в номера соответствующих им кластеров, например в виде вектора размера |X|&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: n (размерность выходящего множества)&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039; Преимущества алгоритма &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* алгоритм может обрабатывать большой объем данных и не зависит от порядка ввода данных;&lt;br /&gt;
* может определять кластера произвольной формы; &lt;br /&gt;
* параллельная реализация сбалансирована по количеству и виду производимых операций (вычисление расстояния, сравнение с &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;);&lt;br /&gt;
* не требуется задание числа кластеров;&lt;br /&gt;
* может выделять кластеры в присутствии «шума»и выбросов &amp;lt;ref&amp;gt;АЛГОРИТМЫ КЛАСТЕРИЗАЦИИ В ЗАДАЧАХ СЕГМЕНТАЦИИ&lt;br /&gt;
СПУТНИКОВЫХ ИЗОБРАЖЕНИЙ/ И. А. Пестунов, Ю. Н. Синявский// Вестник Кемеровского государственного университета. – 2012. – P. 263–&lt;br /&gt;
299.&amp;lt;/ref&amp;gt;;&lt;br /&gt;
* число итераций определяется заранее.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039; Недостатки алгоритма &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* не может выделять кластеры сложной структуры, например, имеющие разную плотность, так как параметры алгоритма не могут быть выбраны отдельно для каждого кластера;&lt;br /&gt;
* не может построить иерархическую структуру кластеров;&lt;br /&gt;
* не детерминирован, так как граничные точки, достижимые из более, чем одного кластера, могут быть частью любого из них в зависимости от порядка обрабатываемых данных. Однако такая ситуация возникает редко, а относительно ядровых точек и шума DBSCAN детерминирован.&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;
* [http://scikit-learn.org/stable/modules/generated/sklearn.cluster.DBSCAN.html Scikit learn (Python, последовательная реализация)]&lt;br /&gt;
* [http://cucis.ece.northwestern.edu/projects/Clustering/download_code_dbscan.html Northwestern University (C++, параллельная реализация kd-tree)]&lt;br /&gt;
* [https://github.com/ContinuumIO/parallel_dbscan github/ContinuumIO (Python, параллельная реализация)]&lt;br /&gt;
* [https://github.com/propanoid/DBSCAN github/propanoid (C++, последовательная реализация VP tree)]&lt;br /&gt;
* [https://github.com/dparks1134/DBSCAN github/dparks1134 (С++, последовательная реализация)]&lt;br /&gt;
* [https://github.com/ahbarnett/validspike/tree/master/contrib/dbscan_patwary Disjoint-Set Data Structure based Parallel DBSCAN (C++ параллельная реализация kd-tree)]&lt;br /&gt;
* [https://github.com/bwoneill/pypardis github/bwoneill (Spark/Python параллельная реализация kd-tree)]&lt;br /&gt;
* [https://github.com/alitouka/spark_dbscan github/alitouka (Spark/Scala параллельная реализация)]&lt;br /&gt;
* [https://github.com/mhahsler/dbscan CRAN (R, последовательная реализация)]&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;br /&gt;
&amp;lt;references \&amp;gt;[https://pdfs.semanticscholar.org/a3f8/a3948e5999def4a0819d0dbaef2ae05e1599.pdf (A Fast Parallel Clustering Algorithm for Large Spatial Databases, JOCHEN JAGER, HANS-PETER KRIEGEL)]&lt;br /&gt;
&amp;lt;references \&amp;gt;[http://cyberleninka.ru/article/n/algoritmy-klasterizatsii-v-zadachah-segmentatsii-sputnikovyh-izobrazheniy (АЛГОРИТМЫ КЛАСТЕРИЗАЦИИ В ЗАДАЧАХ СЕГМЕНТАЦИИ СПУТНИКОВЫХ ИЗОБРАЖЕНИЙ, Пестунов Игорь Алексеевич, Синявский Юрий Николаевич)]&lt;br /&gt;
&lt;br /&gt;
[[en:Cholesky decomposition]]&lt;br /&gt;
&lt;br /&gt;
[[Категория:Законченные статьи]]&lt;/div&gt;</summary>
		<author><name>Sleo</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%96%D0%B0%D0%BD%D0%BD%D0%B0%D1%82_%D0%A1%D0%B0%D0%B3%D0%B8%D0%BE%D0%BB%D0%B4%D0%B0%D0%BD%D0%BE%D0%B2%D0%B0&amp;diff=14031</id>
		<title>Обсуждение участницы:Жаннат Сагиолданова</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%96%D0%B0%D0%BD%D0%BD%D0%B0%D1%82_%D0%A1%D0%B0%D0%B3%D0%B8%D0%BE%D0%BB%D0%B4%D0%B0%D0%BD%D0%BE%D0%B2%D0%B0&amp;diff=14031"/>
		<updated>2016-10-26T14:32:53Z</updated>

		<summary type="html">&lt;p&gt;Sleo: Новая страница: «Замечания к оформлению статьи:  0. Если рисунок не ваш, то требуется указать ссылку на рес…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Замечания к оформлению статьи:&lt;br /&gt;
&lt;br /&gt;
0. Если рисунок не ваш, то требуется указать ссылку на ресурс, откуда он был взят. &lt;br /&gt;
&lt;br /&gt;
1. Пункт 1.3 стоит расписать подробнее. Например, привести основные операции, которые применяются выч. ядре алгоритма.&lt;br /&gt;
&lt;br /&gt;
2. Пункт 1.6: &amp;quot;Если использовать специальную пространственную структуру данных&amp;quot; - поясните термин.&lt;br /&gt;
&lt;br /&gt;
3. Пункт 1.5 стоит подписать комментарии к всем трем блокам псевдокода.&lt;br /&gt;
&lt;br /&gt;
4. Почему в пункте 1.9 два описания входных и выходных данных?&lt;br /&gt;
&lt;br /&gt;
5. В постановке задачи имелось ввиду более подробное графическое описание информационного графа. (см. пример: https://algowiki-project.org/ru/%D0%A0%D0%B0%D0%B7%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%A5%D0%BE%D0%BB%D0%B5%D1%86%D0%BA%D0%BE%D0%B3%D0%BE_(%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D0%BA%D0%B2%D0%B0%D0%B4%D1%80%D0%B0%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BA%D0%BE%D1%80%D0%BD%D1%8F)&lt;br /&gt;
&lt;br /&gt;
6. Не указан вклад каждого из авторов статьи. &lt;br /&gt;
&lt;br /&gt;
7. Вычислительная мощность не приведена. (см. пример: https://algowiki-project.org/ru/%D0%A0%D0%B0%D0%B7%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%A5%D0%BE%D0%BB%D0%B5%D1%86%D0%BA%D0%BE%D0%B3%D0%BE_(%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D0%BA%D0%B2%D0%B0%D0%B4%D1%80%D0%B0%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BA%D0%BE%D1%80%D0%BD%D1%8F)&lt;/div&gt;</summary>
		<author><name>Sleo</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Ramon93i7&amp;diff=14029</id>
		<title>Обсуждение участника:Ramon93i7</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Ramon93i7&amp;diff=14029"/>
		<updated>2016-10-26T14:31:29Z</updated>

		<summary type="html">&lt;p&gt;Sleo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Замечания к оформлению статьи:&lt;br /&gt;
&lt;br /&gt;
0. Если рисунок не ваш, то требуется указать ссылку на ресурс, откуда он был взят. &lt;br /&gt;
&lt;br /&gt;
1. В пунтке 1.1 не указано ни одного свойства алгоритма. (см. пример: https://algowiki-project.org/ru/%D0%A0%D0%B0%D0%B7%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%A5%D0%BE%D0%BB%D0%B5%D1%86%D0%BA%D0%BE%D0%B3%D0%BE_(%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D0%BA%D0%B2%D0%B0%D0%B4%D1%80%D0%B0%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BA%D0%BE%D1%80%D0%BD%D1%8F)&lt;br /&gt;
&lt;br /&gt;
2. Пункт 1.3 стоит расписать подробнее. привести, например, формулы нахождения расстояния между любыми двумя точками множества X по заданной метрике и т.д.&lt;br /&gt;
&lt;br /&gt;
3. Пункт 1.5 стоит подписать комментарии к трем блокам псевдокода.&lt;br /&gt;
&lt;br /&gt;
4. Почему в таблицу в начале выделено  O(n^2), а не O(n \log n), как в пункте 1.6.&lt;br /&gt;
&lt;br /&gt;
5. В постановке задачи имелось ввиду более подробное графическое описание информационного графа. (см. пример: https://algowiki-project.org/ru/%D0%A0%D0%B0%D0%B7%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%A5%D0%BE%D0%BB%D0%B5%D1%86%D0%BA%D0%BE%D0%B3%D0%BE_(%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D0%BA%D0%B2%D0%B0%D0%B4%D1%80%D0%B0%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BA%D0%BE%D1%80%D0%BD%D1%8F)&lt;br /&gt;
&lt;br /&gt;
6. Не указан вклад каждого из авторов статьи.&lt;br /&gt;
&lt;br /&gt;
7. Не приведены:&lt;br /&gt;
Высота ярусно-параллельной формы	-&lt;br /&gt;
Ширина ярусно-параллельной формы	-&lt;br /&gt;
&lt;br /&gt;
8. Вычислительная мощность не приведена. (см. пример: https://algowiki-project.org/ru/%D0%A0%D0%B0%D0%B7%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%A5%D0%BE%D0%BB%D0%B5%D1%86%D0%BA%D0%BE%D0%B3%D0%BE_(%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D0%BA%D0%B2%D0%B0%D0%B4%D1%80%D0%B0%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BA%D0%BE%D1%80%D0%BD%D1%8F)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
- Должны быть указаны авторы статьи (ФИО); если статья выполняется более чем одним автором, должен быть указан вклад каждого. (не указано).&lt;/div&gt;</summary>
		<author><name>Sleo</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Ramon93i7&amp;diff=14028</id>
		<title>Обсуждение участника:Ramon93i7</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Ramon93i7&amp;diff=14028"/>
		<updated>2016-10-26T14:28:21Z</updated>

		<summary type="html">&lt;p&gt;Sleo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Замечания к оформлению статьи:&lt;br /&gt;
&lt;br /&gt;
0. Если рисунок не ваш, то требуется указать ссылку на ресурс, откуда он был взят. &lt;br /&gt;
&lt;br /&gt;
1. В пунтке 1.1 не указано ни одного свойства алгоритма. (см. пример: https://algowiki-project.org/ru/%D0%A0%D0%B0%D0%B7%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%A5%D0%BE%D0%BB%D0%B5%D1%86%D0%BA%D0%BE%D0%B3%D0%BE_(%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D0%BA%D0%B2%D0%B0%D0%B4%D1%80%D0%B0%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BA%D0%BE%D1%80%D0%BD%D1%8F)&lt;br /&gt;
&lt;br /&gt;
2. Пункт 1.3 стоит расписать подробнее. привести, например, формулы нахождения расстояния между любыми двумя точками множества X по заданной метрике и т.д.&lt;br /&gt;
&lt;br /&gt;
3. Пункт 1.5 стоит подписать комментарии к трем блокам псевдокода.&lt;br /&gt;
&lt;br /&gt;
4. Почему в таблицу в начале выделено  O(n^2), а не O(n \log n), как в пункте 1.6.&lt;br /&gt;
&lt;br /&gt;
5. В постановке задачи имелось ввиду более подробное графическое описание информационного графа. (см. пример: https://algowiki-project.org/ru/%D0%A0%D0%B0%D0%B7%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%A5%D0%BE%D0%BB%D0%B5%D1%86%D0%BA%D0%BE%D0%B3%D0%BE_(%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D0%BA%D0%B2%D0%B0%D0%B4%D1%80%D0%B0%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BA%D0%BE%D1%80%D0%BD%D1%8F)&lt;br /&gt;
&lt;br /&gt;
6. Не указан вклад каждого из авторов статьи.&lt;br /&gt;
&lt;br /&gt;
7. Не приведены:&lt;br /&gt;
Высота ярусно-параллельной формы	-&lt;br /&gt;
Ширина ярусно-параллельной формы	-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
- Должны быть указаны авторы статьи (ФИО); если статья выполняется более чем одним автором, должен быть указан вклад каждого. (не указано).&lt;/div&gt;</summary>
		<author><name>Sleo</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Ramon93i7&amp;diff=14027</id>
		<title>Обсуждение участника:Ramon93i7</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Ramon93i7&amp;diff=14027"/>
		<updated>2016-10-26T14:24:56Z</updated>

		<summary type="html">&lt;p&gt;Sleo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Замечания к оформлению статьи:&lt;br /&gt;
&lt;br /&gt;
0. Если рисунок не ваш, то требуется указать ссылку на ресурс, откуда он был взят. &lt;br /&gt;
&lt;br /&gt;
1. В пунтке 1.1 не указано ни одного свойства алгоритма. (см. пример: https://algowiki-project.org/ru/%D0%A0%D0%B0%D0%B7%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%A5%D0%BE%D0%BB%D0%B5%D1%86%D0%BA%D0%BE%D0%B3%D0%BE_(%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D0%BA%D0%B2%D0%B0%D0%B4%D1%80%D0%B0%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BA%D0%BE%D1%80%D0%BD%D1%8F)&lt;br /&gt;
&lt;br /&gt;
2. Пункт 1.3 стоит расписать подробнее. привести, например, формулы нахождения расстояния между любыми двумя точками множества X по заданной метрике и т.д.&lt;br /&gt;
&lt;br /&gt;
3. Пункт 1.5 стоит подписать комментарии к трем блокам псевдокода.&lt;br /&gt;
&lt;br /&gt;
4. Почему в таблицу в начале выделено  O(n^2), а не O(n \log n), как в пункте 1.6.&lt;br /&gt;
&lt;br /&gt;
5. В постановке задачи имелось ввиду более подробное графическое описание информационного графа. (см. пример: https://algowiki-project.org/ru/%D0%A0%D0%B0%D0%B7%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%A5%D0%BE%D0%BB%D0%B5%D1%86%D0%BA%D0%BE%D0%B3%D0%BE_(%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D0%BA%D0%B2%D0%B0%D0%B4%D1%80%D0%B0%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BA%D0%BE%D1%80%D0%BD%D1%8F)&lt;br /&gt;
&lt;br /&gt;
6. Не указан вклад каждого из авторов статьи. (пункт 1.10). &lt;br /&gt;
&lt;br /&gt;
7. Не приведены:&lt;br /&gt;
Высота ярусно-параллельной формы	-&lt;br /&gt;
Ширина ярусно-параллельной формы	-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
- Должны быть указаны авторы статьи (ФИО); если статья выполняется более чем одним автором, должен быть указан вклад каждого. (не указано).&lt;/div&gt;</summary>
		<author><name>Sleo</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Ramon93i7&amp;diff=14026</id>
		<title>Обсуждение участника:Ramon93i7</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Ramon93i7&amp;diff=14026"/>
		<updated>2016-10-26T14:21:46Z</updated>

		<summary type="html">&lt;p&gt;Sleo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Замечания к оформлению статьи:&lt;br /&gt;
&lt;br /&gt;
0. Если рисунок не ваш, то требуется указать ссылку на ресурс, откуда он был взят. &lt;br /&gt;
&lt;br /&gt;
1. В пунтке 1.1 не указано ни одного свойства алгоритма. (см. пример: https://algowiki-project.org/ru/%D0%A0%D0%B0%D0%B7%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%A5%D0%BE%D0%BB%D0%B5%D1%86%D0%BA%D0%BE%D0%B3%D0%BE_(%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D0%BA%D0%B2%D0%B0%D0%B4%D1%80%D0%B0%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BA%D0%BE%D1%80%D0%BD%D1%8F)&lt;br /&gt;
&lt;br /&gt;
2. Пункт 1.3 стоит расписать подробнее. привести, например, формулы нахождения расстояния между любыми двумя точками множества X по заданной метрике и т.д.&lt;br /&gt;
&lt;br /&gt;
3. Пункт 1.4 стоит подписать комментарии к трем блокам псевдокода.&lt;br /&gt;
&lt;br /&gt;
4. Почему в таблицу в начале выделено  O(n^2), а не O(n \log n), как в пункте 1.6.&lt;br /&gt;
&lt;br /&gt;
5. В постановке задачи имелось ввиду более подробное графическое описание информационного графа. (см. пример: https://algowiki-project.org/ru/%D0%A0%D0%B0%D0%B7%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%A5%D0%BE%D0%BB%D0%B5%D1%86%D0%BA%D0%BE%D0%B3%D0%BE_(%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D0%BA%D0%B2%D0%B0%D0%B4%D1%80%D0%B0%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BA%D0%BE%D1%80%D0%BD%D1%8F)&lt;br /&gt;
&lt;br /&gt;
6. Не указан вклад каждого из авторов статьи. (пункт 1.10). &lt;br /&gt;
&lt;br /&gt;
7. Не приведены:&lt;br /&gt;
Высота ярусно-параллельной формы	-&lt;br /&gt;
Ширина ярусно-параллельной формы	-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
- Должны быть указаны авторы статьи (ФИО); если статья выполняется более чем одним автором, должен быть указан вклад каждого. (не указано).&lt;/div&gt;</summary>
		<author><name>Sleo</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:Dadrik/%D0%9F%D0%BB%D0%BE%D1%82%D0%BD%D0%BE%D1%81%D1%82%D0%BD%D1%8B%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8&amp;diff=14025</id>
		<title>Участник:Dadrik/Плотностный алгоритм кластеризации</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:Dadrik/%D0%9F%D0%BB%D0%BE%D1%82%D0%BD%D0%BE%D1%81%D1%82%D0%BD%D1%8B%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8&amp;diff=14025"/>
		<updated>2016-10-26T14:20:08Z</updated>

		<summary type="html">&lt;p&gt;Sleo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Плотностный алгоритм кластеризации DBSCAN&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Авторы описания: [[Участник:Dadrik | Вашуров И.М.]], [[Участник:ramon93i7 | Шемякин Р.О.]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Задача кластеризации - это задача разбиения заданной входной выборки объектов на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из схожих объектов, а объекты разных кластеров существенно отличались.&lt;br /&gt;
&lt;br /&gt;
Алгоритм DBSCAN (Density-based spatial clustering of applications with noise)&amp;lt;ref&amp;gt;Ester, Martin, et al. &amp;quot;A density-based algorithm for discovering clusters in large spatial databases with noise.&amp;quot; Kdd. Vol. 96. No. 34. 1996.&amp;lt;/ref&amp;gt; был предложен Мартином Эстер, Гансом-Питером Кригель и коллегами в 1996 году как решение задачи кластеризации с кластерами произвольной формы. DBSCAN является непараметрическим плотностным алгоритмом кластеризации: для заданного набора точек в некотором пространстве, алгоритм группирует те точки, которые расположены достаточно близко друг к другу (точки с большим количеством соседей), и помечает как выбросы те, что располагаются далеко от ближайших соседей.&lt;br /&gt;
&lt;br /&gt;
Близость в алгоритме определяется заданной в пространстве метрикой. Наиболее часто в качестве метрики используются Евклидово расстояние, квадрат Евклидова расстояния, манхэттенская метрика, расстояние Чебышева или степенное расстояние.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Вход алгоритма: множество точек &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;-мерного пространства, на котором определена функция расстояния &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Выход алгоритма: размеченное множество точек &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;, в котором каждой точке соответствует номер ее кластера.&lt;br /&gt;
&lt;br /&gt;
Параметры алгоритма: &lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; - максимальное расстояние между соседями;&lt;br /&gt;
* &amp;lt;math&amp;gt;MinPts&amp;lt;/math&amp;gt; - минимальное количество соседей для создания области связности.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Определения ===&lt;br /&gt;
&lt;br /&gt;
[[File:Cluster_scheme.png|thumb|right|400px| Рис. 1. Здесь &#039;&#039;MinPts&#039;&#039; = 4. Точка &#039;&#039;A&#039;&#039; и другие красные точки - ядровые и образуют единый кластер, так как достижимы друг из друга. Точки &#039;&#039;B&#039;&#039; и &#039;&#039;C&#039;&#039; не являются ядровыми, но достижимы из &#039;&#039;A&#039;&#039;, а значит также принадлежат кластеру. Точка &#039;&#039;N&#039;&#039; - не достижима из других точек и является шумом.]]&lt;br /&gt;
&lt;br /&gt;
Все заданные точки классифицируются на три группы:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;ядровые точки&#039;&#039;: точка &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; является ядровой, если количество &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей, включая саму точку &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, не меньше &amp;lt;math&amp;gt;MinPts&amp;lt;/math&amp;gt;. Под &#039;&#039;&amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседями&#039;&#039; точки &amp;lt;math&amp;gt;p \in X&amp;lt;/math&amp;gt; понимается множество точек, расстояние до которых не превышает &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;N_\varepsilon(p) = \{ x \in X | D(p, x) \le \varepsilon \}&amp;lt;/math&amp;gt;. Эти точки являются напрямую достижимыми из &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;достижимые точки&#039;&#039;: точка &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; достижима из &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, если  существует путь &amp;lt;math&amp;gt;p_1, \dots, p_n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;p_1 = p&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_n = q&amp;lt;/math&amp;gt;, для которого выполнено: &lt;br /&gt;
:&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
p_{i + 1} \in N_\varepsilon(p_i),  i = 1, \dots, n-1 \\&lt;br /&gt;
| N_\varepsilon(p_{i}) | \ge MinPts, i = 1, \dots, n-1 \\&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;шум&#039;&#039; (выбросы): все точки, недостижимые из какой-либо другой точки считаются шумом (выбросом).&lt;br /&gt;
&lt;br /&gt;
Так, если &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - ядровая точка, то она образует кластер вместе со всеми точками, достижимыми из неё. Каждый кластер содержит по крайней мере одну ядровую точку; неядровые точки могут быть частью кластера, образуя при этом его &amp;quot;границу&amp;quot;, так как они не могут быть использованы для достижения других точек.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Достижимость не является симметричным отношением, так как по определению никакая точка не может быть достижима из неядровой точки, независимо от расстояния. Поэтому в DBSCAN применяется следующий термин &#039;&#039;связности&#039;&#039;: две точки &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; связанны, если существует такая точка &amp;lt;math&amp;gt;o&amp;lt;/math&amp;gt;, что &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; достижимы из &amp;lt;math&amp;gt;o&amp;lt;/math&amp;gt;. Такое отношение связности симметрично.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Кластер&#039;&#039; в таком случае определяется двумя свойствами:&lt;br /&gt;
* Все точки внутри кластера взаимно связанны;&lt;br /&gt;
* Если точка достижима из любой точки кластера, она также является частью кластера.&lt;br /&gt;
&lt;br /&gt;
=== Шаги алгоритма ===&lt;br /&gt;
&lt;br /&gt;
#Выбирается произвольная непосещенная точка &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;.&lt;br /&gt;
#Точка &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; помечается как посещенная. &lt;br /&gt;
#У точки &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; определяется множество её &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей - &amp;lt;math&amp;gt;N_\varepsilon(p)&amp;lt;/math&amp;gt;.&lt;br /&gt;
#*Если точка &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; оказалась ядровой - &amp;lt;math&amp;gt;| N_\varepsilon(p) | \ \ge MinPts&amp;lt;/math&amp;gt;, то: &lt;br /&gt;
#**она становится началом нового кластера или сохраняет номер кластера, который был ей присвоен ранее; &lt;br /&gt;
#**все точки из &amp;lt;math&amp;gt;N_\varepsilon(p)&amp;lt;/math&amp;gt; добавляются в её кластер;&lt;br /&gt;
#**процесс продолжается рекурсивно для каждой новой добавленной непосещенной точки &amp;lt;math&amp;gt;p&#039; \in N_\varepsilon(p)&amp;lt;/math&amp;gt; c шага 2 (в качестве новой &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).&lt;br /&gt;
#*Если точка &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; оказалась не ядровой, то &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; объявляется шумом. Алгоритм продолжается с шага 4.&lt;br /&gt;
#Если остались непосещенные точки, то алгоритм продолжается с шага 1.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром алгоритма является нахождение &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей каждой точки входного множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для решения этой задачи требуется найти расстояния между любыми двумя точками множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; по заданной метрике.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как записано и в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть метода составляют вызовы функции &amp;lt;math&amp;gt;request\_neighbours&amp;lt;/math&amp;gt; получения &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей и нахождение расстояний между точками множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;DBSCAN(X, \varepsilon, MinPts)&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;C = 0&amp;lt;/math&amp;gt;&lt;br /&gt;
   for &amp;lt;math&amp;gt;\forall p \in X&amp;lt;/math&amp;gt;&lt;br /&gt;
      if &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; is visited then&lt;br /&gt;
         continue&lt;br /&gt;
      mark &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; as visited&lt;br /&gt;
      &amp;lt;math&amp;gt;neighbours&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;request\_neighbours(p, \varepsilon)&amp;lt;/math&amp;gt;&lt;br /&gt;
      if &amp;lt;math&amp;gt;| neighbours | &amp;lt; MinPts&amp;lt;/math&amp;gt; then&lt;br /&gt;
         mark &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; as &amp;lt;math&amp;gt;NOISE&amp;lt;/math&amp;gt;&lt;br /&gt;
      else&lt;br /&gt;
         &amp;lt;math&amp;gt;C = next\_cluster&amp;lt;/math&amp;gt;&lt;br /&gt;
         &amp;lt;math&amp;gt;expand\_cluster(p, neighbours, C, \varepsilon, MinPts)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;expand\_cluster(p, neighbours, C, \varepsilon, MinPts)&amp;lt;/math&amp;gt;&lt;br /&gt;
   add &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; to cluster &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;&lt;br /&gt;
   for &amp;lt;math&amp;gt;\forall p&#039; \in neighbours&amp;lt;/math&amp;gt;&lt;br /&gt;
      if &amp;lt;math&amp;gt;p&#039;&amp;lt;/math&amp;gt; is not visited &lt;br /&gt;
         mark &amp;lt;math&amp;gt;p&#039;&amp;lt;/math&amp;gt; as visited&lt;br /&gt;
         &amp;lt;math&amp;gt;neighbours&#039;&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;request\_neighbours(p, \varepsilon)&amp;lt;/math&amp;gt;&lt;br /&gt;
         if &amp;lt;math&amp;gt;| neighbours&#039; | \ \ge MinPts&amp;lt;/math&amp;gt;&lt;br /&gt;
            &amp;lt;math&amp;gt;neighbours&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;neighbours \cup neighbours&#039;&amp;lt;/math&amp;gt;  &lt;br /&gt;
      if &amp;lt;math&amp;gt;p&#039;&amp;lt;/math&amp;gt; is not yet member of any cluster&lt;br /&gt;
         add &amp;lt;math&amp;gt;p&#039;&amp;lt;/math&amp;gt; to cluster &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;request\_neighbours(p, \varepsilon)&amp;lt;/math&amp;gt;&lt;br /&gt;
   return &amp;lt;math&amp;gt;\{ p&#039; \ | \ \forall p&#039; \in X: D(p, p&#039;) &amp;lt; \varepsilon \}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
DBSCAN проходит через каждую точку входного множества, возможно, по несколько раз. Временная сложность зависит в большей степени от вызова функции &amp;lt;math&amp;gt;request\_neighbours&amp;lt;/math&amp;gt; (нахождение &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей для заданной точки). Эта функция вызывается ровно один раз для каждой точки множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если использовать индексированную структуру данных (например, R-деревья), выполяющую операцию &amp;lt;math&amp;gt;request\_neighbours&amp;lt;/math&amp;gt; за &amp;lt;math&amp;gt;O(\log n)&amp;lt;/math&amp;gt;, то суммарная сложность алгоритма в среднем составит &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt;, с учётом хорошо подобранного параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;, такого что в среднем &amp;lt;math&amp;gt;request\_neighbours&amp;lt;/math&amp;gt; возвращает &amp;lt;math&amp;gt;O(\log n)&amp;lt;/math&amp;gt; точек. Без использования ускоряющих структур или на вырожденных данных (таких, что все точки находятся на расстоянии меньшем, чем &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; друг от друга) сложность по времени в худшем случае будет &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Расстояния между точками можно вычислить заранее за &amp;lt;math&amp;gt;O(\frac {n(n - 1)}{2})&amp;lt;/math&amp;gt;, например в виде матрицы расстояний, но это потребует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; памяти. Иначе, расстояния будут вычисляться при каждом запуске функции &amp;lt;math&amp;gt;request\_neighbours&amp;lt;/math&amp;gt; за &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; и потребуют &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; памяти. Итоговая сложность вычисления расстояний в таком случае составляет &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;. Сложность рассчета расстояний зависит от природы объектов из &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; и заданной метрики &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;. Например, если &amp;lt;math&amp;gt;X\subset\mathbb{R}^m&amp;lt;/math&amp;gt;, то сложность равна &amp;lt;math&amp;gt;O(m)&amp;lt;/math&amp;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;
[[File:Dbscan abstract.png |thumb|right|320px| Рис. 2. Внешний цикл алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На рис. 2 изображен информационный граф внешнего цикла алгоритма, который соответствует коду основной функции &amp;lt;math&amp;gt;DBSCAN&amp;lt;/math&amp;gt;:&lt;br /&gt;
*Макрооперация &#039;&#039;Init&#039;&#039; заключается в получении множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; и инициирования вспомогательных структур. &lt;br /&gt;
*Макрооперация &#039;&#039;Choose&#039;&#039; производит выбор непосещенной точки из &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Макрооперация &#039;&#039;Build cluster&#039;&#039; строит кластер, если точка ядровая, или объявляет ее шумом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Переход от &#039;&#039;Build cluster&#039;&#039; к &#039;&#039;Choose&#039;&#039; заключает в себе зависимость данных о принадлежности некоторых точек к текущему кластеру или шуму и об их посещенности.&lt;br /&gt;
&lt;br /&gt;
[[File:Expand cluster 2.png |thumb|right|600px| Рис. 3. Расширение кластера.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На рис. 3 изображен информационный граф алгоритма расширения кластера из начальной точки кластера:&lt;br /&gt;
*Макрооперация &#039;&#039;Init&#039;&#039; заключается в создании кластера из его начальной вершины.&lt;br /&gt;
*Макрооперация &#039;&#039;Nε&#039;&#039; вычисляет множество &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей.&lt;br /&gt;
*Желтым цветом обозначены узлы, в которых точки из &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей классифицируются на ядровые, граничные точки и шум. В рамках операции для конкретного соседа вычисляется множество его &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей.&lt;br /&gt;
*Макрооперации &#039;&#039;Ñε&#039;&#039;, &#039;&#039;Ňε&#039;&#039;, ... производят объединение входных множеств.&lt;br /&gt;
*Макрооперация &#039;&#039;Ø&#039;&#039; выполняется тогда, когда объединение входных множеств является пустым.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:N eps 3.png         |thumb|right|320px| Рис. 4. Подсчет &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей.]]&lt;br /&gt;
&lt;br /&gt;
На рис. 4 изображен информационный граф алгоритма вычисления множества &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей:&lt;br /&gt;
*Операция &#039;&#039;D&#039;&#039; - вычисление расстояния между точками.&lt;br /&gt;
*Операция &#039;&#039;ε&#039;&#039; - сравнение расстояния с ε.&lt;br /&gt;
*Операция &#039;&#039;U&#039;&#039; - объединение результатов.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Поиск &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей требует вычисления &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; расстояний (функция &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;) и выполнения &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений с &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Эти операции для каждой пары точек независимы и могут быть выполнены параллельно. Таким образом, при наличии неограниченного числа процессоров сложность поиска составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;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;
Вход алгоритма: множество точек X из n-мерного пространства, на котором определена функция расстояния D. В наиболее распространенном случае пространственной кластеризации используется Евлидово расстояние между векторами из &amp;lt;math&amp;gt;\mathbb{R}^n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Выход алгоритма: размеченное множество точек &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;, в котором каждой точке соответствует номер ее кластера. Обычно каждой точке из &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; сопоставляется ее номер, а на выходе алгоритм дает отображение номеров точек в номера соответствующих им кластеров, например в виде вектора размера &amp;lt;math&amp;gt;|X|&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;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
=== Недостатки алгоритма ===&lt;br /&gt;
&lt;br /&gt;
# не детерминирован: граничные точки, достижимые из более, чем одного кластера, могут быть частью любого из них в зависимости от порядка обрабатываемых данных. Однако такая ситуация возникает редко, а относительно ядровых точек и шума DBSCAN детерминирован. Впрочем, от недетерминизма можно избавиться, если считать все граничные точки шумом (алгоритм DBSCAN*);&lt;br /&gt;
# качество алгоритма зависит от используемой функции расстояния &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;. Наиболее часто используемое Евклидово расстояние в многомерных множествах может оказаться практически бесполезным из-за так называемого &amp;quot;проклятия размерности&amp;quot;, значительно затрудняя нахождение подходящего значения &amp;lt;math&amp;gt;\varepsilon&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;
!!! ЭКСПЕРИМЕНТЫ ДО 15 НОЯБРЯ !!!&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
* [http://scikit-learn.org/stable/modules/generated/sklearn.cluster.DBSCAN.html Scikit learn (Python)]&lt;br /&gt;
* [https://cran.r-project.org/web/packages/dbscan/dbscan.pdf R-project] ([https://github.com/mhahsler/dbscan github])&lt;br /&gt;
* [https://www.mathworks.com/matlabcentral/fileexchange/52905-dbscan-clustering-algorithm Matlab]&lt;br /&gt;
* P-DBSCAN (Parallel DBSCAN)&amp;lt;ref&amp;gt;Chen, Min, Xuedong Gao, and HuiFei Li. &amp;quot;Parallel DBSCAN with priority r-tree.&amp;quot; Information Management and Engineering (ICIME), 2010 The 2nd IEEE International Conference on. IEEE, 2010.&amp;lt;/ref&amp;gt;&lt;br /&gt;
* Parallel DBSCAN with MPI&amp;lt;ref&amp;gt;Savvas, Ilias K., and Dimitrios Tselios. &amp;quot;Parallelizing DBSCaN Algorithm Using MPI.&amp;quot; Enabling Technologies: Infrastructure for Collaborative Enterprises (WETICE), 2016 IEEE 25th International Conference on. IEEE, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
* PDSDBSCAN (Parallel Disjoint-Set DBSCAN)&amp;lt;ref&amp;gt;Patwary, Md Mostofa Ali, et al. &amp;quot;A new scalable parallel DBSCAN algorithm using the disjoint-set data structure.&amp;quot; High Performance Computing, Networking, Storage and Analysis (SC), 2012 International Conference for. IEEE, 2012.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sleo</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Ramon93i7&amp;diff=14024</id>
		<title>Обсуждение участника:Ramon93i7</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Ramon93i7&amp;diff=14024"/>
		<updated>2016-10-26T14:19:05Z</updated>

		<summary type="html">&lt;p&gt;Sleo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Замечания к оформлению статьи:&lt;br /&gt;
&lt;br /&gt;
0. Если рисунок не ваш, то требуется указать ссылку на ресурс, откуда он был взят. &lt;br /&gt;
&lt;br /&gt;
1. В пунтке 1.1 не указано ни одного свойства алгоритма. (см. пример: https://algowiki-project.org/ru/%D0%A0%D0%B0%D0%B7%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%A5%D0%BE%D0%BB%D0%B5%D1%86%D0%BA%D0%BE%D0%B3%D0%BE_(%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D0%BA%D0%B2%D0%B0%D0%B4%D1%80%D0%B0%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BA%D0%BE%D1%80%D0%BD%D1%8F)&lt;br /&gt;
&lt;br /&gt;
2. Пункт 1.3 стоит расписать подробнее. привести, например, формулы нахождения расстояния между любыми двумя точками множества X по заданной метрике и т.д.&lt;br /&gt;
&lt;br /&gt;
3. Пункт 1.4 стоит подписать комментарии к трем блокам псевдокода.&lt;br /&gt;
&lt;br /&gt;
4. Почему в таблицу в начале выделено  O(n^2), а не O(n \log n), как в пункте 1.6.&lt;br /&gt;
&lt;br /&gt;
5. В постановке задачи имелось ввиду более подробное графическое описание информационного графа. (см. пример: https://algowiki-project.org/ru/%D0%A0%D0%B0%D0%B7%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D0%A5%D0%BE%D0%BB%D0%B5%D1%86%D0%BA%D0%BE%D0%B3%D0%BE_(%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D0%BA%D0%B2%D0%B0%D0%B4%D1%80%D0%B0%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BA%D0%BE%D1%80%D0%BD%D1%8F)&lt;br /&gt;
&lt;br /&gt;
6. Не указан вклад каждого из авторов статьи. (пункт 1.10). &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
- Должны быть указаны авторы статьи (ФИО); если статья выполняется более чем одним автором, должен быть указан вклад каждого. (не указано).&lt;/div&gt;</summary>
		<author><name>Sleo</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:Dadrik/%D0%9F%D0%BB%D0%BE%D1%82%D0%BD%D0%BE%D1%81%D1%82%D0%BD%D1%8B%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8&amp;diff=14019</id>
		<title>Участник:Dadrik/Плотностный алгоритм кластеризации</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:Dadrik/%D0%9F%D0%BB%D0%BE%D1%82%D0%BD%D0%BE%D1%81%D1%82%D0%BD%D1%8B%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8&amp;diff=14019"/>
		<updated>2016-10-26T13:42:33Z</updated>

		<summary type="html">&lt;p&gt;Sleo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Плотностный алгоритм кластеризации DBSCAN&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Авторы описания: [[Участник:Dadrik | Вашуров И.М.]], [[Участник:ramon93i7 | Шемякин Р.О.]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Задача кластеризации - это задача разбиения заданной входной выборки объектов на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из схожих объектов, а объекты разных кластеров существенно отличались.&lt;br /&gt;
&lt;br /&gt;
Алгоритм DBSCAN (Density-based spatial clustering of applications with noise)&amp;lt;ref&amp;gt;Ester, Martin, et al. &amp;quot;A density-based algorithm for discovering clusters in large spatial databases with noise.&amp;quot; Kdd. Vol. 96. No. 34. 1996.&amp;lt;/ref&amp;gt; был предложен Мартином Эстер, Гансом-Питером Кригель и коллегами в 1996 году как решение задачи кластеризации с кластерами произвольной формы. DBSCAN является непараметрическим плотностным алгоритмом кластеризации: для заданного набора точек в некотором пространстве, алгоритм группирует те точки, которые расположены достаточно близко друг к другу (точки с большим количеством соседей), и помечает как выбросы те, что располагаются далеко от ближайших соседей.&lt;br /&gt;
&lt;br /&gt;
Близость в алгоритме определяется заданной в пространстве метрикой. Наиболее часто в качестве метрики используются Евклидово расстояние, квадрат Евклидова расстояния, манхэттенская метрика, расстояние Чебышева или степенное расстояние.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Вход алгоритма: множество точек &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;-мерного пространства, на котором определена функция расстояния &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Выход алгоритма: размеченное множество точек &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;, в котором каждой точке соответствует номер ее кластера.&lt;br /&gt;
&lt;br /&gt;
Параметры алгоритма: &lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; - максимальное расстояние между соседями;&lt;br /&gt;
* &amp;lt;math&amp;gt;MinPts&amp;lt;/math&amp;gt; - минимальное количество соседей для создания области связности.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Определения ===&lt;br /&gt;
&lt;br /&gt;
[[File:Cluster_scheme.png|thumb|right|400px| Рис. 1. Здесь &#039;&#039;MinPts&#039;&#039; = 4. Точка &#039;&#039;A&#039;&#039; и другие красные точки - ядровые и образуют единый кластер, так как достижимы друг из друга. Точки &#039;&#039;B&#039;&#039; и &#039;&#039;C&#039;&#039; не являются ядровыми, но достижимы из &#039;&#039;A&#039;&#039;, а значит также принадлежат кластеру. Точка &#039;&#039;N&#039;&#039; - не достижима из других точек и является шумом.]]&lt;br /&gt;
&lt;br /&gt;
Все заданные точки классифицируются на три группы:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;ядровые точки&#039;&#039;: точка &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; является ядровой, если количество &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей, включая саму точку &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, не меньше &amp;lt;math&amp;gt;MinPts&amp;lt;/math&amp;gt;. Под &#039;&#039;&amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседями&#039;&#039; точки &amp;lt;math&amp;gt;p \in X&amp;lt;/math&amp;gt; понимается множество точек, расстояние до которых не превышает &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;N_\varepsilon(p) = \{ x \in X | D(p, x) \le \varepsilon \}&amp;lt;/math&amp;gt;. Эти точки являются напрямую достижимыми из &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;достижимые точки&#039;&#039;: точка &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; достижима из &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, если  существует путь &amp;lt;math&amp;gt;p_1, \dots, p_n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;p_1 = p&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_n = q&amp;lt;/math&amp;gt;, для которого выполнено: &lt;br /&gt;
:&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
p_{i + 1} \in N_\varepsilon(p_i),  i = 1, \dots, n-1 \\&lt;br /&gt;
| N_\varepsilon(p_{i}) | \ge MinPts, i = 1, \dots, n-1 \\&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;шум&#039;&#039; (выбросы): все точки, недостижимые из какой-либо другой точки считаются шумом (выбросом).&lt;br /&gt;
&lt;br /&gt;
Так, если &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - ядровая точка, то она образует кластер вместе со всеми точками, достижимыми из неё. Каждый кластер содержит по крайней мере одну ядровую точку; неядровые точки могут быть частью кластера, образуя при этом его &amp;quot;границу&amp;quot;, так как они не могут быть использованы для достижения других точек.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Достижимость не является симметричным отношением, так как по определению никакая точка не может быть достижима из неядровой точки, независимо от расстояния. Поэтому в DBSCAN применяется следующий термин &#039;&#039;связности&#039;&#039;: две точки &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; связанны, если существует такая точка &amp;lt;math&amp;gt;o&amp;lt;/math&amp;gt;, что &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; достижимы из &amp;lt;math&amp;gt;o&amp;lt;/math&amp;gt;. Такое отношение связности симметрично.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Кластер&#039;&#039; в таком случае определяется двумя свойствами:&lt;br /&gt;
* Все точки внутри кластера взаимно связанны;&lt;br /&gt;
* Если точка достижима из любой точки кластера, она также является частью кластера.&lt;br /&gt;
&lt;br /&gt;
=== Шаги алгоритма ===&lt;br /&gt;
&lt;br /&gt;
#Выбирается произвольная непосещенная точка &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;.&lt;br /&gt;
#Точка &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; помечается как посещенная. &lt;br /&gt;
#У точки &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; определяется множество её &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей - &amp;lt;math&amp;gt;N_\varepsilon(p)&amp;lt;/math&amp;gt;.&lt;br /&gt;
#*Если точка &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; оказалась ядровой - &amp;lt;math&amp;gt;| N_\varepsilon(p) | \ \ge MinPts&amp;lt;/math&amp;gt;, то: &lt;br /&gt;
#**она становится началом нового кластера или сохраняет номер кластера, который был ей присвоен ранее; &lt;br /&gt;
#**все точки из &amp;lt;math&amp;gt;N_\varepsilon(p)&amp;lt;/math&amp;gt; добавляются в её кластер;&lt;br /&gt;
#**процесс продолжается рекурсивно для каждой новой добавленной непосещенной точки &amp;lt;math&amp;gt;p&#039; \in N_\varepsilon(p)&amp;lt;/math&amp;gt; c шага 2 (в качестве новой &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).&lt;br /&gt;
#*Если точка &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; оказалась не ядровой, то &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; объявляется шумом. Алгоритм продолжается с шага 4.&lt;br /&gt;
#Если остались непосещенные точки, то алгоритм продолжается с шага 1.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром алгоритма является нахождение &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей каждой точки входного множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для решения этой задачи требуется найти расстояния между любыми двумя точками множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; по заданной метрике.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как записано и в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть метода составляют вызовы функции &amp;lt;math&amp;gt;request\_neighbours&amp;lt;/math&amp;gt; получения &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей и нахождение расстояний между точками множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;DBSCAN(X, \varepsilon, MinPts)&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;C = 0&amp;lt;/math&amp;gt;&lt;br /&gt;
   for &amp;lt;math&amp;gt;\forall p \in X&amp;lt;/math&amp;gt;&lt;br /&gt;
      if &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; is visited then&lt;br /&gt;
         continue&lt;br /&gt;
      mark &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; as visited&lt;br /&gt;
      &amp;lt;math&amp;gt;neighbours&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;request\_neighbours(p, \varepsilon)&amp;lt;/math&amp;gt;&lt;br /&gt;
      if &amp;lt;math&amp;gt;| neighbours | &amp;lt; MinPts&amp;lt;/math&amp;gt; then&lt;br /&gt;
         mark &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; as &amp;lt;math&amp;gt;NOISE&amp;lt;/math&amp;gt;&lt;br /&gt;
      else&lt;br /&gt;
         &amp;lt;math&amp;gt;C = next\_cluster&amp;lt;/math&amp;gt;&lt;br /&gt;
         &amp;lt;math&amp;gt;expand\_cluster(p, neighbours, C, \varepsilon, MinPts)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;expand\_cluster(p, neighbours, C, \varepsilon, MinPts)&amp;lt;/math&amp;gt;&lt;br /&gt;
   add &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; to cluster &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;&lt;br /&gt;
   for &amp;lt;math&amp;gt;\forall p&#039; \in neighbours&amp;lt;/math&amp;gt;&lt;br /&gt;
      if &amp;lt;math&amp;gt;p&#039;&amp;lt;/math&amp;gt; is not visited &lt;br /&gt;
         mark &amp;lt;math&amp;gt;p&#039;&amp;lt;/math&amp;gt; as visited&lt;br /&gt;
         &amp;lt;math&amp;gt;neighbours&#039;&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;request\_neighbours(p, \varepsilon)&amp;lt;/math&amp;gt;&lt;br /&gt;
         if &amp;lt;math&amp;gt;| neighbours&#039; | \ \ge MinPts&amp;lt;/math&amp;gt;&lt;br /&gt;
            &amp;lt;math&amp;gt;neighbours&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;neighbours \cup neighbours&#039;&amp;lt;/math&amp;gt;  &lt;br /&gt;
      if &amp;lt;math&amp;gt;p&#039;&amp;lt;/math&amp;gt; is not yet member of any cluster&lt;br /&gt;
         add &amp;lt;math&amp;gt;p&#039;&amp;lt;/math&amp;gt; to cluster &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;request\_neighbours(p, \varepsilon)&amp;lt;/math&amp;gt;&lt;br /&gt;
   return &amp;lt;math&amp;gt;\{ p&#039; \ | \ \forall p&#039; \in X: D(p, p&#039;) &amp;lt; \varepsilon \}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
DBSCAN проходит через каждую точку входного множества, возможно, по несколько раз. Временная сложность зависит в большей степени от вызова функции &amp;lt;math&amp;gt;request\_neighbours&amp;lt;/math&amp;gt; (нахождение &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей для заданной точки). Эта функция вызывается ровно один раз для каждой точки множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если использовать индексированную структуру данных (например, R-деревья), выполяющую операцию &amp;lt;math&amp;gt;request\_neighbours&amp;lt;/math&amp;gt; за &amp;lt;math&amp;gt;O(\log n)&amp;lt;/math&amp;gt;, то суммарная сложность алгоритма в среднем составит &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt;, с учётом хорошо подобранного параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;, такого что в среднем &amp;lt;math&amp;gt;request\_neighbours&amp;lt;/math&amp;gt; возвращает &amp;lt;math&amp;gt;O(\log n)&amp;lt;/math&amp;gt; точек. Без использования ускоряющих структур или на вырожденных данных (таких, что все точки находятся на расстоянии меньшем, чем &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; друг от друга) сложность по времени в худшем случае будет &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Расстояния между точками можно вычислить заранее за &amp;lt;math&amp;gt;O(\frac {n(n - 1)}{2})&amp;lt;/math&amp;gt;, например в виде матрицы расстояний, но это потребует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; памяти. Иначе, расстояния будут вычисляться при каждом запуске функции &amp;lt;math&amp;gt;request\_neighbours&amp;lt;/math&amp;gt; за &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; и потребуют &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; памяти. Итоговая сложность вычисления расстояний в таком случае составляет &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;. Сложность рассчета расстояний зависит от природы объектов из &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; и заданной метрики &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;. Например, если &amp;lt;math&amp;gt;X\subset\mathbb{R}^m&amp;lt;/math&amp;gt;, то сложность равна &amp;lt;math&amp;gt;O(m)&amp;lt;/math&amp;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;
[[File:Dbscan abstract.png |thumb|right|320px| Рис. 2. Внешний цикл алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На рис. 2 изображен информационный граф внешнего цикла алгоритма, который соответствует коду основной функции &amp;lt;math&amp;gt;DBSCAN&amp;lt;/math&amp;gt;:&lt;br /&gt;
*Макрооперация &#039;&#039;Init&#039;&#039; заключается в получении множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; и инициирования вспомогательных структур. &lt;br /&gt;
*Макрооперация &#039;&#039;Choose&#039;&#039; производит выбор непосещенной точки из &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Макрооперация &#039;&#039;Build cluster&#039;&#039; строит кластер, если точка ядровая, или объявляет ее шумом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Переход от &#039;&#039;Build cluster&#039;&#039; к &#039;&#039;Choose&#039;&#039; заключает в себе зависимость данных о принадлежности некоторых точек к текущему кластеру или шуму и об их посещенности.&lt;br /&gt;
&lt;br /&gt;
[[File:Expand cluster 2.png |thumb|right|600px| Рис. 3. Расширение кластера.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На рис. 3 изображен информационный граф алгоритма расширения кластера из начальной точки кластера:&lt;br /&gt;
*Макрооперация &#039;&#039;Init&#039;&#039; заключается в создании кластера из его начальной вершины.&lt;br /&gt;
*Макрооперация &#039;&#039;Nε&#039;&#039; вычисляет множество &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей.&lt;br /&gt;
*Желтым цветом обозначены узлы, в которых точки из &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей классифицируются на ядровые, граничные точки и шум. В рамках операции для конкретного соседа вычисляется множество его &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей.&lt;br /&gt;
*Макрооперации &#039;&#039;Ñε&#039;&#039;, &#039;&#039;Ňε&#039;&#039;, ... производят объединение входных множеств.&lt;br /&gt;
*Макрооперация &#039;&#039;Ø&#039;&#039; выполняется тогда, когда объединение входных множеств является пустым.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:N eps 3.png         |thumb|right|320px| Рис. 4. Подсчет &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей.]]&lt;br /&gt;
&lt;br /&gt;
На рис. 4 изображен информационный граф алгоритма вычисления множества &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей:&lt;br /&gt;
*Операция &#039;&#039;D&#039;&#039; - вычисление расстояния между точками.&lt;br /&gt;
*Операция &#039;&#039;ε&#039;&#039; - сравнение расстояния с ε.&lt;br /&gt;
*Операция &#039;&#039;U&#039;&#039; - объединение результатов.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Поиск &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей требует вычисления &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; расстояний (функция &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;) и выполнения &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений с &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Эти операции для каждой пары точек независимы и могут быть выполнены параллельно. Таким образом, при наличии неограниченного числа процессоров сложность поиска составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;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;
Вход алгоритма: множество точек X из n-мерного пространства, на котором определена функция расстояния D. В наиболее распространенном случае пространственной кластеризации используется Евлидово расстояние между векторами из &amp;lt;math&amp;gt;\mathbb{R}^n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Выход алгоритма: размеченное множество точек &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;, в котором каждой точке соответствует номер ее кластера. Обычно каждой точке из &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; сопоставляется ее номер, а на выходе алгоритм дает отображение номеров точек в номера соответствующих им кластеров, например в виде вектора размера &amp;lt;math&amp;gt;|X|&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;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
=== Недостатки алгоритма ===&lt;br /&gt;
&lt;br /&gt;
# не детерминирован: граничные точки, достижимые из более, чем одного кластера, могут быть частью любого из них в зависимости от порядка обрабатываемых данных. Однако такая ситуация возникает редко, а относительно ядровых точек и шума DBSCAN детерминирован. Впрочем, от недетерминизма можно избавиться, если считать все граничные точки шумом (алгоритм DBSCAN*);&lt;br /&gt;
# качество алгоритма зависит от используемой функции расстояния &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;. Наиболее часто используемое Евклидово расстояние в многомерных множествах может оказаться практически бесполезным из-за так называемого &amp;quot;проклятия размерности&amp;quot;, значительно затрудняя нахождение подходящего значения &amp;lt;math&amp;gt;\varepsilon&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;
!!! ЭКСПЕРИМЕНТЫ ДО 15 НОЯБРЯ !!!&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
* [http://scikit-learn.org/stable/modules/generated/sklearn.cluster.DBSCAN.html Scikit learn (Python)]&lt;br /&gt;
* [https://cran.r-project.org/web/packages/dbscan/dbscan.pdf R-project] ([https://github.com/mhahsler/dbscan github])&lt;br /&gt;
* [https://www.mathworks.com/matlabcentral/fileexchange/52905-dbscan-clustering-algorithm Matlab]&lt;br /&gt;
* P-DBSCAN (Parallel DBSCAN)&amp;lt;ref&amp;gt;Chen, Min, Xuedong Gao, and HuiFei Li. &amp;quot;Parallel DBSCAN with priority r-tree.&amp;quot; Information Management and Engineering (ICIME), 2010 The 2nd IEEE International Conference on. IEEE, 2010.&amp;lt;/ref&amp;gt;&lt;br /&gt;
* Parallel DBSCAN with MPI&amp;lt;ref&amp;gt;Savvas, Ilias K., and Dimitrios Tselios. &amp;quot;Parallelizing DBSCaN Algorithm Using MPI.&amp;quot; Enabling Technologies: Infrastructure for Collaborative Enterprises (WETICE), 2016 IEEE 25th International Conference on. IEEE, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
* PDSDBSCAN (Parallel Disjoint-Set DBSCAN)&amp;lt;ref&amp;gt;Patwary, Md Mostofa Ali, et al. &amp;quot;A new scalable parallel DBSCAN algorithm using the disjoint-set data structure.&amp;quot; High Performance Computing, Networking, Storage and Analysis (SC), 2012 International Conference for. IEEE, 2012.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sleo</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:Dadrik/%D0%9F%D0%BB%D0%BE%D1%82%D0%BD%D0%BE%D1%81%D1%82%D0%BD%D1%8B%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8&amp;diff=14018</id>
		<title>Участник:Dadrik/Плотностный алгоритм кластеризации</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:Dadrik/%D0%9F%D0%BB%D0%BE%D1%82%D0%BD%D0%BE%D1%81%D1%82%D0%BD%D1%8B%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8&amp;diff=14018"/>
		<updated>2016-10-26T13:42:23Z</updated>

		<summary type="html">&lt;p&gt;Sleo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Плотностный алгоритм кластеризации DBSCAN&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Авторы описания: [[Участник:Dadrik | Вашуров И.М.]], [[Участник:ramon93i7 | Шемякин Р.О.]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Задача кластеризации - это задача разбиения заданной входной выборки объектов на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из схожих объектов, а объекты разных кластеров существенно отличались.&lt;br /&gt;
&lt;br /&gt;
Алгоритм DBSCAN (Density-based spatial clustering of applications with noise)&amp;lt;ref&amp;gt;Ester, Martin, et al. &amp;quot;A density-based algorithm for discovering clusters in large spatial databases with noise.&amp;quot; Kdd. Vol. 96. No. 34. 1996.&amp;lt;/ref&amp;gt; был предложен Мартином Эстер, Гансом-Питером Кригель и коллегами в 1996 году как решение задачи кластеризации с кластерами произвольной формы. DBSCAN является непараметрическим плотностным алгоритмом кластеризации: для заданного набора точек в некотором пространстве, алгоритм группирует те точки, которые расположены достаточно близко друг к другу (точки с большим количеством соседей), и помечает как выбросы те, что располагаются далеко от ближайших соседей.&lt;br /&gt;
&lt;br /&gt;
Близость в алгоритме определяется заданной в пространстве метрикой. Наиболее часто в качестве метрики используются Евклидово расстояние, квадрат Евклидова расстояния, манхэттенская метрика, расстояние Чебышева или степенное расстояние.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Вход алгоритма: множество точек &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;-мерного пространства, на котором определена функция расстояния &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Выход алгоритма: размеченное множество точек &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;, в котором каждой точке соответствует номер ее кластера.&lt;br /&gt;
&lt;br /&gt;
Параметры алгоритма: &lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; - максимальное расстояние между соседями;&lt;br /&gt;
* &amp;lt;math&amp;gt;MinPts&amp;lt;/math&amp;gt; - минимальное количество соседей для создания области связности.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Определения ===&lt;br /&gt;
&lt;br /&gt;
[[File:Cluster_scheme.png|thumb|right|400px| Рис. 1. Здесь &#039;&#039;MinPts&#039;&#039; = 4. Точка &#039;&#039;A&#039;&#039; и другие красные точки - ядровые и образуют единый кластер, так как достижимы друг из друга. Точки &#039;&#039;B&#039;&#039; и &#039;&#039;C&#039;&#039; не являются ядровыми, но достижимы из &#039;&#039;A&#039;&#039;, а значит также принадлежат кластеру. Точка &#039;&#039;N&#039;&#039; - не достижима из других точек и является шумом.]]&lt;br /&gt;
&lt;br /&gt;
Все заданные точки классифицируются на три группы:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;ядровые точки&#039;&#039;: точка &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; является ядровой, если количество &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей, включая саму точку &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, не меньше &amp;lt;math&amp;gt;MinPts&amp;lt;/math&amp;gt;. Под &#039;&#039;&amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседями&#039;&#039; точки &amp;lt;math&amp;gt;p \in X&amp;lt;/math&amp;gt; понимается множество точек, расстояние до которых не превышает &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;N_\varepsilon(p) = \{ x \in X | D(p, x) \le \varepsilon \}&amp;lt;/math&amp;gt;. Эти точки являются напрямую достижимыми из &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;достижимые точки&#039;&#039;: точка &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; достижима из &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, если  существует путь &amp;lt;math&amp;gt;p_1, \dots, p_n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;p_1 = p&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_n = q&amp;lt;/math&amp;gt;, для которого выполнено: &lt;br /&gt;
:&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
p_{i + 1} \in N_\varepsilon(p_i),  i = 1, \dots, n-1 \\&lt;br /&gt;
| N_\varepsilon(p_{i}) | \ge MinPts, i = 1, \dots, n-1 \\&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;шум&#039;&#039; (выбросы): все точки, недостижимые из какой-либо другой точки считаются шумом (выбросом).&lt;br /&gt;
&lt;br /&gt;
Так, если &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - ядровая точка, то она образует кластер вместе со всеми точками, достижимыми из неё. Каждый кластер содержит по крайней мере одну ядровую точку; неядровые точки могут быть частью кластера, образуя при этом его &amp;quot;границу&amp;quot;, так как они не могут быть использованы для достижения других точек.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Достижимость не является симметричным отношением, так как по определению никакая точка не может быть достижима из неядровой точки, независимо от расстояния. Поэтому в DBSCAN применяется следующий термин &#039;&#039;связности&#039;&#039;: две точки &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; связанны, если существует такая точка &amp;lt;math&amp;gt;o&amp;lt;/math&amp;gt;, что &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; достижимы из &amp;lt;math&amp;gt;o&amp;lt;/math&amp;gt;. Такое отношение связности симметрично.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Кластер&#039;&#039; в таком случае определяется двумя свойствами:&lt;br /&gt;
* Все точки внутри кластера взаимно связанны;&lt;br /&gt;
* Если точка достижима из любой точки кластера, она также является частью кластера.&lt;br /&gt;
&lt;br /&gt;
=== Шаги алгоритма ===&lt;br /&gt;
&lt;br /&gt;
#Выбирается произвольная непосещенная точка &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;.&lt;br /&gt;
#Точка &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; помечается как посещенная. &lt;br /&gt;
#У точки &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; определяется множество её &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей - &amp;lt;math&amp;gt;N_\varepsilon(p)&amp;lt;/math&amp;gt;.&lt;br /&gt;
#*Если точка &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; оказалась ядровой - &amp;lt;math&amp;gt;| N_\varepsilon(p) | \ \ge MinPts&amp;lt;/math&amp;gt;, то: &lt;br /&gt;
#**она становится началом нового кластера или сохраняет номер кластера, который был ей присвоен ранее; &lt;br /&gt;
#**все точки из &amp;lt;math&amp;gt;N_\varepsilon(p)&amp;lt;/math&amp;gt; добавляются в её кластер;&lt;br /&gt;
#**процесс продолжается рекурсивно для каждой новой добавленной непосещенной точки &amp;lt;math&amp;gt;p&#039; \in N_\varepsilon(p)&amp;lt;/math&amp;gt; c шага 2 (в качестве новой &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;).&lt;br /&gt;
#*Если точка &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; оказалась не ядровой, то &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; объявляется шумом. Алгоритм продолжается с шага 4.&lt;br /&gt;
#Если остались непосещенные точки, то алгоритм продолжается с шага 1.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром алгоритма является нахождение &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей каждой точки входного множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для решения этой задачи требуется найти расстояния между любыми двумя точками множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; по заданной метрике.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как записано и в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть метода составляют вызовы функции &amp;lt;math&amp;gt;request\_neighbours&amp;lt;/math&amp;gt; получения &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей и нахождение расстояний между точками множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;DBSCAN(X, \varepsilon, MinPts)&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;C = 0&amp;lt;/math&amp;gt;&lt;br /&gt;
   for &amp;lt;math&amp;gt;\forall p \in X&amp;lt;/math&amp;gt;&lt;br /&gt;
      if &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; is visited then&lt;br /&gt;
         continue&lt;br /&gt;
      mark &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; as visited&lt;br /&gt;
      &amp;lt;math&amp;gt;neighbours&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;request\_neighbours(p, \varepsilon)&amp;lt;/math&amp;gt;&lt;br /&gt;
      if &amp;lt;math&amp;gt;| neighbours | &amp;lt; MinPts&amp;lt;/math&amp;gt; then&lt;br /&gt;
         mark &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; as &amp;lt;math&amp;gt;NOISE&amp;lt;/math&amp;gt;&lt;br /&gt;
      else&lt;br /&gt;
         &amp;lt;math&amp;gt;C = next\_cluster&amp;lt;/math&amp;gt;&lt;br /&gt;
         &amp;lt;math&amp;gt;expand\_cluster(p, neighbours, C, \varepsilon, MinPts)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;expand\_cluster(p, neighbours, C, \varepsilon, MinPts)&amp;lt;/math&amp;gt;&lt;br /&gt;
   add &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; to cluster &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;&lt;br /&gt;
   for &amp;lt;math&amp;gt;\forall p&#039; \in neighbours&amp;lt;/math&amp;gt;&lt;br /&gt;
      if &amp;lt;math&amp;gt;p&#039;&amp;lt;/math&amp;gt; is not visited &lt;br /&gt;
         mark &amp;lt;math&amp;gt;p&#039;&amp;lt;/math&amp;gt; as visited&lt;br /&gt;
         &amp;lt;math&amp;gt;neighbours&#039;&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;request\_neighbours(p, \varepsilon)&amp;lt;/math&amp;gt;&lt;br /&gt;
         if &amp;lt;math&amp;gt;| neighbours&#039; | \ \ge MinPts&amp;lt;/math&amp;gt;&lt;br /&gt;
            &amp;lt;math&amp;gt;neighbours&amp;lt;/math&amp;gt; = &amp;lt;math&amp;gt;neighbours \cup neighbours&#039;&amp;lt;/math&amp;gt;  &lt;br /&gt;
      if &amp;lt;math&amp;gt;p&#039;&amp;lt;/math&amp;gt; is not yet member of any cluster&lt;br /&gt;
         add &amp;lt;math&amp;gt;p&#039;&amp;lt;/math&amp;gt; to cluster &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;request\_neighbours(p, \varepsilon)&amp;lt;/math&amp;gt;&lt;br /&gt;
   return &amp;lt;math&amp;gt;\{ p&#039; \ | \ \forall p&#039; \in X: D(p, p&#039;) &amp;lt; \varepsilon \}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
DBSCAN проходит через каждую точку входного множества, возможно, по несколько раз. Временная сложность зависит в большей степени от вызова функции &amp;lt;math&amp;gt;request\_neighbours&amp;lt;/math&amp;gt; (нахождение &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей для заданной точки). Эта функция вызывается ровно один раз для каждой точки множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если использовать индексированную структуру данных (например, R-деревья), выполяющую операцию &amp;lt;math&amp;gt;request\_neighbours&amp;lt;/math&amp;gt; за &amp;lt;math&amp;gt;O(\log n)&amp;lt;/math&amp;gt;, то суммарная сложность алгоритма в среднем составит &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt;, с учётом хорошо подобранного параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;, такого что в среднем &amp;lt;math&amp;gt;request\_neighbours&amp;lt;/math&amp;gt; возвращает &amp;lt;math&amp;gt;O(\log n)&amp;lt;/math&amp;gt; точек. Без использования ускоряющих структур или на вырожденных данных (таких, что все точки находятся на расстоянии меньшем, чем &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; друг от друга) сложность по времени в худшем случае будет &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Расстояния между точками можно вычислить заранее за &amp;lt;math&amp;gt;O(\frac {n(n - 1)}{2})&amp;lt;/math&amp;gt;, например в виде матрицы расстояний, но это потребует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; памяти. Иначе, расстояния будут вычисляться при каждом запуске функции &amp;lt;math&amp;gt;request\_neighbours&amp;lt;/math&amp;gt; за &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; и потребуют &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; памяти. Итоговая сложность вычисления расстояний в таком случае составляет &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;. Сложность рассчета расстояний зависит от природы объектов из &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; и заданной метрики &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;. Например, если &amp;lt;math&amp;gt;X\subset\mathbb{R}^m&amp;lt;/math&amp;gt;, то сложность равна &amp;lt;math&amp;gt;O(m)&amp;lt;/math&amp;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;
[[File:Dbscan abstract.png |thumb|right|320px| Рис. 2. Внешний цикл алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На рис. 2 изображен информационный граф внешнего цикла алгоритма, который соответствует коду основной функции &amp;lt;math&amp;gt;DBSCAN&amp;lt;/math&amp;gt;:&lt;br /&gt;
*Макрооперация &#039;&#039;Init&#039;&#039; заключается в получении множества &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; и инициирования вспомогательных структур. &lt;br /&gt;
*Макрооперация &#039;&#039;Choose&#039;&#039; производит выбор непосещенной точки из &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Макрооперация &#039;&#039;Build cluster&#039;&#039; строит кластер, если точка ядровая, или объявляет ее шумом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Переход от &#039;&#039;Build cluster&#039;&#039; к &#039;&#039;Choose&#039;&#039; заключает в себе зависимость данных о принадлежности некоторых точек к текущему кластеру или шуму и об их посещенности.&lt;br /&gt;
&lt;br /&gt;
[[File:Expand cluster 2.png |thumb|right|600px| Рис. 3. Расширение кластера.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На рис. 3 изображен информационный граф алгоритма расширения кластера из начальной точки кластера:&lt;br /&gt;
*Макрооперация &#039;&#039;Init&#039;&#039; заключается в создании кластера из его начальной вершины.&lt;br /&gt;
*Макрооперация &#039;&#039;Nε&#039;&#039; вычисляет множество &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей.&lt;br /&gt;
*Желтым цветом обозначены узлы, в которых точки из &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей классифицируются на ядровые, граничные точки и шум. В рамках операции для конкретного соседа вычисляется множество его &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей.&lt;br /&gt;
*Макрооперации &#039;&#039;Ñε&#039;&#039;, &#039;&#039;Ňε&#039;&#039;, ... производят объединение входных множеств.&lt;br /&gt;
*Макрооперация &#039;&#039;Ø&#039;&#039; выполняется тогда, когда объединение входных множеств является пустым.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:N eps 3.png         |thumb|right|320px| Рис. 4. Подсчет &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей.]]&lt;br /&gt;
&lt;br /&gt;
На рис. 4 изображен информационный граф алгоритма вычисления множества &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей:&lt;br /&gt;
*Операция &#039;&#039;D&#039;&#039; - вычисление расстояния между точками.&lt;br /&gt;
*Операция &#039;&#039;ε&#039;&#039; - сравнение расстояния с ε.&lt;br /&gt;
*Операция &#039;&#039;U&#039;&#039; - объединение результатов.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Поиск &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;-соседей требует вычисления &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; расстояний (функция &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;) и выполнения &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений с &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Эти операции для каждой пары точек независимы и могут быть выполнены параллельно. Таким образом, при наличии неограниченного числа процессоров сложность поиска составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;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;
Вход алгоритма: множество точек X из n-мерного пространства, на котором определена функция расстояния D. В наиболее распространенном случае пространственной кластеризации используется Евлидово расстояние между векторами из &amp;lt;math&amp;gt;\mathbb{R}^n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Выход алгоритма: размеченное множество точек &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;, в котором каждой точке соответствует номер ее кластера. Обычно каждой точке из &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; сопоставляется ее номер, а на выходе алгоритм дает отображение номеров точек в номера соответствующих им кластеров, например в виде вектора размера &amp;lt;math&amp;gt;|X|&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;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
=== Недостатки алгоритма ===&lt;br /&gt;
&lt;br /&gt;
# не детерминирован: граничные точки, достижимые из более, чем одного кластера, могут быть частью любого из них в зависимости от порядка обрабатываемых данных. Однако такая ситуация возникает редко, а относительно ядровых точек и шума DBSCAN детерминирован. Впрочем, от недетерминизма можно избавиться, если считать все граничные точки шумом (алгоритм DBSCAN*);&lt;br /&gt;
# качество алгоритма зависит от используемой функции расстояния &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;. Наиболее часто используемое Евклидово расстояние в многомерных множествах может оказаться практически бесполезным из-за так называемого &amp;quot;проклятия размерности&amp;quot;, значительно затрудняя нахождение подходящего значения &amp;lt;math&amp;gt;\varepsilon&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;
!!! ЭКСПЕРИМЕНТЫ ДО 15 НОЯБРЯ !!!&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
* [http://scikit-learn.org/stable/modules/generated/sklearn.cluster.DBSCAN.html Scikit learn (Python)]&lt;br /&gt;
* [https://cran.r-project.org/web/packages/dbscan/dbscan.pdf R-project] ([https://github.com/mhahsler/dbscan github])&lt;br /&gt;
* [https://www.mathworks.com/matlabcentral/fileexchange/52905-dbscan-clustering-algorithm Matlab]&lt;br /&gt;
* P-DBSCAN (Parallel DBSCAN)&amp;lt;ref&amp;gt;Chen, Min, Xuedong Gao, and HuiFei Li. &amp;quot;Parallel DBSCAN with priority r-tree.&amp;quot; Information Management and Engineering (ICIME), 2010 The 2nd IEEE International Conference on. IEEE, 2010.&amp;lt;/ref&amp;gt;&lt;br /&gt;
* Parallel DBSCAN with MPI&amp;lt;ref&amp;gt;Savvas, Ilias K., and Dimitrios Tselios. &amp;quot;Parallelizing DBSCaN Algorithm Using MPI.&amp;quot; Enabling Technologies: Infrastructure for Collaborative Enterprises (WETICE), 2016 IEEE 25th International Conference on. IEEE, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
* PDSDBSCAN (Parallel Disjoint-Set DBSCAN)&amp;lt;ref&amp;gt;Patwary, Md Mostofa Ali, et al. &amp;quot;A new scalable parallel DBSCAN algorithm using the disjoint-set data structure.&amp;quot; High Performance Computing, Networking, Storage and Analysis (SC), 2012 International Conference for. IEEE, 2012.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sleo</name></author>
	</entry>
</feed>