<?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=%D0%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0+%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80</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=%D0%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0+%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80"/>
	<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/%D0%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80"/>
	<updated>2026-10-22T20:31:03Z</updated>
	<subtitle>Вклад</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80&amp;diff=21282</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80&amp;diff=21282"/>
		<updated>2016-12-18T20:59:08Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Статья [[Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)]] =&lt;br /&gt;
&lt;br /&gt;
* У вас в сложности фигурирует количество итераций. В литературе есть какие-то оценки требуемого количества итераций исходя из входных параметров? Если есть, то хорошо бы указать. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 18:23, 18 декабря 2016 (MSK)&lt;br /&gt;
** Нет, оценок нет.&lt;br /&gt;
&lt;br /&gt;
* 1.8 — высота не равна O(1) на вашем графе, она зависит в том числе от n. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 23:43, 17 декабря 2016 (MSK)&lt;br /&gt;
** Исправлено.&lt;br /&gt;
&lt;br /&gt;
* 1.6 — Не совсем понятно, как сложность алгоритма получилась меньше объёма входных данных. Она не зависит от m? [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 18:48, 5 декабря 2016 (MSK)&lt;br /&gt;
** В пункте 1.6 написано, что мы исходим из следующего предположения - размерность m и количество кластерных центров C существенно меньше n.&lt;br /&gt;
*** Это всё равно вам не даёт сложности O(N). Она зависит от m и C. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 23:43, 17 декабря 2016 (MSK)&lt;br /&gt;
**** Исправлено.&lt;br /&gt;
&lt;br /&gt;
* 2.4 — Написано, что исследование проводилось на системе с двумя процессорами E5-2697 v2. У них по 12 физических ядер [https://ark.intel.com/ru/products/75283/Intel-Xeon-Processor-E5-2697-v2-30M-Cache-2_70-GHz]. Как это согласуется с «number of processors», доходящим до 48 на графике? Всё, что выше 24 — определённо Hyper Threading. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 18:16, 5 декабря 2016 (MSK)&lt;br /&gt;
** Да, Вы правы, у нас был включен ht.&lt;br /&gt;
*** Стоит указать количество реальных ядер и количество потоков в тексте. В графиках у вас всё ещё подписано «number of processors», и он всё ещё доходит до 48. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 23:43, 17 декабря 2016 (MSK)&lt;br /&gt;
**** Исправлено.&lt;br /&gt;
----------------------&lt;br /&gt;
* Не указан вклад каждого автора [[Участник:Coctic|Coctic]] ([[Обсуждение участника:Coctic|обсуждение]]) 11:08, 25 октября 2016 (MSK)&lt;br /&gt;
** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 12:42, 2 ноября 2016 (MSK)&lt;br /&gt;
* Стоит добавить ссылку на оригинальную публикацию, в которой был впервые предложен алгоритм. [[Участник:Coctic|Coctic]] ([[Обсуждение участника:Coctic|обсуждение]]) 11:08, 25 октября 2016 (MSK)&lt;br /&gt;
** Не исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 12:42, 2 ноября 2016 (MSK)&lt;br /&gt;
* Значительная часть п. 1.2  совпадает с тем же пунктом из [[Строгий алгоритм С средних (Hard C-Means, HCM)]]&lt;br /&gt;
** Замечание снимается [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 12:42, 2 ноября 2016 (MSK)&lt;br /&gt;
* Пункты раздела 2 не соответствуют шаблону. П. 2.1 должен быть 2.4, п. 2.2 должен быть 2.7, остальные пункты пропущены [[Участник:Coctic|Coctic]] ([[Обсуждение участника:Coctic|обсуждение]]) 11:08, 25 октября 2016 (MSK)&lt;br /&gt;
** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 12:42, 2 ноября 2016 (MSK)&lt;br /&gt;
* В списке литературы отсутствуют выходные данные публикаций, кроме названия и автора. По приведенным данным определить конкретную публикацию не представляется возможным. [[Участник:Coctic|Coctic]] ([[Обсуждение участника:Coctic|обсуждение]]) 11:08, 25 октября 2016 (MSK)&lt;br /&gt;
** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 12:42, 2 ноября 2016 (MSK)&lt;br /&gt;
* Список литературы совпадает со списком из [[Строгий алгоритм С средних (Hard C-Means, HCM)]] [[Участник:Coctic|Coctic]] ([[Обсуждение участника:Coctic|обсуждение]]) 11:08, 25 октября 2016 (MSK)&lt;br /&gt;
** Замечание снимается [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 12:42, 2 ноября 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
------------&lt;br /&gt;
* Стоит добавить ссылку на оригинальную публикацию, в которой был впервые предложен алгоритм [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 12:42, 2 ноября 2016 (MSK)&lt;br /&gt;
** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 13:16, 23 ноября 2016 (MSK)&lt;br /&gt;
* п. 2.4.1 пустой. [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:35, 17 ноября 2016 (MSK)&lt;br /&gt;
** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 13:16, 23 ноября 2016 (MSK)&lt;br /&gt;
* п. 2.4.2. Отсутствует ссылка на текст исследуемой программы и аппаратную платформу, на которой проводилось тестирование. [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:35, 17 ноября 2016 (MSK)&lt;br /&gt;
** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 13:16, 23 ноября 2016 (MSK)&lt;br /&gt;
* Рис. 3. В подписи к рисунку не указано, график зависимости эффективности какого типа приведен. [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:35, 17 ноября 2016 (MSK)&lt;br /&gt;
** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 13:16, 23 ноября 2016 (MSK)&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=21280</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=21280"/>
		<updated>2016-12-18T20:58:24Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|{{REVISIONUSER}}}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(nmC)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(nClog_2(nC))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(n+m)C&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания: [[Участник:Каледа_Александр|Каледа Александр]] (разделы [[#Общее описание алгоритма|1.1]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Информационный граф|1.7]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Входные и выходные данные алгоритма|1.9]]), [[Участник:Шапулин_Андрей|Шапулин Андрей]] (разделы [[#Математическое описание алгоритма|1.2]], [[#Вычислительное ядро алгоритма|1.3]], [[#Макроструктура алгоритма|1.4]], [[#Информационный граф|1.7]], [[#Свойства алгоритма|1.10]], [[#Существующие реализации алгоритма|2.7]]).&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;&amp;lt;ref&amp;gt;Jang, J.-S. R., Sun, C.-T. and Mizutani, E. (1997). Neuro-Fuzzy and Soft Computing, number&lt;br /&gt;
isbn 0-13-261066-3 in Matlab Curriculum Series, Prentice Hall, Upper Saddle River, NJ, USA.&amp;lt;/ref&amp;gt;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;[http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf Jantzen J. Neurofuzzy Modelling. 1998. Электронное издание. 28 Стр.]&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt;[http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf Нейский И.М. Классификация и сравнение методов кластеризации // Интеллектуальные технологии и системы. Сборник учебно-методических работ и статей аспирантов и студентов. – М.: НОК «CLAIM», 2006. – Выпуск 8. – С. 130-142.]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(nmC)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из 4 видов вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин отмечена символом &#039;&#039;&#039;&#039;&#039;M&#039;&#039;&#039;&#039;&#039;. Ей соответствует вычисление минимального расстояния до кластерных центров, а также запись единицы в соответствующий столбец матрицы, обозначающей принадлежность кластерному центру:&lt;br /&gt;
* независимое вычисление расстояний от заданного элемента &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; до каждого из кластерных центров;&lt;br /&gt;
* последовательное сравнение полученных значений с целью отыскания максимума;&lt;br /&gt;
* операция записи 1 в соответствующий столбец матрицы принадлежности кластерным центрам;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; вершина отмечена символом &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит итоговый расчёт объектной функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; вершина помечена &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит проверка условия достижения требуемой точности.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Четвертая&#039;&#039;&#039; соответствует операции пересчёта кластерных центров, она отмечена как &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmeans.png|thumb|800px|center|Рисунок 1. Информационный граф алгоритма. Здесь &#039;&#039;&#039;&#039;&#039;in&#039;&#039;&#039;&#039;&#039; — ввод входных данных, &#039;&#039;&#039;&#039;&#039;M&#039;&#039;&#039;&#039;&#039; — вычисление минимального расстояния до кластерных центров и проставление принадлежности соответствующему кластерному центру, &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039; — вычисление объектной функции по результатам полученных вычислений, &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039; — проверка условия достижения желаемой точности, &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039; — пересчёт кластерных центров и &#039;&#039;&#039;&#039;&#039;out&#039;&#039;&#039;&#039;&#039; — вывод полученных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Число итераций алгоритма оценим как &amp;lt;math&amp;gt;O(nC)&amp;lt;/math&amp;gt;. Исходя из того, что сложность вычислительного блока &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; равна &amp;lt;math&amp;gt;log_2(C)&amp;lt;/math&amp;gt;, а сложность расчета функционала &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; составляет &amp;lt;math&amp;gt;log_2(n)&amp;lt;/math&amp;gt;, имеем, что высота итерации составляет &amp;lt;math&amp;gt;log_2(nC)&amp;lt;/math&amp;gt;. Таким образом, высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(nClog_2(nC))&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;
Необходимо учитывать, что при небольшом объеме входной выборки, параллельная реализация алгоритма может лишь понизить производительность. В первую очередь это связано с пересылкой данных для вычисления итоговых значений объектной функции и кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;(n+m)C&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;
Проведём исследование масштабируемости параллельной реализации строгого алгоритма C средних согласно [[Scalability methodology|методике]].&lt;br /&gt;
&lt;br /&gt;
Исследование проводилось на 1U сервере со &#039;&#039;&#039;следующими характеристиками&#039;&#039;&#039;:&lt;br /&gt;
*	2 x Intel® Xeon® Processor E5-2697 v2, всего 24 физических ядра (48 логических ядра при включенном Hyper-Threading);&lt;br /&gt;
*	128GB RAM;&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Сборка осуществлялась со следующими параметрами:&lt;br /&gt;
&lt;br /&gt;
*	GCC-4.8.4;&lt;br /&gt;
*	OpenMP-3.1;&lt;br /&gt;
*	аргументы компилятора: -std=c++11 -O3;&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число логических ядер [1 : 48] с шагом 2;&lt;br /&gt;
*	размерность пространства [3 : 50] c шагом 3;&lt;br /&gt;
*	число векторов 100 000 000;&lt;br /&gt;
*	число кластерных центров 30;&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон [[Глоссарий#Эффективность реализации|эффективности реализации]] алгоритма (отношение реальной производительности программы к пиковым показателям работы вычислительной системы):&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0.014;&lt;br /&gt;
*	максимальная эффективность реализации 0.9;&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики [[Глоссарий#Производительность|производительности]] и эффективности выбранной реализации HCM в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:1new.png|thumb|center|700px|Рисунок 2. Параллельная реализация алгоритма. Изменение производительности в зависимости от числа процессоров и размерности векторов.]]&lt;br /&gt;
[[file:2new.png|thumb|center|700px|Рисунок 3. Параллельная реализация алгоритма. Изменение эффективности в зависимости от числа процессоров и размерности векторов.]]&lt;br /&gt;
&lt;br /&gt;
==== Реализация на языке C++ ====&lt;br /&gt;
[http://pastebin.com/31UkHgcW Исследованная параллельная реализация на языке C++]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80&amp;diff=21253</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80&amp;diff=21253"/>
		<updated>2016-12-18T20:04:57Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: /* Статья Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Статья [[Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)]] =&lt;br /&gt;
&lt;br /&gt;
* У вас в сложности фигурирует количество итераций. В литературе есть какие-то оценки требуемого количества итераций исходя из входных параметров? Если есть, то хорошо бы указать. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 18:23, 18 декабря 2016 (MSK)&lt;br /&gt;
** Нет, оценок нет.&lt;br /&gt;
&lt;br /&gt;
* 1.8 — высота не равна O(1) на вашем графе, она зависит в том числе от n. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 23:43, 17 декабря 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
* 1.6 — Не совсем понятно, как сложность алгоритма получилась меньше объёма входных данных. Она не зависит от m? [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 18:48, 5 декабря 2016 (MSK)&lt;br /&gt;
** В пункте 1.6 написано, что мы исходим из следующего предположения - размерность m и количество кластерных центров C существенно меньше n.&lt;br /&gt;
*** Это всё равно вам не даёт сложности O(N). Она зависит от m и C. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 23:43, 17 декабря 2016 (MSK)&lt;br /&gt;
**** Исправлено.&lt;br /&gt;
&lt;br /&gt;
* 2.4 — Написано, что исследование проводилось на системе с двумя процессорами E5-2697 v2. У них по 12 физических ядер [https://ark.intel.com/ru/products/75283/Intel-Xeon-Processor-E5-2697-v2-30M-Cache-2_70-GHz]. Как это согласуется с «number of processors», доходящим до 48 на графике? Всё, что выше 24 — определённо Hyper Threading. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 18:16, 5 декабря 2016 (MSK)&lt;br /&gt;
** Да, Вы правы, у нас был включен ht.&lt;br /&gt;
*** Стоит указать количество реальных ядер и количество потоков в тексте. В графиках у вас всё ещё подписано «number of processors», и он всё ещё доходит до 48. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 23:43, 17 декабря 2016 (MSK)&lt;br /&gt;
**** Исправлено.&lt;br /&gt;
----------------------&lt;br /&gt;
* Не указан вклад каждого автора [[Участник:Coctic|Coctic]] ([[Обсуждение участника:Coctic|обсуждение]]) 11:08, 25 октября 2016 (MSK)&lt;br /&gt;
** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 12:42, 2 ноября 2016 (MSK)&lt;br /&gt;
* Стоит добавить ссылку на оригинальную публикацию, в которой был впервые предложен алгоритм. [[Участник:Coctic|Coctic]] ([[Обсуждение участника:Coctic|обсуждение]]) 11:08, 25 октября 2016 (MSK)&lt;br /&gt;
** Не исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 12:42, 2 ноября 2016 (MSK)&lt;br /&gt;
* Значительная часть п. 1.2  совпадает с тем же пунктом из [[Строгий алгоритм С средних (Hard C-Means, HCM)]]&lt;br /&gt;
** Замечание снимается [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 12:42, 2 ноября 2016 (MSK)&lt;br /&gt;
* Пункты раздела 2 не соответствуют шаблону. П. 2.1 должен быть 2.4, п. 2.2 должен быть 2.7, остальные пункты пропущены [[Участник:Coctic|Coctic]] ([[Обсуждение участника:Coctic|обсуждение]]) 11:08, 25 октября 2016 (MSK)&lt;br /&gt;
** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 12:42, 2 ноября 2016 (MSK)&lt;br /&gt;
* В списке литературы отсутствуют выходные данные публикаций, кроме названия и автора. По приведенным данным определить конкретную публикацию не представляется возможным. [[Участник:Coctic|Coctic]] ([[Обсуждение участника:Coctic|обсуждение]]) 11:08, 25 октября 2016 (MSK)&lt;br /&gt;
** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 12:42, 2 ноября 2016 (MSK)&lt;br /&gt;
* Список литературы совпадает со списком из [[Строгий алгоритм С средних (Hard C-Means, HCM)]] [[Участник:Coctic|Coctic]] ([[Обсуждение участника:Coctic|обсуждение]]) 11:08, 25 октября 2016 (MSK)&lt;br /&gt;
** Замечание снимается [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 12:42, 2 ноября 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
------------&lt;br /&gt;
* Стоит добавить ссылку на оригинальную публикацию, в которой был впервые предложен алгоритм [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 12:42, 2 ноября 2016 (MSK)&lt;br /&gt;
** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 13:16, 23 ноября 2016 (MSK)&lt;br /&gt;
* п. 2.4.1 пустой. [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:35, 17 ноября 2016 (MSK)&lt;br /&gt;
** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 13:16, 23 ноября 2016 (MSK)&lt;br /&gt;
* п. 2.4.2. Отсутствует ссылка на текст исследуемой программы и аппаратную платформу, на которой проводилось тестирование. [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:35, 17 ноября 2016 (MSK)&lt;br /&gt;
** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 13:16, 23 ноября 2016 (MSK)&lt;br /&gt;
* Рис. 3. В подписи к рисунку не указано, график зависимости эффективности какого типа приведен. [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:35, 17 ноября 2016 (MSK)&lt;br /&gt;
** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 13:16, 23 ноября 2016 (MSK)&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=21248</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=21248"/>
		<updated>2016-12-18T19:43:37Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|{{REVISIONUSER}}}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(nmC)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(n+m)C&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания: [[Участник:Каледа_Александр|Каледа Александр]] (разделы [[#Общее описание алгоритма|1.1]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Информационный граф|1.7]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Входные и выходные данные алгоритма|1.9]]), [[Участник:Шапулин_Андрей|Шапулин Андрей]] (разделы [[#Математическое описание алгоритма|1.2]], [[#Вычислительное ядро алгоритма|1.3]], [[#Макроструктура алгоритма|1.4]], [[#Информационный граф|1.7]], [[#Свойства алгоритма|1.10]], [[#Существующие реализации алгоритма|2.7]]).&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;&amp;lt;ref&amp;gt;Jang, J.-S. R., Sun, C.-T. and Mizutani, E. (1997). Neuro-Fuzzy and Soft Computing, number&lt;br /&gt;
isbn 0-13-261066-3 in Matlab Curriculum Series, Prentice Hall, Upper Saddle River, NJ, USA.&amp;lt;/ref&amp;gt;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;[http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf Jantzen J. Neurofuzzy Modelling. 1998. Электронное издание. 28 Стр.]&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt;[http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf Нейский И.М. Классификация и сравнение методов кластеризации // Интеллектуальные технологии и системы. Сборник учебно-методических работ и статей аспирантов и студентов. – М.: НОК «CLAIM», 2006. – Выпуск 8. – С. 130-142.]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(nmC)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из 4 видов вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин отмечена символом &#039;&#039;&#039;&#039;&#039;M&#039;&#039;&#039;&#039;&#039;. Ей соответствует вычисление минимального расстояния до кластерных центров, а также запись единицы в соответствующий столбец матрицы, обозначающей принадлежность кластерному центру:&lt;br /&gt;
* независимое вычисление расстояний от заданного элемента &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; до каждого из кластерных центров;&lt;br /&gt;
* последовательное сравнение полученных значений с целью отыскания максимума;&lt;br /&gt;
* операция записи 1 в соответствующий столбец матрицы принадлежности кластерным центрам;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; вершина отмечена символом &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит итоговый расчёт объектной функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; вершина помечена &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит проверка условия достижения требуемой точности.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Четвертая&#039;&#039;&#039; соответствует операции пересчёта кластерных центров, она отмечена как &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmeans.png|thumb|800px|center|Рисунок 1. Информационный граф алгоритма. Здесь &#039;&#039;&#039;&#039;&#039;in&#039;&#039;&#039;&#039;&#039; — ввод входных данных, &#039;&#039;&#039;&#039;&#039;M&#039;&#039;&#039;&#039;&#039; — вычисление минимального расстояния до кластерных центров и проставление принадлежности соответствующему кластерному центру, &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039; — вычисление объектной функции по результатам полученных вычислений, &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039; — проверка условия достижения желаемой точности, &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039; — пересчёт кластерных центров и &#039;&#039;&#039;&#039;&#039;out&#039;&#039;&#039;&#039;&#039; — вывод полученных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;(n+m)C&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;
Проведём исследование масштабируемости параллельной реализации строгого алгоритма C средних согласно [[Scalability methodology|методике]].&lt;br /&gt;
&lt;br /&gt;
Исследование проводилось на 1U сервере со &#039;&#039;&#039;следующими характеристиками&#039;&#039;&#039;:&lt;br /&gt;
*	2 x Intel® Xeon® Processor E5-2697 v2, всего 24 физических ядра (48 логических ядра при включенном Hyper-Threading);&lt;br /&gt;
*	128GB RAM;&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Сборка осуществлялась со следующими параметрами:&lt;br /&gt;
&lt;br /&gt;
*	GCC-4.8.4;&lt;br /&gt;
*	OpenMP-3.1;&lt;br /&gt;
*	аргументы компилятора: -std=c++11 -O3;&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число логических ядер [1 : 48] с шагом 2;&lt;br /&gt;
*	размерность пространства [3 : 50] c шагом 3;&lt;br /&gt;
*	число векторов 100 000 000;&lt;br /&gt;
*	число кластерных центров 30;&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон [[Глоссарий#Эффективность реализации|эффективности реализации]] алгоритма (отношение реальной производительности программы к пиковым показателям работы вычислительной системы):&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0.014;&lt;br /&gt;
*	максимальная эффективность реализации 0.9;&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики [[Глоссарий#Производительность|производительности]] и эффективности выбранной реализации HCM в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:1new.png|thumb|center|700px|Рисунок 2. Параллельная реализация алгоритма. Изменение производительности в зависимости от числа процессоров и размерности векторов.]]&lt;br /&gt;
[[file:2new.png|thumb|center|700px|Рисунок 3. Параллельная реализация алгоритма. Изменение эффективности в зависимости от числа процессоров и размерности векторов.]]&lt;br /&gt;
&lt;br /&gt;
==== Реализация на языке C++ ====&lt;br /&gt;
[http://pastebin.com/31UkHgcW Исследованная параллельная реализация на языке C++]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=21238</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=21238"/>
		<updated>2016-12-18T18:39:18Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|{{REVISIONUSER}}}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(nmC)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(n+m)C&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания: [[Участник:Каледа_Александр|Каледа Александр]] (разделы [[#Общее описание алгоритма|1.1]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Информационный граф|1.7]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Входные и выходные данные алгоритма|1.9]]), [[Участник:Шапулин_Андрей|Шапулин Андрей]] (разделы [[#Математическое описание алгоритма|1.2]], [[#Вычислительное ядро алгоритма|1.3]], [[#Макроструктура алгоритма|1.4]], [[#Информационный граф|1.7]], [[#Свойства алгоритма|1.10]], [[#Существующие реализации алгоритма|2.7]]).&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;&amp;lt;ref&amp;gt;Jang, J.-S. R., Sun, C.-T. and Mizutani, E. (1997). Neuro-Fuzzy and Soft Computing, number&lt;br /&gt;
isbn 0-13-261066-3 in Matlab Curriculum Series, Prentice Hall, Upper Saddle River, NJ, USA.&amp;lt;/ref&amp;gt;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;[http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf Jantzen J. Neurofuzzy Modelling. 1998. Электронное издание. 28 Стр.]&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt;[http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf Нейский И.М. Классификация и сравнение методов кластеризации // Интеллектуальные технологии и системы. Сборник учебно-методических работ и статей аспирантов и студентов. – М.: НОК «CLAIM», 2006. – Выпуск 8. – С. 130-142.]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(nmC)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из 4 видов вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин отмечена символом &#039;&#039;&#039;&#039;&#039;M&#039;&#039;&#039;&#039;&#039;. Ей соответствует вычисление минимального расстояния до кластерных центров, а также запись единицы в соответствующий столбец матрицы, обозначающей принадлежность кластерному центру:&lt;br /&gt;
* независимое вычисление расстояний от заданного элемента &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; до каждого из кластерных центров;&lt;br /&gt;
* последовательное сравнение полученных значений с целью отыскания максимума;&lt;br /&gt;
* операция записи 1 в соответствующий столбец матрицы принадлежности кластерным центрам;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; вершина отмечена символом &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит итоговый расчёт объектной функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; вершина помечена &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит проверка условия достижения требуемой точности.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Четвертая&#039;&#039;&#039; соответствует операции пересчёта кластерных центров, она отмечена как &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmeans.png|thumb|800px|center|Рисунок 1. Информационный граф алгоритма. Здесь &#039;&#039;&#039;&#039;&#039;in&#039;&#039;&#039;&#039;&#039; — ввод входных данных, &#039;&#039;&#039;&#039;&#039;D&#039;&#039;&#039;&#039;&#039; — вычисление минимального расстояния до кластерных центров и проставление принадлежности соответствующему кластерному центру, &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039; — вычисление объектной функции по результатам полученных вычислений, &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039; — проверка условия достижения желаемой точности, &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039; — пересчёт кластерных центров и &#039;&#039;&#039;&#039;&#039;out&#039;&#039;&#039;&#039;&#039; — вывод полученных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;(n+m)C&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;
Проведём исследование масштабируемости параллельной реализации строгого алгоритма C средних согласно [[Scalability methodology|методике]].&lt;br /&gt;
&lt;br /&gt;
Исследование проводилось на 1U сервере со &#039;&#039;&#039;следующими характеристиками&#039;&#039;&#039;:&lt;br /&gt;
*	2 x Intel® Xeon® Processor E5-2697 v2, всего 24 физических ядра (48 логических ядра при включенном Hyper-Threading);&lt;br /&gt;
*	128GB RAM;&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Сборка осуществлялась со следующими параметрами:&lt;br /&gt;
&lt;br /&gt;
*	GCC-4.8.4;&lt;br /&gt;
*	OpenMP-3.1;&lt;br /&gt;
*	аргументы компилятора: -std=c++11 -O3;&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число логических ядер [1 : 48] с шагом 2;&lt;br /&gt;
*	размерность пространства [3 : 50] c шагом 3;&lt;br /&gt;
*	число векторов 100 000 000;&lt;br /&gt;
*	число кластерных центров 30;&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон [[Глоссарий#Эффективность реализации|эффективности реализации]] алгоритма (отношение реальной производительности программы к пиковым показателям работы вычислительной системы):&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0.014;&lt;br /&gt;
*	максимальная эффективность реализации 0.9;&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики [[Глоссарий#Производительность|производительности]] и эффективности выбранной реализации HCM в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:1new.png|thumb|center|700px|Рисунок 2. Параллельная реализация алгоритма. Изменение производительности в зависимости от числа процессоров и размерности векторов.]]&lt;br /&gt;
[[file:2new.png|thumb|center|700px|Рисунок 3. Параллельная реализация алгоритма. Изменение эффективности в зависимости от числа процессоров и размерности векторов.]]&lt;br /&gt;
&lt;br /&gt;
==== Реализация на языке C++ ====&lt;br /&gt;
[http://pastebin.com/31UkHgcW Исследованная параллельная реализация на языке C++]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=21236</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=21236"/>
		<updated>2016-12-18T18:24:51Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|{{REVISIONUSER}}}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(nmC)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(n+m)C&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания: [[Участник:Каледа_Александр|Каледа Александр]] (разделы [[#Общее описание алгоритма|1.1]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Информационный граф|1.7]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Входные и выходные данные алгоритма|1.9]]), [[Участник:Шапулин_Андрей|Шапулин Андрей]] (разделы [[#Математическое описание алгоритма|1.2]], [[#Вычислительное ядро алгоритма|1.3]], [[#Макроструктура алгоритма|1.4]], [[#Информационный граф|1.7]], [[#Свойства алгоритма|1.10]], [[#Существующие реализации алгоритма|2.7]]).&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;&amp;lt;ref&amp;gt;Jang, J.-S. R., Sun, C.-T. and Mizutani, E. (1997). Neuro-Fuzzy and Soft Computing, number&lt;br /&gt;
isbn 0-13-261066-3 in Matlab Curriculum Series, Prentice Hall, Upper Saddle River, NJ, USA.&amp;lt;/ref&amp;gt;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;[http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf Jantzen J. Neurofuzzy Modelling. 1998. Электронное издание. 28 Стр.]&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt;[http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf Нейский И.М. Классификация и сравнение методов кластеризации // Интеллектуальные технологии и системы. Сборник учебно-методических работ и статей аспирантов и студентов. – М.: НОК «CLAIM», 2006. – Выпуск 8. – С. 130-142.]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(nmC)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из 4 видов вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин отмечена символом &#039;&#039;&#039;&#039;&#039;M&#039;&#039;&#039;&#039;&#039;. Ей соответствует вычисление минимального расстояния до кластерных центров, а также запись единицы в соответствующий столбец матрицы, обозначающей принадлежность кластерному центру:&lt;br /&gt;
* независимое вычисление расстояний от заданного элемента &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; до каждого из кластерных центров;&lt;br /&gt;
* последовательное сравнение полученных значений с целью отыскания максимума;&lt;br /&gt;
* операция записи 1 в соответствующий столбец матрицы принадлежности кластерным центрам;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; вершина отмечена символом &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит итоговый расчёт объектной функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; вершина помечена &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит проверка условия достижения требуемой точности.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Четвертая&#039;&#039;&#039; соответствует операции пересчёта кластерных центров, она отмечена как &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmeans.png|thumb|800px|center|Рисунок 1. Информационный граф алгоритма. Здесь &#039;&#039;&#039;&#039;&#039;in&#039;&#039;&#039;&#039;&#039; — ввод входных данных, &#039;&#039;&#039;&#039;&#039;D&#039;&#039;&#039;&#039;&#039; — вычисление минимального расстояния до кластерных центров и проставление принадлежности соответствующему кластерному центру, &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039; — вычисление объектной функции по результатам полученных вычислений, &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039; — проверка условия достижения желаемой точности, &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039; — пересчёт кластерных центров и &#039;&#039;&#039;&#039;&#039;out&#039;&#039;&#039;&#039;&#039; — вывод полученных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;(n+m)C&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;
Проведём исследование масштабируемости параллельной реализации строгого алгоритма C средних согласно [[Scalability methodology|методике]].&lt;br /&gt;
&lt;br /&gt;
Исследование проводилось на 1U сервере со &#039;&#039;&#039;следующими характеристиками&#039;&#039;&#039;:&lt;br /&gt;
*	2 x Intel® Xeon® Processor E5-2697 v2, всего 24 физических ядра (48 логических ядра при включенном Hyper-Threading);&lt;br /&gt;
*	128GB RAM;&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Сборка осуществлялась со следующими параметрами:&lt;br /&gt;
&lt;br /&gt;
*	GCC-4.8.4;&lt;br /&gt;
*	OpenMP-3.1;&lt;br /&gt;
*	аргументы компилятора: -std=c++11 -O3;&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число логических ядер [1 : 48] с шагом 2;&lt;br /&gt;
*	размерность пространства [3 : 50] c шагом 3;&lt;br /&gt;
*	число векторов 100 000 000;&lt;br /&gt;
*	число кластерных центров 30;&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон [[Глоссарий#Эффективность реализации|эффективности реализации]] алгоритма (отношение реальной производительности программы к пиковым показателям работы вычислительной системы):&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0.014;&lt;br /&gt;
*	максимальная эффективность реализации 0.9;&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики [[Глоссарий#Производительность|производительности]] и эффективности выбранной реализации HCM в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:GFLOPS_AA.png|thumb|center|700px|Рисунок 2. Параллельная реализация алгоритма. Изменение производительности в зависимости от числа процессоров и размерности векторов.]]&lt;br /&gt;
[[file:EFFICIENCY.png|thumb|center|700px|Рисунок 3. Параллельная реализация алгоритма. Изменение эффективности в зависимости от числа процессоров и размерности векторов.]]&lt;br /&gt;
&lt;br /&gt;
==== Реализация на языке C++ ====&lt;br /&gt;
[http://pastebin.com/31UkHgcW Исследованная параллельная реализация на языке C++]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=21233</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=21233"/>
		<updated>2016-12-18T18:08:28Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|{{REVISIONUSER}}}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(nmC)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(n+m)C&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания: [[Участник:Каледа_Александр|Каледа Александр]] (разделы [[#Общее описание алгоритма|1.1]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Информационный граф|1.7]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Входные и выходные данные алгоритма|1.9]]), [[Участник:Шапулин_Андрей|Шапулин Андрей]] (разделы [[#Математическое описание алгоритма|1.2]], [[#Вычислительное ядро алгоритма|1.3]], [[#Макроструктура алгоритма|1.4]], [[#Информационный граф|1.7]], [[#Свойства алгоритма|1.10]], [[#Существующие реализации алгоритма|2.7]]).&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;&amp;lt;ref&amp;gt;Jang, J.-S. R., Sun, C.-T. and Mizutani, E. (1997). Neuro-Fuzzy and Soft Computing, number&lt;br /&gt;
isbn 0-13-261066-3 in Matlab Curriculum Series, Prentice Hall, Upper Saddle River, NJ, USA.&amp;lt;/ref&amp;gt;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;[http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf Jantzen J. Neurofuzzy Modelling. 1998. Электронное издание. 28 Стр.]&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt;[http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf Нейский И.М. Классификация и сравнение методов кластеризации // Интеллектуальные технологии и системы. Сборник учебно-методических работ и статей аспирантов и студентов. – М.: НОК «CLAIM», 2006. – Выпуск 8. – С. 130-142.]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(nmC)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из 4 видов вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин отмечена символом &#039;&#039;&#039;&#039;&#039;M&#039;&#039;&#039;&#039;&#039;. Ей соответствует вычисление минимального расстояния до кластерных центров, а также запись единицы в соответствующий столбец матрицы, обозначающей принадлежность кластерному центру:&lt;br /&gt;
* независимое вычисление расстояний от заданного элемента &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; до каждого из кластерных центров;&lt;br /&gt;
* последовательное сравнение полученных значений с целью отыскания максимума;&lt;br /&gt;
* операция записи 1 в соответствующий столбец матрицы принадлежности кластерным центрам;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; вершина отмечена символом &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит итоговый расчёт объектной функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; вершина помечена &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит проверка условия достижения требуемой точности.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Четвертая&#039;&#039;&#039; соответствует операции пересчёта кластерных центров, она отмечена как &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmeans.png|thumb|800px|center|Рисунок 1. Информационный граф алгоритма. Здесь &#039;&#039;&#039;&#039;&#039;in&#039;&#039;&#039;&#039;&#039; — ввод входных данных, &#039;&#039;&#039;&#039;&#039;D&#039;&#039;&#039;&#039;&#039; — вычисление минимального расстояния до кластерных центров и проставление принадлежности соответствующему кластерному центру, &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039; — вычисление объектной функции по результатам полученных вычислений, &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039; — проверка условия достижения желаемой точности, &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039; — пересчёт кластерных центров и &#039;&#039;&#039;&#039;&#039;out&#039;&#039;&#039;&#039;&#039; — вывод полученных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;(n+m)C&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;
Проведём исследование масштабируемости параллельной реализации строгого алгоритма C средних согласно [[Scalability methodology|методике]].&lt;br /&gt;
&lt;br /&gt;
Исследование проводилось на 1U сервере со &#039;&#039;&#039;следующими характеристиками&#039;&#039;&#039;:&lt;br /&gt;
*	2 x Intel® Xeon® Processor E5-2697 v2, всего 24 физических ядра (48 логических ядра при включенном Hyper-Threading);&lt;br /&gt;
*	128GB RAM;&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Сборка осуществлялась со следующими параметрами:&lt;br /&gt;
&lt;br /&gt;
*	GCC-4.8.4;&lt;br /&gt;
*	OpenMP-3.1;&lt;br /&gt;
*	аргументы компилятора: -std=c++11 -O3;&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число логических ядер [1 : 48] с шагом 2;&lt;br /&gt;
*	размерность пространства [3 : 50] c шагом 3;&lt;br /&gt;
*	число векторов 100 000 000;&lt;br /&gt;
*	число кластерных центров 30;&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон [[Глоссарий#Эффективность реализации|эффективности реализации]] алгоритма (отношение реальной производительности программы к пиковым показателям работы вычислительной системы):&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0.014;&lt;br /&gt;
*	максимальная эффективность реализации 0.9;&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики [[Глоссарий#Производительность|производительности]] и эффективности выбранной реализации HCM в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:GFLOPS_AA_new.png|thumb|center|700px|Рисунок 2. Параллельная реализация алгоритма. Изменение производительности в зависимости от числа процессоров и размерности векторов.]]&lt;br /&gt;
[[file:EFFICIENCY_new.png|thumb|center|700px|Рисунок 3. Параллельная реализация алгоритма. Изменение эффективности в зависимости от числа процессоров и размерности векторов.]]&lt;br /&gt;
&lt;br /&gt;
==== Реализация на языке C++ ====&lt;br /&gt;
[http://pastebin.com/31UkHgcW Исследованная параллельная реализация на языке C++]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=21232</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=21232"/>
		<updated>2016-12-18T18:00:45Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|{{REVISIONUSER}}}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(nmC)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(n+m)C&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания: [[Участник:Каледа_Александр|Каледа Александр]] (разделы [[#Общее описание алгоритма|1.1]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Информационный граф|1.7]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Входные и выходные данные алгоритма|1.9]]), [[Участник:Шапулин_Андрей|Шапулин Андрей]] (разделы [[#Математическое описание алгоритма|1.2]], [[#Вычислительное ядро алгоритма|1.3]], [[#Макроструктура алгоритма|1.4]], [[#Информационный граф|1.7]], [[#Свойства алгоритма|1.10]], [[#Существующие реализации алгоритма|2.7]]).&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;&amp;lt;ref&amp;gt;Jang, J.-S. R., Sun, C.-T. and Mizutani, E. (1997). Neuro-Fuzzy and Soft Computing, number&lt;br /&gt;
isbn 0-13-261066-3 in Matlab Curriculum Series, Prentice Hall, Upper Saddle River, NJ, USA.&amp;lt;/ref&amp;gt;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;[http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf Jantzen J. Neurofuzzy Modelling. 1998. Электронное издание. 28 Стр.]&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt;[http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf Нейский И.М. Классификация и сравнение методов кластеризации // Интеллектуальные технологии и системы. Сборник учебно-методических работ и статей аспирантов и студентов. – М.: НОК «CLAIM», 2006. – Выпуск 8. – С. 130-142.]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(nmC)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из 4 видов вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин отмечена символом &#039;&#039;&#039;&#039;&#039;M&#039;&#039;&#039;&#039;&#039;. Ей соответствует вычисление минимального расстояния до кластерных центров, а также запись единицы в соответствующий столбец матрицы, обозначающей принадлежность кластерному центру:&lt;br /&gt;
* независимое вычисление расстояний от заданного элемента &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; до каждого из кластерных центров;&lt;br /&gt;
* последовательное сравнение полученных значений с целью отыскания максимума;&lt;br /&gt;
* операция записи 1 в соответствующий столбец матрицы принадлежности кластерным центрам;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; вершина отмечена символом &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит итоговый расчёт объектной функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; вершина помечена &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит проверка условия достижения требуемой точности.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Четвертая&#039;&#039;&#039; соответствует операции пересчёта кластерных центров, она отмечена как &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmeans.png|thumb|800px|center|Рисунок 1. Информационный граф алгоритма. Здесь &#039;&#039;&#039;&#039;&#039;in&#039;&#039;&#039;&#039;&#039; — ввод входных данных, &#039;&#039;&#039;&#039;&#039;D&#039;&#039;&#039;&#039;&#039; — вычисление минимального расстояния до кластерных центров и проставление принадлежности соответствующему кластерному центру, &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039; — вычисление объектной функции по результатам полученных вычислений, &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039; — проверка условия достижения желаемой точности, &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039; — пересчёт кластерных центров и &#039;&#039;&#039;&#039;&#039;out&#039;&#039;&#039;&#039;&#039; — вывод полученных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;(n+m)C&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;
Проведём исследование масштабируемости параллельной реализации строгого алгоритма C средних согласно [[Scalability methodology|методике]].&lt;br /&gt;
&lt;br /&gt;
Исследование проводилось на 1U сервере со &#039;&#039;&#039;следующими характеристиками&#039;&#039;&#039;:&lt;br /&gt;
*	2 x Intel® Xeon® Processor E5-2697 v2, всего 24 физических ядра (48 логических ядра при включенном Hyper-Thereading);&lt;br /&gt;
*	128GB RAM;&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Сборка осуществлялась со следующими параметрами:&lt;br /&gt;
&lt;br /&gt;
*	GCC-4.8.4;&lt;br /&gt;
*	OpenMP-3.1;&lt;br /&gt;
*	аргументы компилятора: -std=c++11 -O3;&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число логических ядер [1 : 48] с шагом 1;&lt;br /&gt;
*	размерность пространства [3 : 50] c шагом 3;&lt;br /&gt;
*	число векторов 100 000 000;&lt;br /&gt;
*	число кластерных центров 30;&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон [[Глоссарий#Эффективность реализации|эффективности реализации]] алгоритма (отношение реальной производительности программы к пиковым показателям работы вычислительной системы):&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0.014;&lt;br /&gt;
*	максимальная эффективность реализации 0.9;&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики [[Глоссарий#Производительность|производительности]] и эффективности выбранной реализации HCM в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:GFLOPS_AA.png|thumb|center|700px|Рисунок 2. Параллельная реализация алгоритма. Изменение производительности в зависимости от числа процессоров и размерности векторов.]]&lt;br /&gt;
[[file:EFFICIENCY.png|thumb|center|700px|Рисунок 3. Параллельная реализация алгоритма. Изменение эффективности в зависимости от числа процессоров и размерности векторов.]]&lt;br /&gt;
&lt;br /&gt;
==== Реализация на языке C++ ====&lt;br /&gt;
[http://pastebin.com/31UkHgcW Исследованная параллельная реализация на языке C++]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=21231</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=21231"/>
		<updated>2016-12-18T17:59:15Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|{{REVISIONUSER}}}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(nmC)&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(nC)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(n+m)C&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания: [[Участник:Каледа_Александр|Каледа Александр]] (разделы [[#Общее описание алгоритма|1.1]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Информационный граф|1.7]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Входные и выходные данные алгоритма|1.9]]), [[Участник:Шапулин_Андрей|Шапулин Андрей]] (разделы [[#Математическое описание алгоритма|1.2]], [[#Вычислительное ядро алгоритма|1.3]], [[#Макроструктура алгоритма|1.4]], [[#Информационный граф|1.7]], [[#Свойства алгоритма|1.10]], [[#Существующие реализации алгоритма|2.7]]).&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;&amp;lt;ref&amp;gt;Jang, J.-S. R., Sun, C.-T. and Mizutani, E. (1997). Neuro-Fuzzy and Soft Computing, number&lt;br /&gt;
isbn 0-13-261066-3 in Matlab Curriculum Series, Prentice Hall, Upper Saddle River, NJ, USA.&amp;lt;/ref&amp;gt;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;[http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf Jantzen J. Neurofuzzy Modelling. 1998. Электронное издание. 28 Стр.]&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt;[http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf Нейский И.М. Классификация и сравнение методов кластеризации // Интеллектуальные технологии и системы. Сборник учебно-методических работ и статей аспирантов и студентов. – М.: НОК «CLAIM», 2006. – Выпуск 8. – С. 130-142.]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(nmC)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из 4 видов вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин отмечена символом &#039;&#039;&#039;&#039;&#039;M&#039;&#039;&#039;&#039;&#039;. Ей соответствует вычисление минимального расстояния до кластерных центров, а также запись единицы в соответствующий столбец матрицы, обозначающей принадлежность кластерному центру:&lt;br /&gt;
* независимое вычисление расстояний от заданного элемента &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; до каждого из кластерных центров;&lt;br /&gt;
* последовательное сравнение полученных значений с целью отыскания максимума;&lt;br /&gt;
* операция записи 1 в соответствующий столбец матрицы принадлежности кластерным центрам;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; вершина отмечена символом &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит итоговый расчёт объектной функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; вершина помечена &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит проверка условия достижения требуемой точности.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Четвертая&#039;&#039;&#039; соответствует операции пересчёта кластерных центров, она отмечена как &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmeans.png|thumb|800px|center|Рисунок 1. Информационный граф алгоритма. Здесь &#039;&#039;&#039;&#039;&#039;in&#039;&#039;&#039;&#039;&#039; — ввод входных данных, &#039;&#039;&#039;&#039;&#039;D&#039;&#039;&#039;&#039;&#039; — вычисление минимального расстояния до кластерных центров и проставление принадлежности соответствующему кластерному центру, &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039; — вычисление объектной функции по результатам полученных вычислений, &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039; — проверка условия достижения желаемой точности, &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039; — пересчёт кластерных центров и &#039;&#039;&#039;&#039;&#039;out&#039;&#039;&#039;&#039;&#039; — вывод полученных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;(n+m)C&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;
Проведём исследование масштабируемости параллельной реализации строгого алгоритма C средних согласно [[Scalability methodology|методике]].&lt;br /&gt;
&lt;br /&gt;
Исследование проводилось на 1U сервере со &#039;&#039;&#039;следующими характеристиками&#039;&#039;&#039;:&lt;br /&gt;
*	2 x Intel® Xeon® Processor E5-2697 v2, всего 24 физических ядра (48 логических ядра при включенном Hyper-Thereading);&lt;br /&gt;
*	128GB RAM;&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Сборка осуществлялась со следующими параметрами:&lt;br /&gt;
&lt;br /&gt;
*	GCC-4.8.4;&lt;br /&gt;
*	OpenMP-3.1;&lt;br /&gt;
*	аргументы компилятора: -std=c++11 -O3;&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число логических ядер [1 : 48] с шагом 1;&lt;br /&gt;
*	размерность пространства [3 : 50] c шагом 3;&lt;br /&gt;
*	число векторов 100 000 000;&lt;br /&gt;
*	число кластерных центров 30;&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон [[Глоссарий#Эффективность реализации|эффективности реализации]] алгоритма (отношение реальной производительности программы к пиковым показателям работы вычислительной системы):&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0.014;&lt;br /&gt;
*	максимальная эффективность реализации 0.9;&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики [[Глоссарий#Производительность|производительности]] и эффективности выбранной реализации HCM в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:GFLOPS_AA.png|thumb|center|700px|Рисунок 2. Параллельная реализация алгоритма. Изменение производительности в зависимости от числа процессоров и размерности векторов.]]&lt;br /&gt;
[[file:EFFICIENCY.png|thumb|center|700px|Рисунок 3. Параллельная реализация алгоритма. Изменение эффективности в зависимости от числа процессоров и размерности векторов.]]&lt;br /&gt;
&lt;br /&gt;
==== Реализация на языке C++ ====&lt;br /&gt;
[http://pastebin.com/31UkHgcW Исследованная параллельная реализация на языке C++]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80&amp;diff=20364</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80&amp;diff=20364"/>
		<updated>2016-12-08T13:46:20Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: /* Статья Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Статья [[Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)]] =&lt;br /&gt;
* 1.6 — Не совсем понятно, как сложность алгоритма получилась меньше объёма входных данных. Она не зависит от m? [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 18:48, 5 декабря 2016 (MSK)&lt;br /&gt;
** В пункте 1.6 написано, что мы исходим из следующего предположения - размерность m и количество кластерных центров C существенно меньше n.&lt;br /&gt;
&lt;br /&gt;
* 2.4 — Написано, что исследование проводилось на системе с двумя процессорами E5-2697 v2. У них по 12 физических ядер [https://ark.intel.com/ru/products/75283/Intel-Xeon-Processor-E5-2697-v2-30M-Cache-2_70-GHz]. Как это согласуется с «number of processors», доходящим до 48 на графике? Всё, что выше 24 — определённо Hyper Threading. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 18:16, 5 декабря 2016 (MSK)&lt;br /&gt;
** Да, Вы правы, у нас был включен ht.&lt;br /&gt;
&lt;br /&gt;
----------------------&lt;br /&gt;
* Не указан вклад каждого автора [[Участник:Coctic|Coctic]] ([[Обсуждение участника:Coctic|обсуждение]]) 11:08, 25 октября 2016 (MSK)&lt;br /&gt;
** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 12:42, 2 ноября 2016 (MSK)&lt;br /&gt;
* Стоит добавить ссылку на оригинальную публикацию, в которой был впервые предложен алгоритм. [[Участник:Coctic|Coctic]] ([[Обсуждение участника:Coctic|обсуждение]]) 11:08, 25 октября 2016 (MSK)&lt;br /&gt;
** Не исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 12:42, 2 ноября 2016 (MSK)&lt;br /&gt;
* Значительная часть п. 1.2  совпадает с тем же пунктом из [[Строгий алгоритм С средних (Hard C-Means, HCM)]]&lt;br /&gt;
** Замечание снимается [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 12:42, 2 ноября 2016 (MSK)&lt;br /&gt;
* Пункты раздела 2 не соответствуют шаблону. П. 2.1 должен быть 2.4, п. 2.2 должен быть 2.7, остальные пункты пропущены [[Участник:Coctic|Coctic]] ([[Обсуждение участника:Coctic|обсуждение]]) 11:08, 25 октября 2016 (MSK)&lt;br /&gt;
** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 12:42, 2 ноября 2016 (MSK)&lt;br /&gt;
* В списке литературы отсутствуют выходные данные публикаций, кроме названия и автора. По приведенным данным определить конкретную публикацию не представляется возможным. [[Участник:Coctic|Coctic]] ([[Обсуждение участника:Coctic|обсуждение]]) 11:08, 25 октября 2016 (MSK)&lt;br /&gt;
** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 12:42, 2 ноября 2016 (MSK)&lt;br /&gt;
* Список литературы совпадает со списком из [[Строгий алгоритм С средних (Hard C-Means, HCM)]] [[Участник:Coctic|Coctic]] ([[Обсуждение участника:Coctic|обсуждение]]) 11:08, 25 октября 2016 (MSK)&lt;br /&gt;
** Замечание снимается [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 12:42, 2 ноября 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
------------&lt;br /&gt;
* Стоит добавить ссылку на оригинальную публикацию, в которой был впервые предложен алгоритм [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 12:42, 2 ноября 2016 (MSK)&lt;br /&gt;
** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 13:16, 23 ноября 2016 (MSK)&lt;br /&gt;
* п. 2.4.1 пустой. [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:35, 17 ноября 2016 (MSK)&lt;br /&gt;
** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 13:16, 23 ноября 2016 (MSK)&lt;br /&gt;
* п. 2.4.2. Отсутствует ссылка на текст исследуемой программы и аппаратную платформу, на которой проводилось тестирование. [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:35, 17 ноября 2016 (MSK)&lt;br /&gt;
** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 13:16, 23 ноября 2016 (MSK)&lt;br /&gt;
* Рис. 3. В подписи к рисунку не указано, график зависимости эффективности какого типа приведен. [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:35, 17 ноября 2016 (MSK)&lt;br /&gt;
** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 13:16, 23 ноября 2016 (MSK)&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=18983</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=18983"/>
		<updated>2016-11-22T20:24:33Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(n+m)C&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания: [[Участник:Каледа_Александр|Каледа Александр]] (разделы [[#Общее описание алгоритма|1.1]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Информационный граф|1.7]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Входные и выходные данные алгоритма|1.9]]), [[Участник:Шапулин_Андрей|Шапулин Андрей]] (разделы [[#Математическое описание алгоритма|1.2]], [[#Вычислительное ядро алгоритма|1.3]], [[#Макроструктура алгоритма|1.4]], [[#Информационный граф|1.7]], [[#Свойства алгоритма|1.10]], [[#Существующие реализации алгоритма|2.7]]).&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;&amp;lt;ref&amp;gt;Jang, J.-S. R., Sun, C.-T. and Mizutani, E. (1997). Neuro-Fuzzy and Soft Computing, number&lt;br /&gt;
isbn 0-13-261066-3 in Matlab Curriculum Series, Prentice Hall, Upper Saddle River, NJ, USA.&amp;lt;/ref&amp;gt;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;[http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf Jantzen J. Neurofuzzy Modelling. 1998. Электронное издание. 28 Стр.]&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt;[http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf Нейский И.М. Классификация и сравнение методов кластеризации // Интеллектуальные технологии и системы. Сборник учебно-методических работ и статей аспирантов и студентов. – М.: НОК «CLAIM», 2006. – Выпуск 8. – С. 130-142.]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из 4 видов вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин отмечена символом &#039;&#039;&#039;&#039;&#039;M&#039;&#039;&#039;&#039;&#039;. Ей соответствует вычисление минимального расстояния до кластерных центров, а также запись единицы в соответствующий столбец матрицы, обозначающей принадлежность кластерному центру:&lt;br /&gt;
* независимое вычисление расстояний от заданного элемента &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; до каждого из кластерных центров;&lt;br /&gt;
* последовательное сравнение полученных значений с целью отыскания максимума;&lt;br /&gt;
* операция записи 1 в соответствующий столбец матрицы принадлежности кластерным центрам;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; вершина отмечена символом &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит итоговый расчёт объектной функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; вершина помечена &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит проверка условия достижения требуемой точности.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Четвертая&#039;&#039;&#039; соответствует операции пересчёта кластерных центров, она отмечена как &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmeans.png|thumb|800px|center|Рисунок 1. Информационный граф алгоритма. Здесь &#039;&#039;&#039;&#039;&#039;in&#039;&#039;&#039;&#039;&#039; — ввод входных данных, &#039;&#039;&#039;&#039;&#039;D&#039;&#039;&#039;&#039;&#039; — вычисление минимального расстояния до кластерных центров и проставление принадлежности соответствующему кластерному центру, &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039; — вычисление объектной функции по результатам полученных вычислений, &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039; — проверка условия достижения желаемой точности, &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039; — пересчёт кластерных центров и &#039;&#039;&#039;&#039;&#039;out&#039;&#039;&#039;&#039;&#039; — вывод полученных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;(n+m)C&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;
Проведём исследование масштабируемости параллельной реализации строгого алгоритма C средних согласно [[Scalability methodology|методике]].&lt;br /&gt;
&lt;br /&gt;
Исследование проводилось на 1U сервере со &#039;&#039;&#039;следующими характеристиками&#039;&#039;&#039;:&lt;br /&gt;
*	2 x Intel® Xeon® Processor E5-2697 v2;&lt;br /&gt;
*	128GB RAM;&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Сборка осуществлялась со следующими параметрами:&lt;br /&gt;
&lt;br /&gt;
*	GCC-4.8.4;&lt;br /&gt;
*	OpenMP-3.1;&lt;br /&gt;
*	аргументы компилятора: -std=c++11 -O3;&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1 : 48] с шагом 1;&lt;br /&gt;
*	размерность пространства [3 : 50] c шагом 3;&lt;br /&gt;
*	число векторов 100 000 000;&lt;br /&gt;
*	число кластерных центров 30;&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон [[Глоссарий#Эффективность реализации|эффективности реализации]] алгоритма (отношение реальной производительности программы к пиковым показателям работы вычислительной системы):&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0.014;&lt;br /&gt;
*	максимальная эффективность реализации 0.9;&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики [[Глоссарий#Производительность|производительности]] и эффективности выбранной реализации HCM в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:GFLOPS_AA.png|thumb|center|700px|Рисунок 2. Параллельная реализация алгоритма. Изменение производительности в зависимости от числа процессоров и размерности векторов.]]&lt;br /&gt;
[[file:EFFICIENCY.png|thumb|center|700px|Рисунок 3. Параллельная реализация алгоритма. Изменение эффективности в зависимости от числа процессоров и размерности векторов.]]&lt;br /&gt;
&lt;br /&gt;
==== Реализация на языке C++ ====&lt;br /&gt;
[http://pastebin.com/31UkHgcW Исследованная параллельная реализация на языке C++]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=18982</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=18982"/>
		<updated>2016-11-22T20:23:18Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(n+m)C&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания: [[Участник:Каледа_Александр|Каледа Александр]] (разделы [[#Общее описание алгоритма|1.1]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Информационный граф|1.7]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Входные и выходные данные алгоритма|1.9]]), [[Участник:Шапулин_Андрей|Шапулин Андрей]] (разделы [[#Математическое описание алгоритма|1.2]], [[#Вычислительное ядро алгоритма|1.3]], [[#Макроструктура алгоритма|1.4]], [[#Информационный граф|1.7]], [[#Свойства алгоритма|1.10]], [[#Существующие реализации алгоритма|2.7]]).&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;&amp;lt;ref&amp;gt;Jang, J.-S. R., Sun, C.-T. and Mizutani, E. (1997). Neuro-Fuzzy and Soft Computing, number&lt;br /&gt;
isbn 0-13-261066-3 in Matlab Curriculum Series, Prentice Hall, Upper Saddle River, NJ, USA.&amp;lt;/ref&amp;gt;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;[http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf Jantzen J. Neurofuzzy Modelling. 1998. Электронное издание. 28 Стр.]&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt;[http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf Нейский И.М. Классификация и сравнение методов кластеризации // Интеллектуальные технологии и системы. Сборник учебно-методических работ и статей аспирантов и студентов. – М.: НОК «CLAIM», 2006. – Выпуск 8. – С. 130-142.]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из 4 видов вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин отмечена символом &#039;&#039;&#039;&#039;&#039;M&#039;&#039;&#039;&#039;&#039;. Ей соответствует вычисление минимального расстояния до кластерных центров, а также запись единицы в соответствующий столбец матрицы, обозначающей принадлежность кластерному центру:&lt;br /&gt;
* независимое вычисление расстояний от заданного элемента &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; до каждого из кластерных центров;&lt;br /&gt;
* последовательное сравнение полученных значений с целью отыскания максимума;&lt;br /&gt;
* операция записи 1 в соответствующий столбец матрицы принадлежности кластерным центрам;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; вершина отмечена символом &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит итоговый расчёт объектной функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; вершина помечена &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит проверка условия достижения требуемой точности.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Четвертая&#039;&#039;&#039; соответствует операции пересчёта кластерных центров, она отмечена как &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmeans.png|thumb|800px|center|Рисунок 1. Информационный граф алгоритма. Здесь &#039;&#039;&#039;&#039;&#039;in&#039;&#039;&#039;&#039;&#039; — ввод входных данных, &#039;&#039;&#039;&#039;&#039;D&#039;&#039;&#039;&#039;&#039; — вычисление минимального расстояния до кластерных центров и проставление принадлежности соответствующему кластерному центру, &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039; — вычисление объектной функции по результатам полученных вычислений, &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039; — проверка условия достижения желаемой точности, &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039; — пересчёт кластерных центров и &#039;&#039;&#039;&#039;&#039;out&#039;&#039;&#039;&#039;&#039; — вывод полученных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;(n+m)C&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;
Проведём исследование масштабируемости параллельной реализации строгого алгоритма C средних согласно [[Scalability methodology|методике]].&lt;br /&gt;
&lt;br /&gt;
Исследование проводилось на 1U сервере со &#039;&#039;&#039;следующими характеристиками&#039;&#039;&#039;:&lt;br /&gt;
*	2 x Intel® Xeon® Processor E5-2697 v2;&lt;br /&gt;
*	128GB RAM;&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Сборка осуществлялась со следующими параметрами:&lt;br /&gt;
&lt;br /&gt;
*	GCC-4.8.4;&lt;br /&gt;
*	OpenMP-3.1;&lt;br /&gt;
*	аргументы компилятора: -std=c++11 -O3;&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1 : 48] с шагом 1;&lt;br /&gt;
*	размерность пространства [3 : 50] c шагом 3;&lt;br /&gt;
*	число векторов 100 000 000;&lt;br /&gt;
*	число кластерных центров 30;&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон [[Глоссарий#Эффективность реализации|эффективности реализации]] алгоритма (отношение реальной производительности программы к пиковым показателям работы вычислительной системы):&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0.014;&lt;br /&gt;
*	максимальная эффективность реализации 0.9;&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики [[Глоссарий#Производительность|производительности]] и эффективности выбранной реализации HCM в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:GFLOPS_AA.png|thumb|center|700px|Рисунок 2. Параллельная реализация алгоритма. Изменение производительности в зависимости от числа процессоров и размерности векторов.]]&lt;br /&gt;
[[file:EFFICIENCY.png|thumb|center|700px|Рисунок 3. Параллельная реализация алгоритма. Изменение эффективности в зависимости от числа процессоров и размерности векторов.]]&lt;br /&gt;
&lt;br /&gt;
==== Реализация на языке C++ ====&lt;br /&gt;
[http://pastebin.com/31UkHgcW Исследованная параллельная реализация на языке C++]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=18981</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=18981"/>
		<updated>2016-11-22T20:14:36Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(n+m)C&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания: [[Участник:Каледа_Александр|Каледа Александр]] (разделы [[#Общее описание алгоритма|1.1]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Информационный граф|1.7]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Входные и выходные данные алгоритма|1.9]]), [[Участник:Шапулин_Андрей|Шапулин Андрей]] (разделы [[#Математическое описание алгоритма|1.2]], [[#Вычислительное ядро алгоритма|1.3]], [[#Макроструктура алгоритма|1.4]], [[#Информационный граф|1.7]], [[#Свойства алгоритма|1.10]], [[#Существующие реализации алгоритма|2.7]]).&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;&amp;lt;ref&amp;gt;Jang, J.-S. R., Sun, C.-T. and Mizutani, E. (1997). Neuro-Fuzzy and Soft Computing, number&lt;br /&gt;
isbn 0-13-261066-3 in Matlab Curriculum Series, Prentice Hall, Upper Saddle River, NJ, USA.&amp;lt;/ref&amp;gt;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;[http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf Jantzen J. Neurofuzzy Modelling. 1998. Электронное издание. 28 Стр.]&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt;[http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf Нейский И.М. Классификация и сравнение методов кластеризации // Интеллектуальные технологии и системы. Сборник учебно-методических работ и статей аспирантов и студентов. – М.: НОК «CLAIM», 2006. – Выпуск 8. – С. 130-142.]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из 4 видов вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин отмечена символом &#039;&#039;&#039;&#039;&#039;M&#039;&#039;&#039;&#039;&#039;. Ей соответствует вычисление минимального расстояния до кластерных центров, а также запись единицы в соответствующий столбец матрицы, обозначающей принадлежность кластерному центру:&lt;br /&gt;
* независимое вычисление расстояний от заданного элемента &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; до каждого из кластерных центров;&lt;br /&gt;
* последовательное сравнение полученных значений с целью отыскания максимума;&lt;br /&gt;
* операция записи 1 в соответствующий столбец матрицы принадлежности кластерным центрам;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; вершина отмечена символом &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит итоговый расчёт объектной функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; вершина помечена &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит проверка условия достижения требуемой точности.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Четвертая&#039;&#039;&#039; соответствует операции пересчёта кластерных центров, она отмечена как &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmeans.png|thumb|800px|center|Рисунок 1. Информационный граф алгоритма. Здесь &#039;&#039;&#039;&#039;&#039;in&#039;&#039;&#039;&#039;&#039; — ввод входных данных, &#039;&#039;&#039;&#039;&#039;D&#039;&#039;&#039;&#039;&#039; — вычисление минимального расстояния до кластерных центров и проставление принадлежности соответствующему кластерному центру, &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039; — вычисление объектной функции по результатам полученных вычислений, &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039; — проверка условия достижения желаемой точности, &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039; — пересчёт кластерных центров и &#039;&#039;&#039;&#039;&#039;out&#039;&#039;&#039;&#039;&#039; — вывод полученных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;(n+m)C&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;
Проведём исследование масштабируемости параллельной реализации строгого алгоритма C средних согласно [[Scalability methodology|методике]].&lt;br /&gt;
&lt;br /&gt;
Исследование проводилось на 1U сервере со &#039;&#039;&#039;следующими характеристиками&#039;&#039;&#039;:&lt;br /&gt;
*	2 x Intel® Xeon® Processor E5-2697 v2;&lt;br /&gt;
*	128GB RAM;&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Сборка осуществлялась со следующими параметрами:&lt;br /&gt;
&lt;br /&gt;
*	GCC-4.8.4;&lt;br /&gt;
*	OpenMP-3.1;&lt;br /&gt;
*	аргументы компилятора: -std=c++11 -O3;&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1 : 48] с шагом 1;&lt;br /&gt;
*	размерность пространства [3 : 50] c шагом 3;&lt;br /&gt;
*	число векторов 100 000 000;&lt;br /&gt;
*	число кластерных центров 30;&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон [[Глоссарий#Эффективность реализации|эффективности реализации]] алгоритма:&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0.014;&lt;br /&gt;
*	максимальная эффективность реализации 0.9;&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики [[Глоссарий#Производительность|производительности]] и эффективности выбранной реализации HCM в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:GFLOPS_AA.png|thumb|center|700px|Рисунок 2. Параллельная реализация алгоритма. Изменение производительности в зависимости от числа процессоров и размерности векторов.]]&lt;br /&gt;
[[file:EFFICIENCY.png|thumb|center|700px|Рисунок 3. Параллельная реализация алгоритма. Изменение эффективности в зависимости от числа процессоров и размерности векторов.]]&lt;br /&gt;
&lt;br /&gt;
==== Реализация на языке C++ ====&lt;br /&gt;
[http://pastebin.com/31UkHgcW Исследованная параллельная реализация на языке C++]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=18979</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=18979"/>
		<updated>2016-11-22T19:55:51Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: /* Общее описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(n+m)C&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания: [[Участник:Каледа_Александр|Каледа Александр]] (разделы [[#Общее описание алгоритма|1.1]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Информационный граф|1.7]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Входные и выходные данные алгоритма|1.9]]), [[Участник:Шапулин_Андрей|Шапулин Андрей]] (разделы [[#Математическое описание алгоритма|1.2]], [[#Вычислительное ядро алгоритма|1.3]], [[#Макроструктура алгоритма|1.4]], [[#Информационный граф|1.7]], [[#Свойства алгоритма|1.10]], [[#Существующие реализации алгоритма|2.7]]).&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;&amp;lt;ref&amp;gt;Jang, J.-S. R., Sun, C.-T. and Mizutani, E. (1997). Neuro-Fuzzy and Soft Computing, number&lt;br /&gt;
isbn 0-13-261066-3 in Matlab Curriculum Series, Prentice Hall, Upper Saddle River, NJ, USA.&amp;lt;/ref&amp;gt;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;[http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf Jantzen J. Neurofuzzy Modelling. 1998. Электронное издание. 28 Стр.]&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt;[http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf Нейский И.М. Классификация и сравнение методов кластеризации // Интеллектуальные технологии и системы. Сборник учебно-методических работ и статей аспирантов и студентов. – М.: НОК «CLAIM», 2006. – Выпуск 8. – С. 130-142.]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из 4 видов вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин отмечена символом &#039;&#039;&#039;&#039;&#039;M&#039;&#039;&#039;&#039;&#039;. Ей соответствует вычисление минимального расстояния до кластерных центров, а также запись единицы в соответствующий столбец матрицы, обозначающей принадлежность кластерному центру:&lt;br /&gt;
* независимое вычисление расстояний от заданного элемента &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; до каждого из кластерных центров;&lt;br /&gt;
* последовательное сравнение полученных значений с целью отыскания максимума;&lt;br /&gt;
* операция записи 1 в соответствующий столбец матрицы принадлежности кластерным центрам;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; вершина отмечена символом &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит итоговый расчёт объектной функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; вершина помечена &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит проверка условия достижения требуемой точности.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Четвертая&#039;&#039;&#039; соответствует операции пересчёта кластерных центров, она отмечена как &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmeans.png|thumb|800px|center|Рисунок 1. Информационный граф алгоритма. Здесь &#039;&#039;&#039;&#039;&#039;in&#039;&#039;&#039;&#039;&#039; — ввод входных данных, &#039;&#039;&#039;&#039;&#039;D&#039;&#039;&#039;&#039;&#039; — вычисление минимального расстояния до кластерных центров и проставление принадлежности соответствующему кластерному центру, &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039; — вычисление объектной функции по результатам полученных вычислений, &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039; — проверка условия достижения желаемой точности, &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039; — пересчёт кластерных центров и &#039;&#039;&#039;&#039;&#039;out&#039;&#039;&#039;&#039;&#039; — вывод полученных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;(n+m)C&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;
Проведём исследование масштабируемости параллельной реализации строгого алгоритма C средних согласно [[Scalability methodology|методике]].&lt;br /&gt;
&lt;br /&gt;
Исследование проводилось на 1U сервере со &#039;&#039;&#039;следующими характеристиками&#039;&#039;&#039;:&lt;br /&gt;
*	2 x Intel® Xeon® Processor E5-2697 v2;&lt;br /&gt;
*	128GB RAM;&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1 : 48] с шагом 1;&lt;br /&gt;
*	размерность пространства [3 : 50] c шагом 3;&lt;br /&gt;
*	число векторов 100 000 000;&lt;br /&gt;
*	число кластерных центров 30;&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон [[Глоссарий#Эффективность реализации|эффективности реализации]] алгоритма:&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0.014;&lt;br /&gt;
*	максимальная эффективность реализации 0.9;&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики [[Глоссарий#Производительность|производительности]] и эффективности выбранной реализации HCM в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:GFLOPS_AA.png|thumb|center|700px|Рисунок 2. Параллельная реализация алгоритма. Изменение производительности в зависимости от числа процессоров и размерности векторов.]]&lt;br /&gt;
[[file:EFFICIENCY.png|thumb|center|700px|Рисунок 3. Параллельная реализация алгоритма. Изменение эффективности в зависимости от числа процессоров и размерности векторов.]]&lt;br /&gt;
&lt;br /&gt;
==== Реализация на языке C++ ====&lt;br /&gt;
[http://pastebin.com/31UkHgcW Исследованная параллельная реализация на языке C++]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=18978</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=18978"/>
		<updated>2016-11-22T19:51:46Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(n+m)C&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания: [[Участник:Каледа_Александр|Каледа Александр]] (разделы [[#Общее описание алгоритма|1.1]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Информационный граф|1.7]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Входные и выходные данные алгоритма|1.9]]), [[Участник:Шапулин_Андрей|Шапулин Андрей]] (разделы [[#Математическое описание алгоритма|1.2]], [[#Вычислительное ядро алгоритма|1.3]], [[#Макроструктура алгоритма|1.4]], [[#Информационный граф|1.7]], [[#Свойства алгоритма|1.10]], [[#Существующие реализации алгоритма|2.7]]).&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;[http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf Jantzen J. Neurofuzzy Modelling. 1998. Электронное издание. 28 Стр.]&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt;[http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf Нейский И.М. Классификация и сравнение методов кластеризации // Интеллектуальные технологии и системы. Сборник учебно-методических работ и статей аспирантов и студентов. – М.: НОК «CLAIM», 2006. – Выпуск 8. – С. 130-142.]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из 4 видов вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин отмечена символом &#039;&#039;&#039;&#039;&#039;M&#039;&#039;&#039;&#039;&#039;. Ей соответствует вычисление минимального расстояния до кластерных центров, а также запись единицы в соответствующий столбец матрицы, обозначающей принадлежность кластерному центру:&lt;br /&gt;
* независимое вычисление расстояний от заданного элемента &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; до каждого из кластерных центров;&lt;br /&gt;
* последовательное сравнение полученных значений с целью отыскания максимума;&lt;br /&gt;
* операция записи 1 в соответствующий столбец матрицы принадлежности кластерным центрам;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; вершина отмечена символом &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит итоговый расчёт объектной функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; вершина помечена &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит проверка условия достижения требуемой точности.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Четвертая&#039;&#039;&#039; соответствует операции пересчёта кластерных центров, она отмечена как &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmeans.png|thumb|800px|center|Рисунок 1. Информационный граф алгоритма. Здесь &#039;&#039;&#039;&#039;&#039;in&#039;&#039;&#039;&#039;&#039; — ввод входных данных, &#039;&#039;&#039;&#039;&#039;D&#039;&#039;&#039;&#039;&#039; — вычисление минимального расстояния до кластерных центров и проставление принадлежности соответствующему кластерному центру, &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039; — вычисление объектной функции по результатам полученных вычислений, &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039; — проверка условия достижения желаемой точности, &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039; — пересчёт кластерных центров и &#039;&#039;&#039;&#039;&#039;out&#039;&#039;&#039;&#039;&#039; — вывод полученных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;(n+m)C&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;
Проведём исследование масштабируемости параллельной реализации строгого алгоритма C средних согласно [[Scalability methodology|методике]].&lt;br /&gt;
&lt;br /&gt;
Исследование проводилось на 1U сервере со &#039;&#039;&#039;следующими характеристиками&#039;&#039;&#039;:&lt;br /&gt;
*	2 x Intel® Xeon® Processor E5-2697 v2;&lt;br /&gt;
*	128GB RAM;&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1 : 48] с шагом 1;&lt;br /&gt;
*	размерность пространства [3 : 50] c шагом 3;&lt;br /&gt;
*	число векторов 100 000 000;&lt;br /&gt;
*	число кластерных центров 30;&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон [[Глоссарий#Эффективность реализации|эффективности реализации]] алгоритма:&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0.014;&lt;br /&gt;
*	максимальная эффективность реализации 0.9;&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики [[Глоссарий#Производительность|производительности]] и эффективности выбранной реализации HCM в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:GFLOPS_AA.png|thumb|center|700px|Рисунок 2. Параллельная реализация алгоритма. Изменение производительности в зависимости от числа процессоров и размерности векторов.]]&lt;br /&gt;
[[file:EFFICIENCY.png|thumb|center|700px|Рисунок 3. Параллельная реализация алгоритма. Изменение эффективности в зависимости от числа процессоров и размерности векторов.]]&lt;br /&gt;
&lt;br /&gt;
==== Реализация на языке C++ ====&lt;br /&gt;
[http://pastebin.com/31UkHgcW Исследованная параллельная реализация на языке C++]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=18977</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=18977"/>
		<updated>2016-11-22T19:49:25Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(n+m)C&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания: [[Участник:Каледа_Александр|Каледа Александр]] (разделы [[#Общее описание алгоритма|1.1]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Информационный граф|1.7]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Входные и выходные данные алгоритма|1.9]]), [[Участник:Шапулин_Андрей|Шапулин Андрей]] (разделы [[#Математическое описание алгоритма|1.2]], [[#Вычислительное ядро алгоритма|1.3]], [[#Макроструктура алгоритма|1.4]], [[#Информационный граф|1.7]], [[#Свойства алгоритма|1.10]], [[#Существующие реализации алгоритма|2.7]]).&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;[http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf Jantzen J. Neurofuzzy Modelling. 1998. Электронное издание. 28 Стр.]&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt;[http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf Нейский И.М. Классификация и сравнение методов кластеризации // Интеллектуальные технологии и системы. Сборник учебно-методических работ и статей аспирантов и студентов. – М.: НОК «CLAIM», 2006. – Выпуск 8. – С. 130-142.]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из 4 видов вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин отмечена символом &#039;&#039;&#039;&#039;&#039;M&#039;&#039;&#039;&#039;&#039;. Ей соответствует вычисление минимального расстояния до кластерных центров, а также запись единицы в соответствующий столбец матрицы, обозначающей принадлежность кластерному центру:&lt;br /&gt;
* независимое вычисление расстояний от заданного элемента &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; до каждого из кластерных центров;&lt;br /&gt;
* последовательное сравнение полученных значений с целью отыскания максимума;&lt;br /&gt;
* операция записи 1 в соответствующий столбец матрицы принадлежности кластерным центрам;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; вершина отмечена символом &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит итоговый расчёт объектной функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; вершина помечена &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит проверка условия достижения требуемой точности.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Четвертая&#039;&#039;&#039; соответствует операции пересчёта кластерных центров, она отмечена как &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmeans.png|thumb|800px|center|Рисунок 1. Информационный граф алгоритма. Здесь &#039;&#039;&#039;&#039;&#039;in&#039;&#039;&#039;&#039;&#039; — ввод входных данных, &#039;&#039;&#039;&#039;&#039;D&#039;&#039;&#039;&#039;&#039; — вычисление минимального расстояния до кластерных центров и проставление принадлежности соответствующему кластерному центру, &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039; — вычисление объектной функции по результатам полученных вычислений, &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039; — проверка условия достижения желаемой точности, &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039; — пересчёт кластерных центров и &#039;&#039;&#039;&#039;&#039;out&#039;&#039;&#039;&#039;&#039; — вывод полученных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;(n+m)C&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;
Проведём исследование масштабируемости параллельной реализации строгого алгоритма C средних согласно [[Scalability methodology|методике]].&lt;br /&gt;
&lt;br /&gt;
Исследование проводилось на 1U сервере со следующими характеристиками:&lt;br /&gt;
*	2 x Intel® Xeon® Processor E5-2697 v2;&lt;br /&gt;
*	128GB RAM;&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1 : 48] с шагом 1;&lt;br /&gt;
*	размерность пространства [3 : 50] c шагом 3;&lt;br /&gt;
*	число векторов 100 000 000;&lt;br /&gt;
*	число кластерных центров 30;&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон [[Глоссарий#Эффективность реализации|эффективности реализации]] алгоритма:&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0.014;&lt;br /&gt;
*	максимальная эффективность реализации 0.9;&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики [[Глоссарий#Производительность|производительности]] и эффективности выбранной реализации HCM в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:GFLOPS_AA.png|thumb|center|700px|Рисунок 2. Параллельная реализация алгоритма. Изменение производительности в зависимости от числа процессоров и размерности векторов.]]&lt;br /&gt;
[[file:EFFICIENCY.png|thumb|center|700px|Рисунок 3. Параллельная реализация алгоритма. Изменение эффективности в зависимости от числа процессоров и размерности векторов.]]&lt;br /&gt;
&lt;br /&gt;
==== Реализация на языке C++ ====&lt;br /&gt;
[http://pastebin.com/31UkHgcW Исследованная параллельная реализация на языке C++]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=18291</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=18291"/>
		<updated>2016-11-18T20:21:48Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(n+m)C&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания: [[Участник:Каледа_Александр|Каледа Александр]] (разделы [[#Общее описание алгоритма|1.1]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Информационный граф|1.7]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Входные и выходные данные алгоритма|1.9]]), [[Участник:Шапулин_Андрей|Шапулин Андрей]] (разделы [[#Математическое описание алгоритма|1.2]], [[#Вычислительное ядро алгоритма|1.3]], [[#Макроструктура алгоритма|1.4]], [[#Информационный граф|1.7]], [[#Свойства алгоритма|1.10]], [[#Существующие реализации алгоритма|2.7]]).&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;[http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf Jantzen J. Neurofuzzy Modelling. 1998. Электронное издание. 28 Стр.]&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt;[http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf Нейский И.М. Классификация и сравнение методов кластеризации // Интеллектуальные технологии и системы. Сборник учебно-методических работ и статей аспирантов и студентов. – М.: НОК «CLAIM», 2006. – Выпуск 8. – С. 130-142.]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из 4 видов вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин отмечена символом &#039;&#039;&#039;&#039;&#039;M&#039;&#039;&#039;&#039;&#039;. Ей соответствует вычисление минимального расстояния до кластерных центров, а также запись единицы в соответствующий столбец матрицы, обозначающей принадлежность кластерному центру:&lt;br /&gt;
* независимое вычисление расстояний от заданного элемента &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; до каждого из кластерных центров;&lt;br /&gt;
* последовательное сравнение полученных значений с целью отыскания максимума;&lt;br /&gt;
* операция записи 1 в соответствующий столбец матрицы принадлежности кластерным центрам;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; вершина отмечена символом &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит итоговый расчёт объектной функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; вершина помечена &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит проверка условия достижения требуемой точности.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Четвертая&#039;&#039;&#039; соответствует операции пересчёта кластерных центров, она отмечена как &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmeans.png|thumb|800px|center|Рисунок 1. Информационный граф алгоритма. Здесь &#039;&#039;&#039;&#039;&#039;in&#039;&#039;&#039;&#039;&#039; — ввод входных данных, &#039;&#039;&#039;&#039;&#039;D&#039;&#039;&#039;&#039;&#039; — вычисление минимального расстояния до кластерных центров и проставление принадлежности соответствующему кластерному центру, &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039; — вычисление объектной функции по результатам полученных вычислений, &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039; — проверка условия достижения желаемой точности, &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039; — пересчёт кластерных центров и &#039;&#039;&#039;&#039;&#039;out&#039;&#039;&#039;&#039;&#039; — вывод полученных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;(n+m)C&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;
Проведём исследование масштабируемости параллельной реализации строгого алгоритма C средних согласно [[Scalability methodology|методике]].&lt;br /&gt;
&lt;br /&gt;
Исследование проводилось на 1U сервере со следующими характеристиками:&lt;br /&gt;
*	2 x Intel® Xeon® Processor E5-2697 v2;&lt;br /&gt;
*	128GB RAM;&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1 : 48] с шагом 1;&lt;br /&gt;
*	размерность пространства [3 : 50] c шагом 3;&lt;br /&gt;
*	число векторов 100 000 000;&lt;br /&gt;
*	число кластерных центров 30;&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон [[Глоссарий#Эффективность реализации|эффективности реализации]] алгоритма:&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0.014;&lt;br /&gt;
*	максимальная эффективность реализации 0.9;&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики [[Глоссарий#Производительность|производительности]] и эффективности выбранной реализации HCM в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:GFLOPS_AA.png|thumb|center|700px|Рисунок 2. Параллельная реализация алгоритма. Изменение производительности в зависимости от числа процессоров и размерности векторов.]]&lt;br /&gt;
[[file:EFFICIENCY.png|thumb|center|700px|Рисунок 3. Параллельная реализация алгоритма. Изменение эффективности в зависимости от числа процессоров и размерности векторов.]]&lt;br /&gt;
&lt;br /&gt;
[http://pastebin.com/31UkHgcW Исследованная параллельная реализация на языке C++]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=18288</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=18288"/>
		<updated>2016-11-18T20:20:53Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(n+m)C&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания: [[Участник:Каледа_Александр|Каледа Александр]] (разделы [[#Общее описание алгоритма|1.1]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Информационный граф|1.7]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Входные и выходные данные алгоритма|1.9]]), [[Участник:Шапулин_Андрей|Шапулин Андрей]] (разделы [[#Математическое описание алгоритма|1.2]], [[#Вычислительное ядро алгоритма|1.3]], [[#Макроструктура алгоритма|1.4]], [[#Информационный граф|1.7]], [[#Свойства алгоритма|1.10]], [[#Существующие реализации алгоритма|2.7]]).&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;[http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf Jantzen J. Neurofuzzy Modelling. 1998. Электронное издание. 28 Стр.]&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt;[http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf Нейский И.М. Классификация и сравнение методов кластеризации // Интеллектуальные технологии и системы. Сборник учебно-методических работ и статей аспирантов и студентов. – М.: НОК «CLAIM», 2006. – Выпуск 8. – С. 130-142.]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из 4 видов вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин отмечена символом &#039;&#039;&#039;&#039;&#039;M&#039;&#039;&#039;&#039;&#039;. Ей соответствует вычисление минимального расстояния до кластерных центров, а также запись единицы в соответствующий столбец матрицы, обозначающей принадлежность кластерному центру:&lt;br /&gt;
* независимое вычисление расстояний от заданного элемента &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; до каждого из кластерных центров;&lt;br /&gt;
* последовательное сравнение полученных значений с целью отыскания максимума;&lt;br /&gt;
* операция записи 1 в соответствующий столбец матрицы принадлежности кластерным центрам;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; вершина отмечена символом &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит итоговый расчёт объектной функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; вершина помечена &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит проверка условия достижения требуемой точности.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Четвертая&#039;&#039;&#039; соответствует операции пересчёта кластерных центров, она отмечена как &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmeans.png|thumb|800px|center|Рисунок 1. Информационный граф алгоритма. Здесь &#039;&#039;&#039;&#039;&#039;in&#039;&#039;&#039;&#039;&#039; — ввод входных данных, &#039;&#039;&#039;&#039;&#039;D&#039;&#039;&#039;&#039;&#039; — вычисление минимального расстояния до кластерных центров и проставление принадлежности соответствующему кластерному центру, &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039; — вычисление объектной функции по результатам полученных вычислений, &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039; — проверка условия достижения желаемой точности, &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039; — пересчёт кластерных центров и &#039;&#039;&#039;&#039;&#039;out&#039;&#039;&#039;&#039;&#039; — вывод полученных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;(n+m)C&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;
Проведём исследование масштабируемости параллельной реализации строгого алгоритма C средних согласно [[Scalability methodology|методике]].&lt;br /&gt;
&lt;br /&gt;
Исследование проводилось на 1U сервере со следующими характеристиками:&lt;br /&gt;
*	2 x Intel® Xeon® Processor E5-2697 v2&lt;br /&gt;
*	128GB RAM&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1 : 48] с шагом 1;&lt;br /&gt;
*	размерность пространства [3 : 50] c шагом 3;&lt;br /&gt;
*	число векторов 100 000 000;&lt;br /&gt;
*	число кластерных центров 30;&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон [[Глоссарий#Эффективность реализации|эффективности реализации]] алгоритма:&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0.014;&lt;br /&gt;
*	максимальная эффективность реализации 0.9;&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики [[Глоссарий#Производительность|производительности]] и эффективности выбранной реализации HCM в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:GFLOPS_AA.png|thumb|center|700px|Рисунок 2. Параллельная реализация алгоритма. Изменение производительности в зависимости от числа процессоров и размерности векторов.]]&lt;br /&gt;
[[file:EFFICIENCY.png|thumb|center|700px|Рисунок 3. Параллельная реализация алгоритма. Изменение эффективности в зависимости от числа процессоров и размерности векторов.]]&lt;br /&gt;
&lt;br /&gt;
[http://pastebin.com/31UkHgcW Исследованная параллельная реализация на языке C++]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=17501</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=17501"/>
		<updated>2016-11-15T22:09:35Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(n+m)C&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания: [[Участник:Каледа_Александр|Каледа Александр]] (разделы [[#Общее описание алгоритма|1.1]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Информационный граф|1.7]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Входные и выходные данные алгоритма|1.9]]), [[Участник:Шапулин_Андрей|Шапулин Андрей]] (разделы [[#Математическое описание алгоритма|1.2]], [[#Вычислительное ядро алгоритма|1.3]], [[#Макроструктура алгоритма|1.4]], [[#Информационный граф|1.7]], [[#Свойства алгоритма|1.10]], [[#Существующие реализации алгоритма|2.7]]).&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;[http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf Jantzen J. Neurofuzzy Modelling. 1998. Электронное издание. 28 Стр.]&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt;[http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf Нейский И.М. Классификация и сравнение методов кластеризации // Интеллектуальные технологии и системы. Сборник учебно-методических работ и статей аспирантов и студентов. – М.: НОК «CLAIM», 2006. – Выпуск 8. – С. 130-142.]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из 4 видов вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин отмечена символом &#039;&#039;&#039;&#039;&#039;M&#039;&#039;&#039;&#039;&#039;. Ей соответствует вычисление минимального расстояния до кластерных центров, а также запись единицы в соответствующий столбец матрицы, обозначающей принадлежность кластерному центру:&lt;br /&gt;
* независимое вычисление расстояний от заданного элемента &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; до каждого из кластерных центров;&lt;br /&gt;
* последовательное сравнение полученных значений с целью отыскания максимума;&lt;br /&gt;
* операция записи 1 в соответствующий столбец матрицы принадлежности кластерным центрам;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; вершина отмечена символом &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит итоговый расчёт объектной функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; вершина помечена &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит проверка условия достижения требуемой точности.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Четвертая&#039;&#039;&#039; соответствует операции пересчёта кластерных центров, она отмечена как &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmeans.png|thumb|800px|center|Рисунок 1. Информационный граф алгоритма. Здесь &#039;&#039;&#039;&#039;&#039;in&#039;&#039;&#039;&#039;&#039; — ввод входных данных, &#039;&#039;&#039;&#039;&#039;D&#039;&#039;&#039;&#039;&#039; — вычисление минимального расстояния до кластерных центров и проставление принадлежности соответствующему кластерному центру, &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039; — вычисление объектной функции по результатам полученных вычислений, &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039; — проверка условия достижения желаемой точности, &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039; — пересчёт кластерных центров и &#039;&#039;&#039;&#039;&#039;out&#039;&#039;&#039;&#039;&#039; — вывод полученных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;(n+m)C&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;
Проведём исследование масштабируемости параллельной реализации строгого алгоритма C средних согласно [[Scalability methodology|методике]]. &lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1 : 48] с шагом 1;&lt;br /&gt;
*	размерность пространства [3 : 50] c шагом 3;&lt;br /&gt;
*	число векторов 100 000 000;&lt;br /&gt;
*	число кластерных центров 30;&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон [[Глоссарий#Эффективность реализации|эффективности реализации]] алгоритма:&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0.014;&lt;br /&gt;
*	максимальная эффективность реализации 0.9.&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики [[Глоссарий#Производительность|производительности]] и эффективности выбранной реализации HCM в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:GFLOPS_AA.png|thumb|center|700px|Рисунок 2. Параллельная реализация алгоритма. Изменение производительности в зависимости от числа процессоров и размерности векторов.]]&lt;br /&gt;
[[file:EFFICIENCY.png|thumb|center|700px|Рисунок 3. Параллельная реализация алгоритма. Изменение эффективности в зависимости от числа процессоров и размерности векторов.]]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=17500</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=17500"/>
		<updated>2016-11-15T22:07:51Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(n+m)C&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания: [[Участник:Каледа_Александр|Каледа Александр]] (разделы [[#Общее описание алгоритма|1.1]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Информационный граф|1.7]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Входные и выходные данные алгоритма|1.9]]), [[Участник:Шапулин_Андрей|Шапулин Андрей]] (разделы [[#Математическое описание алгоритма|1.2]], [[#Вычислительное ядро алгоритма|1.3]], [[#Макроструктура алгоритма|1.4]], [[#Информационный граф|1.7]], [[#Свойства алгоритма|1.10]], [[#Существующие реализации алгоритма|2.7]]).&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;[http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf Jantzen J. Neurofuzzy Modelling. 1998. Электронное издание. 28 Стр.]&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt;[http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf Нейский И.М. Классификация и сравнение методов кластеризации // Интеллектуальные технологии и системы. Сборник учебно-методических работ и статей аспирантов и студентов. – М.: НОК «CLAIM», 2006. – Выпуск 8. – С. 130-142.]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из 4 видов вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин отмечена символом &#039;&#039;&#039;&#039;&#039;M&#039;&#039;&#039;&#039;&#039;. Ей соответствует вычисление минимального расстояния до кластерных центров, а также запись единицы в соответствующий столбец матрицы, обозначающей принадлежность кластерному центру:&lt;br /&gt;
* независимое вычисление расстояний от заданного элемента &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; до каждого из кластерных центров;&lt;br /&gt;
* последовательное сравнение полученных значений с целью отыскания максимума;&lt;br /&gt;
* операция записи 1 в соответствующий столбец матрицы принадлежности кластерным центрам;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; вершина отмечена символом &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит итоговый расчёт объектной функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; вершина помечена &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит проверка условия достижения требуемой точности.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Четвертая&#039;&#039;&#039; соответствует операции пересчёта кластерных центров, она отмечена как &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmeans.png|thumb|800px|center|Рисунок 1. Информационный граф алгоритма. Здесь &#039;&#039;&#039;&#039;&#039;in&#039;&#039;&#039;&#039;&#039; — ввод входных данных, &#039;&#039;&#039;&#039;&#039;D&#039;&#039;&#039;&#039;&#039; — вычисление минимального расстояния до кластерных центров и проставление принадлежности соответствующему кластерному центру, &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039; — вычисление объектной функции по результатам полученных вычислений, &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039; — проверка условия достижения желаемой точности, &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039; — пересчёт кластерных центров и &#039;&#039;&#039;&#039;&#039;out&#039;&#039;&#039;&#039;&#039; — вывод полученных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;(n+m)C&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;
Проведём исследование масштабируемости параллельной реализации строгого алгоритма C средних согласно [[Scalability methodology|методике]]. &lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1 : 48] с шагом 1;&lt;br /&gt;
*	размерность пространства [3 : 50] c шагом 3;&lt;br /&gt;
*	число векторов 100 000 000;&lt;br /&gt;
*	число кластерных центров 30;&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон [[Глоссарий#Эффективность реализации|эффективности реализации]] алгоритма:&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0.014;&lt;br /&gt;
*	максимальная эффективность реализации 0.9.&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики [[Глоссарий#Производительность|производительности]] и эффективности выбранной реализации HCM в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:GFLOPS_AA.png|thumb|center|700px|Рисунок 2. Параллельная реализация алгоритма. Изменение производительности в зависимости от числа процессоров и размерности векторов.]]&lt;br /&gt;
[[file:EFFICIENCY.png|thumb|center|700px|Рисунок 3. Параллельная реализация алгоритма. Изменение эффективности в зависимости от числа процессоров и размерности векторов.]]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=17351</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=17351"/>
		<updated>2016-11-15T18:48:18Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(n+m)C&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания: [[Участник:Каледа_Александр|Каледа Александр]] (разделы [[#Общее описание алгоритма|1.1]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Информационный граф|1.7]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Входные и выходные данные алгоритма|1.9]]), [[Участник:Шапулин_Андрей|Шапулин Андрей]] (разделы [[#Математическое описание алгоритма|1.2]], [[#Вычислительное ядро алгоритма|1.3]], [[#Макроструктура алгоритма|1.4]], [[#Информационный граф|1.7]], [[#Свойства алгоритма|1.10]], [[#Существующие реализации алгоритма|2.7]]).&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;[http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf Jantzen J. Neurofuzzy Modelling. 1998. Электронное издание. 28 Стр.]&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt;[http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf Нейский И.М. Классификация и сравнение методов кластеризации // Интеллектуальные технологии и системы. Сборник учебно-методических работ и статей аспирантов и студентов. – М.: НОК «CLAIM», 2006. – Выпуск 8. – С. 130-142.]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из 4 видов вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин отмечена символом &#039;&#039;&#039;&#039;&#039;M&#039;&#039;&#039;&#039;&#039;. Ей соответствует вычисление минимального расстояния до кластерных центров, а также запись единицы в соответствующий столбец матрицы, обозначающей принадлежность кластерному центру:&lt;br /&gt;
* независимое вычисление расстояний от заданного элемента &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; до каждого из кластерных центров;&lt;br /&gt;
* последовательное сравнение полученных значений с целью отыскания максимума;&lt;br /&gt;
* операция записи 1 в соответствующий столбец матрицы принадлежности кластерным центрам;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; вершина отмечена символом &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит итоговый расчёт объектной функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; вершина помечена &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит проверка условия достижения требуемой точности.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Четвертая&#039;&#039;&#039; соответствует операции пересчёта кластерных центров, она отмечена как &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmeans.png|thumb|800px|center|Рисунок 1. Информационный граф алгоритма. Здесь &#039;&#039;&#039;&#039;&#039;in&#039;&#039;&#039;&#039;&#039; — ввод входных данных, &#039;&#039;&#039;&#039;&#039;D&#039;&#039;&#039;&#039;&#039; — вычисление минимального расстояния до кластерных центров и проставление принадлежности соответствующему кластерному центру, &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039; — вычисление объектной функции по результатам полученных вычислений, &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039; — проверка условия достижения желаемой точности, &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039; — пересчёт кластерных центров и &#039;&#039;&#039;&#039;&#039;out&#039;&#039;&#039;&#039;&#039; — вывод полученных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;(n+m)C&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;
Проведём исследование масштабируемости параллельной реализации строгого алгоритма C средних согласно [[Scalability methodology|методике]]. &lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1 : 48] с шагом 1;&lt;br /&gt;
*	размерность пространства [3 : 50] c шагом 3;&lt;br /&gt;
*	число векторов 100 000 000;&lt;br /&gt;
*	число кластерных центров 30;&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон [[Глоссарий#Эффективность реализации|эффективности реализации]] алгоритма:&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации %;&lt;br /&gt;
*	максимальная эффективность реализации %.&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики [[Глоссарий#Производительность|производительности]] и эффективности выбранной реализации HCM в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=15633</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=15633"/>
		<updated>2016-11-01T19:13:36Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(n+m)C&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания: [[Участник:Каледа_Александр|Каледа Александр]] (разделы [[#Общее описание алгоритма|1.1]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Информационный граф|1.7]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Входные и выходные данные алгоритма|1.9]]), [[Участник:Шапулин_Андрей|Шапулин Андрей]] (разделы [[#Математическое описание алгоритма|1.2]], [[#Вычислительное ядро алгоритма|1.3]], [[#Макроструктура алгоритма|1.4]], [[#Информационный граф|1.7]], [[#Свойства алгоритма|1.10]], [[#Существующие реализации алгоритма|2.7]]).&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;[http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf Jantzen J. Neurofuzzy Modelling. 1998. Электронное издание. 28 Стр.]&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt;[http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf Нейский И.М. Классификация и сравнение методов кластеризации // Интеллектуальные технологии и системы. Сборник учебно-методических работ и статей аспирантов и студентов. – М.: НОК «CLAIM», 2006. – Выпуск 8. – С. 130-142.]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из 4 видов вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин отмечена символом &#039;&#039;&#039;&#039;&#039;M&#039;&#039;&#039;&#039;&#039;. Ей соответствует вычисление минимального расстояния до кластерных центров, а также запись единицы в соответствующий столбец матрицы, обозначающей принадлежность кластерному центру:&lt;br /&gt;
* независимое вычисление расстояний от заданного элемента &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; до каждого из кластерных центров;&lt;br /&gt;
* последовательное сравнение полученных значений с целью отыскания максимума;&lt;br /&gt;
* операция записи 1 в соответствующий столбец матрицы принадлежности кластерным центрам;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; вершина отмечена символом &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит итоговый расчёт объектной функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; вершина помечена &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит проверка условия достижения требуемой точности.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Четвертая&#039;&#039;&#039; соответствует операции пересчёта кластерных центров, она отмечена как &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmeans.png|thumb|800px|center|Рисунок 1. Информационный граф алгоритма. Здесь &#039;&#039;&#039;&#039;&#039;in&#039;&#039;&#039;&#039;&#039; — ввод входных данных, &#039;&#039;&#039;&#039;&#039;D&#039;&#039;&#039;&#039;&#039; — вычисление минимального расстояния до кластерных центров и проставление принадлежности соответствующему кластерному центру, &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039; — вычисление объектной функции по результатам полученных вычислений, &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039; — проверка условия достижения желаемой точности, &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039; — пересчёт кластерных центров и &#039;&#039;&#039;&#039;&#039;out&#039;&#039;&#039;&#039;&#039; — вывод полученных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;(n+m)C&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;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=15509</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=15509"/>
		<updated>2016-11-01T11:10:27Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(n+m)C&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания: [[Участник:Каледа_Александр|Каледа Александр]] (разделы [[#Общее описание алгоритма|1.1]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Информационный граф|1.7]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Входные и выходные данные алгоритма|1.9]]), [[Участник:Шапулин_Андрей|Шапулин Андрей]] (разделы [[#Математическое описание алгоритма|1.2]], [[#Вычислительное ядро алгоритма|1.3]], [[#Макроструктура алгоритма|1.4]], [[#Информационный граф|1.7]], [[#Свойства алгоритма|1.10]], [[#Существующие реализации алгоритма|2.7]]).&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;[http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf Jantzen J. Neurofuzzy Modelling. 1998. Электронное издание. 28 Стр.]&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt;[http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf Нейский И.М. Классификация и сравнение методов кластеризации // Интеллектуальные технологии и системы. Сборник учебно-методических работ и статей аспирантов и студентов. – М.: НОК «CLAIM», 2006. – Выпуск 8. – С. 130-142.]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из 4 видов вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин отмечена символом &#039;&#039;&#039;&#039;&#039;M&#039;&#039;&#039;&#039;&#039;. Ей соответствует вычисление минимального расстояния до кластерных центров, а также запись единицы в соответствующий столбец матрицы, обозначающей принадлежность кластерному центру:&lt;br /&gt;
* независимое вычисление расстояний от заданного элемента &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; до каждого из кластерных центров;&lt;br /&gt;
* последовательное сравнение полученных значений с целью отыскания максимума;&lt;br /&gt;
* операция записи 1 в соответствующий столбец матрицы принадлежности кластерным центрам;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; вершина отмечена символом &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит итоговый расчёт объектной функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; вершина помечена &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит проверка условия достижения требуемой точности.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Четвертая&#039;&#039;&#039; соответствует операции пересчёта кластерных центров, она отмечена как &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmeans.png|thumb|800px|center|Рисунок 1. Информационный граф алгоритма. Здесь &#039;&#039;&#039;&#039;&#039;in&#039;&#039;&#039;&#039;&#039; — ввод входных данных, &#039;&#039;&#039;&#039;&#039;D&#039;&#039;&#039;&#039;&#039; — вычисление минимального расстояния до кластерных центров и проставление принадлежности соответствующему кластерному центру, &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039; — вычисление объектной функции по результатам полученных вычислений, &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039; — проверка условия достижения желаемой точности, &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039; — пересчёт кластерных центров и &#039;&#039;&#039;&#039;&#039;out&#039;&#039;&#039;&#039;&#039; — вывод полученных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;(n+m)C&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;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=15504</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=15504"/>
		<updated>2016-11-01T11:01:30Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(n+m)C&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;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;[http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf Jantzen J. Neurofuzzy Modelling. 1998. Электронное издание. 28 Стр.]&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt;[http://it-claim.ru/Persons/Neyskiy/Article2_Neiskiy.pdf Нейский И.М. Классификация и сравнение методов кластеризации // Интеллектуальные технологии и системы. Сборник учебно-методических работ и статей аспирантов и студентов. – М.: НОК «CLAIM», 2006. – Выпуск 8. – С. 130-142.]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из 4 видов вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин отмечена символом &#039;&#039;&#039;&#039;&#039;M&#039;&#039;&#039;&#039;&#039;. Ей соответствует вычисление минимального расстояния до кластерных центров, а также запись единицы в соответствующий столбец матрицы, обозначающей принадлежность кластерному центру:&lt;br /&gt;
* независимое вычисление расстояний от заданного элемента &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; до каждого из кластерных центров;&lt;br /&gt;
* последовательное сравнение полученных значений с целью отыскания максимума;&lt;br /&gt;
* операция записи 1 в соответствующий столбец матрицы принадлежности кластерным центрам;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; вершина отмечена символом &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит итоговый расчёт объектной функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; вершина помечена &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит проверка условия достижения требуемой точности.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Четвертая&#039;&#039;&#039; соответствует операции пересчёта кластерных центров, она отмечена как &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmeans.png|thumb|800px|center|Рисунок 1. Информационный граф алгоритма. Здесь &#039;&#039;&#039;&#039;&#039;in&#039;&#039;&#039;&#039;&#039; — ввод входных данных, &#039;&#039;&#039;&#039;&#039;D&#039;&#039;&#039;&#039;&#039; — вычисление минимального расстояния до кластерных центров и проставление принадлежности соответствующему кластерному центру, &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039; — вычисление объектной функции по результатам полученных вычислений, &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039; — проверка условия достижения желаемой точности, &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039; — пересчёт кластерных центров и &#039;&#039;&#039;&#039;&#039;out&#039;&#039;&#039;&#039;&#039; — вывод полученных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;(n+m)C&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;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=15503</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=15503"/>
		<updated>2016-11-01T11:00:40Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: /* Общее описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(n+m)C&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;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;[http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf Jantzen J. Neurofuzzy Modelling. 1998. Электронное издание. 28 Стр.]&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt;Нейский И.М. Классификация и сравнение методов кластеризации // Интеллектуальные технологии и системы. Сборник учебно-методических работ и статей аспирантов и студентов. – М.: НОК «CLAIM», 2006. – Выпуск 8. – С. 130-142.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из 4 видов вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин отмечена символом &#039;&#039;&#039;&#039;&#039;M&#039;&#039;&#039;&#039;&#039;. Ей соответствует вычисление минимального расстояния до кластерных центров, а также запись единицы в соответствующий столбец матрицы, обозначающей принадлежность кластерному центру:&lt;br /&gt;
* независимое вычисление расстояний от заданного элемента &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; до каждого из кластерных центров;&lt;br /&gt;
* последовательное сравнение полученных значений с целью отыскания максимума;&lt;br /&gt;
* операция записи 1 в соответствующий столбец матрицы принадлежности кластерным центрам;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; вершина отмечена символом &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит итоговый расчёт объектной функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; вершина помечена &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит проверка условия достижения требуемой точности.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Четвертая&#039;&#039;&#039; соответствует операции пересчёта кластерных центров, она отмечена как &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmeans.png|thumb|800px|center|Рисунок 1. Информационный граф алгоритма. Здесь &#039;&#039;&#039;&#039;&#039;in&#039;&#039;&#039;&#039;&#039; — ввод входных данных, &#039;&#039;&#039;&#039;&#039;D&#039;&#039;&#039;&#039;&#039; — вычисление минимального расстояния до кластерных центров и проставление принадлежности соответствующему кластерному центру, &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039; — вычисление объектной функции по результатам полученных вычислений, &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039; — проверка условия достижения желаемой точности, &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039; — пересчёт кластерных центров и &#039;&#039;&#039;&#039;&#039;out&#039;&#039;&#039;&#039;&#039; — вывод полученных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;(n+m)C&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;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=15501</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=15501"/>
		<updated>2016-11-01T11:00:08Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: /* Общее описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(n+m)C&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;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf Jantzen J. Neurofuzzy Modelling. 1998. Электронное издание. 28 Стр.]&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt;Нейский И.М. Классификация и сравнение методов кластеризации // Интеллектуальные технологии и системы. Сборник учебно-методических работ и статей аспирантов и студентов. – М.: НОК «CLAIM», 2006. – Выпуск 8. – С. 130-142.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из 4 видов вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин отмечена символом &#039;&#039;&#039;&#039;&#039;M&#039;&#039;&#039;&#039;&#039;. Ей соответствует вычисление минимального расстояния до кластерных центров, а также запись единицы в соответствующий столбец матрицы, обозначающей принадлежность кластерному центру:&lt;br /&gt;
* независимое вычисление расстояний от заданного элемента &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; до каждого из кластерных центров;&lt;br /&gt;
* последовательное сравнение полученных значений с целью отыскания максимума;&lt;br /&gt;
* операция записи 1 в соответствующий столбец матрицы принадлежности кластерным центрам;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; вершина отмечена символом &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит итоговый расчёт объектной функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; вершина помечена &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит проверка условия достижения требуемой точности.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Четвертая&#039;&#039;&#039; соответствует операции пересчёта кластерных центров, она отмечена как &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmeans.png|thumb|800px|center|Рисунок 1. Информационный граф алгоритма. Здесь &#039;&#039;&#039;&#039;&#039;in&#039;&#039;&#039;&#039;&#039; — ввод входных данных, &#039;&#039;&#039;&#039;&#039;D&#039;&#039;&#039;&#039;&#039; — вычисление минимального расстояния до кластерных центров и проставление принадлежности соответствующему кластерному центру, &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039; — вычисление объектной функции по результатам полученных вычислений, &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039; — проверка условия достижения желаемой точности, &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039; — пересчёт кластерных центров и &#039;&#039;&#039;&#039;&#039;out&#039;&#039;&#039;&#039;&#039; — вывод полученных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;(n+m)C&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;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=15499</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=15499"/>
		<updated>2016-11-01T10:56:24Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: /* Общее описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(n+m)C&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;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;Jantzen J. Neurofuzzy Modelling. 1998. Электронное издание. 28 Стр.&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt;Нейский И.М. Классификация и сравнение методов кластеризации // Интеллектуальные технологии и системы. Сборник учебно-методических работ и статей аспирантов и студентов. – М.: НОК «CLAIM», 2006. – Выпуск 8. – С. 130-142.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из 4 видов вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин отмечена символом &#039;&#039;&#039;&#039;&#039;M&#039;&#039;&#039;&#039;&#039;. Ей соответствует вычисление минимального расстояния до кластерных центров, а также запись единицы в соответствующий столбец матрицы, обозначающей принадлежность кластерному центру:&lt;br /&gt;
* независимое вычисление расстояний от заданного элемента &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; до каждого из кластерных центров;&lt;br /&gt;
* последовательное сравнение полученных значений с целью отыскания максимума;&lt;br /&gt;
* операция записи 1 в соответствующий столбец матрицы принадлежности кластерным центрам;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; вершина отмечена символом &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит итоговый расчёт объектной функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; вершина помечена &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит проверка условия достижения требуемой точности.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Четвертая&#039;&#039;&#039; соответствует операции пересчёта кластерных центров, она отмечена как &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmeans.png|thumb|800px|center|Рисунок 1. Информационный граф алгоритма. Здесь &#039;&#039;&#039;&#039;&#039;in&#039;&#039;&#039;&#039;&#039; — ввод входных данных, &#039;&#039;&#039;&#039;&#039;D&#039;&#039;&#039;&#039;&#039; — вычисление минимального расстояния до кластерных центров и проставление принадлежности соответствующему кластерному центру, &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039; — вычисление объектной функции по результатам полученных вычислений, &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039; — проверка условия достижения желаемой точности, &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039; — пересчёт кластерных центров и &#039;&#039;&#039;&#039;&#039;out&#039;&#039;&#039;&#039;&#039; — вывод полученных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;(n+m)C&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;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=15497</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=15497"/>
		<updated>2016-11-01T10:56:03Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: /* Общее описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(n+m)C&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;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;\href{http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf}{Jantzen J. Neurofuzzy Modelling. 1998. Электронное издание. 28 Стр.}&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt;Нейский И.М. Классификация и сравнение методов кластеризации // Интеллектуальные технологии и системы. Сборник учебно-методических работ и статей аспирантов и студентов. – М.: НОК «CLAIM», 2006. – Выпуск 8. – С. 130-142.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из 4 видов вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин отмечена символом &#039;&#039;&#039;&#039;&#039;M&#039;&#039;&#039;&#039;&#039;. Ей соответствует вычисление минимального расстояния до кластерных центров, а также запись единицы в соответствующий столбец матрицы, обозначающей принадлежность кластерному центру:&lt;br /&gt;
* независимое вычисление расстояний от заданного элемента &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; до каждого из кластерных центров;&lt;br /&gt;
* последовательное сравнение полученных значений с целью отыскания максимума;&lt;br /&gt;
* операция записи 1 в соответствующий столбец матрицы принадлежности кластерным центрам;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; вершина отмечена символом &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит итоговый расчёт объектной функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; вершина помечена &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит проверка условия достижения требуемой точности.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Четвертая&#039;&#039;&#039; соответствует операции пересчёта кластерных центров, она отмечена как &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmeans.png|thumb|800px|center|Рисунок 1. Информационный граф алгоритма. Здесь &#039;&#039;&#039;&#039;&#039;in&#039;&#039;&#039;&#039;&#039; — ввод входных данных, &#039;&#039;&#039;&#039;&#039;D&#039;&#039;&#039;&#039;&#039; — вычисление минимального расстояния до кластерных центров и проставление принадлежности соответствующему кластерному центру, &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039; — вычисление объектной функции по результатам полученных вычислений, &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039; — проверка условия достижения желаемой точности, &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039; — пересчёт кластерных центров и &#039;&#039;&#039;&#039;&#039;out&#039;&#039;&#039;&#039;&#039; — вывод полученных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;(n+m)C&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;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=15495</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=15495"/>
		<updated>2016-11-01T10:55:37Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: /* Общее описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(n+m)C&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;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;\href{http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf}{Jantzen J. Neurofuzzy Modelling. 1998. Электронное издание. 28 Стр.}{}&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt;Нейский И.М. Классификация и сравнение методов кластеризации // Интеллектуальные технологии и системы. Сборник учебно-методических работ и статей аспирантов и студентов. – М.: НОК «CLAIM», 2006. – Выпуск 8. – С. 130-142.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из 4 видов вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин отмечена символом &#039;&#039;&#039;&#039;&#039;M&#039;&#039;&#039;&#039;&#039;. Ей соответствует вычисление минимального расстояния до кластерных центров, а также запись единицы в соответствующий столбец матрицы, обозначающей принадлежность кластерному центру:&lt;br /&gt;
* независимое вычисление расстояний от заданного элемента &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; до каждого из кластерных центров;&lt;br /&gt;
* последовательное сравнение полученных значений с целью отыскания максимума;&lt;br /&gt;
* операция записи 1 в соответствующий столбец матрицы принадлежности кластерным центрам;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; вершина отмечена символом &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит итоговый расчёт объектной функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; вершина помечена &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит проверка условия достижения требуемой точности.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Четвертая&#039;&#039;&#039; соответствует операции пересчёта кластерных центров, она отмечена как &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmeans.png|thumb|800px|center|Рисунок 1. Информационный граф алгоритма. Здесь &#039;&#039;&#039;&#039;&#039;in&#039;&#039;&#039;&#039;&#039; — ввод входных данных, &#039;&#039;&#039;&#039;&#039;D&#039;&#039;&#039;&#039;&#039; — вычисление минимального расстояния до кластерных центров и проставление принадлежности соответствующему кластерному центру, &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039; — вычисление объектной функции по результатам полученных вычислений, &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039; — проверка условия достижения желаемой точности, &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039; — пересчёт кластерных центров и &#039;&#039;&#039;&#039;&#039;out&#039;&#039;&#039;&#039;&#039; — вывод полученных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;(n+m)C&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;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=15491</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=15491"/>
		<updated>2016-11-01T10:51:10Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: /* Программная реализация алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(n+m)C&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;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;Jantzen J. Neurofuzzy Modelling. 1998. Электронное издание. 28 Стр.&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt;Нейский И.М. Классификация и сравнение методов кластеризации // Интеллектуальные технологии и системы. Сборник учебно-методических работ и статей аспирантов и студентов. – М.: НОК «CLAIM», 2006. – Выпуск 8. – С. 130-142.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из 4 видов вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин отмечена символом &#039;&#039;&#039;&#039;&#039;M&#039;&#039;&#039;&#039;&#039;. Ей соответствует вычисление минимального расстояния до кластерных центров, а также запись единицы в соответствующий столбец матрицы, обозначающей принадлежность кластерному центру:&lt;br /&gt;
* независимое вычисление расстояний от заданного элемента &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; до каждого из кластерных центров;&lt;br /&gt;
* последовательное сравнение полученных значений с целью отыскания максимума;&lt;br /&gt;
* операция записи 1 в соответствующий столбец матрицы принадлежности кластерным центрам;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; вершина отмечена символом &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит итоговый расчёт объектной функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; вершина помечена &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит проверка условия достижения требуемой точности.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Четвертая&#039;&#039;&#039; соответствует операции пересчёта кластерных центров, она отмечена как &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmeans.png|thumb|800px|center|Рисунок 1. Информационный граф алгоритма. Здесь &#039;&#039;&#039;&#039;&#039;in&#039;&#039;&#039;&#039;&#039; — ввод входных данных, &#039;&#039;&#039;&#039;&#039;D&#039;&#039;&#039;&#039;&#039; — вычисление минимального расстояния до кластерных центров и проставление принадлежности соответствующему кластерному центру, &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039; — вычисление объектной функции по результатам полученных вычислений, &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039; — проверка условия достижения желаемой точности, &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039; — пересчёт кластерных центров и &#039;&#039;&#039;&#039;&#039;out&#039;&#039;&#039;&#039;&#039; — вывод полученных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;(n+m)C&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;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=15484</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=15484"/>
		<updated>2016-11-01T10:39:22Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(n+m)C&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;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;Jantzen J. Neurofuzzy Modelling. 1998. Электронное издание. 28 Стр.&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt;Нейский И.М. Классификация и сравнение методов кластеризации // Интеллектуальные технологии и системы. Сборник учебно-методических работ и статей аспирантов и студентов. – М.: НОК «CLAIM», 2006. – Выпуск 8. – С. 130-142.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из 4 видов вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин отмечена символом &#039;&#039;&#039;&#039;&#039;M&#039;&#039;&#039;&#039;&#039;. Ей соответствует вычисление минимального расстояния до кластерных центров, а также запись единицы в соответствующий столбец матрицы, обозначающей принадлежность кластерному центру:&lt;br /&gt;
* независимое вычисление расстояний от заданного элемента &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; до каждого из кластерных центров;&lt;br /&gt;
* последовательное сравнение полученных значений с целью отыскания максимума;&lt;br /&gt;
* операция записи 1 в соответствующий столбец матрицы принадлежности кластерным центрам;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; вершина отмечена символом &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит итоговый расчёт объектной функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; вершина помечена &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит проверка условия достижения требуемой точности.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Четвертая&#039;&#039;&#039; соответствует операции пересчёта кластерных центров, она отмечена как &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmeans.png|thumb|800px|center|Рисунок 1. Информационный граф алгоритма. Здесь &#039;&#039;&#039;&#039;&#039;in&#039;&#039;&#039;&#039;&#039; — ввод входных данных, &#039;&#039;&#039;&#039;&#039;D&#039;&#039;&#039;&#039;&#039; — вычисление минимального расстояния до кластерных центров и проставление принадлежности соответствующему кластерному центру, &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039; — вычисление объектной функции по результатам полученных вычислений, &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039; — проверка условия достижения желаемой точности, &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039; — пересчёт кластерных центров и &#039;&#039;&#039;&#039;&#039;out&#039;&#039;&#039;&#039;&#039; — вывод полученных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;(n+m)C&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;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=11451</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=11451"/>
		<updated>2016-10-15T19:31:37Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(n+m)C&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;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;Jan Jantzen «Neurofuzzy Modelling». Электронное издание.&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt; Нейский И.М. Классификация и сравнение методов кластеризации.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из 4 видов вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин отмечена символом &#039;&#039;&#039;&#039;&#039;M&#039;&#039;&#039;&#039;&#039;. Ей соответствует вычисление минимального расстояния до кластерных центров, а также запись единицы в соответствующий столбец матрицы, обозначающей принадлежность кластерному центру:&lt;br /&gt;
* независимое вычисление расстояний от заданного элемента &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; до каждого из кластерных центров;&lt;br /&gt;
* последовательное сравнение полученных значений с целью отыскания максимума;&lt;br /&gt;
* операция записи 1 в соответствующий столбец матрицы принадлежности кластерным центрам;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; вершина отмечена символом &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит итоговый расчёт объектной функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; вершина помечена &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит проверка условия достижения требуемой точности.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Четвертая&#039;&#039;&#039; соответствует операции пересчёта кластерных центров, она отмечена как &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmeans.png|thumb|800px|center|Рисунок 1. Информационный граф алгоритма. Здесь &#039;&#039;&#039;&#039;&#039;in&#039;&#039;&#039;&#039;&#039; — ввод входных данных, &#039;&#039;&#039;&#039;&#039;D&#039;&#039;&#039;&#039;&#039; — вычисление минимального расстояния до кластерных центров и проставление принадлежности соответствующему кластерному центру, &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039; — вычисление объектной функции по результатам полученных вычислений, &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039; — проверка условия достижения желаемой точности, &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039; — пересчёт кластерных центров и &#039;&#039;&#039;&#039;&#039;out&#039;&#039;&#039;&#039;&#039; — вывод полученных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;(n+m)C&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;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=11441</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=11441"/>
		<updated>2016-10-15T19:31:03Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: /* Свойства алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(n+m)C&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;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;Jan Jantzen «Neurofuzzy Modelling». Электронное издание.&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt; Нейский И.М. Классификация и сравнение методов кластеризации.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из 4 видов вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин отмечена символом &#039;&#039;&#039;&#039;&#039;M&#039;&#039;&#039;&#039;&#039;. Ей соответствует вычисление минимального расстояния до кластерных центров, а также запись единицы в соответствующий столбец матрицы, обозначающей принадлежность кластерному центру:&lt;br /&gt;
* независимое вычисление расстояний от заданного элемента &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; до каждого из кластерных центров;&lt;br /&gt;
* последовательное сравнение полученных значений с целью отыскания максимума;&lt;br /&gt;
* операция записи 1 в соответствующий столбец матрицы принадлежности кластерным центрам;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; вершина отмечена символом &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит итоговый расчёт объектной функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; вершина помечена &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит проверка условия достижения требуемой точности.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Четвертая&#039;&#039;&#039; соответствует операции пересчёта кластерных центров, она отмечена как &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmeans.png|thumb|800px|center|Рисунок 1. Информационный граф алгоритма. Здесь &#039;&#039;&#039;&#039;&#039;in&#039;&#039;&#039;&#039;&#039; — ввод входных данных, &#039;&#039;&#039;&#039;&#039;D&#039;&#039;&#039;&#039;&#039; — вычисление минимального расстояния до кластерных центров и проставление принадлежности соответствующему кластерному центру, &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039; — вычисление объектной функции по результатам полученных вычислений, &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039; — проверка условия достижения желаемой точности, &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039; — пересчёт кластерных центров и &#039;&#039;&#039;&#039;&#039;out&#039;&#039;&#039;&#039;&#039; — вывод полученных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;(n+m)C&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;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=11147</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=11147"/>
		<updated>2016-10-15T18:37:19Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: /* Входные и выходные данные алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(n+m)C&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;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;Jan Jantzen «Neurofuzzy Modelling». Электронное издание.&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt; Нейский И.М. Классификация и сравнение методов кластеризации.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из 4 видов вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин отмечена символом &#039;&#039;&#039;&#039;&#039;M&#039;&#039;&#039;&#039;&#039;. Ей соответствует вычисление минимального расстояния до кластерных центров, а также запись единицы в соответствующий столбец матрицы, обозначающей принадлежность кластерному центру:&lt;br /&gt;
* независимое вычисление расстояний от заданного элемента &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; до каждого из кластерных центров;&lt;br /&gt;
* последовательное сравнение полученных значений с целью отыскания максимума;&lt;br /&gt;
* операция записи 1 в соответствующий столбец матрицы принадлежности кластерным центрам;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; вершина отмечена символом &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит итоговый расчёт объектной функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; вершина помечена &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит проверка условия достижения требуемой точности.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Четвертая&#039;&#039;&#039; соответствует операции пересчёта кластерных центров, она отмечена как &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmeans.png|thumb|800px|center|Рисунок 1. Информационный граф алгоритма. Здесь &#039;&#039;&#039;&#039;&#039;in&#039;&#039;&#039;&#039;&#039; — ввод входных данных, &#039;&#039;&#039;&#039;&#039;D&#039;&#039;&#039;&#039;&#039; — вычисление минимального расстояния до кластерных центров и проставление принадлежности соответствующему кластерному центру, &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039; — вычисление объектной функции по результатам полученных вычислений, &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039; — проверка условия достижения желаемой точности, &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039; — пересчёт кластерных центров и &#039;&#039;&#039;&#039;&#039;out&#039;&#039;&#039;&#039;&#039; — вывод полученных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;(n+m)C&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;
&amp;quot;Длинные&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;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=11143</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=11143"/>
		<updated>2016-10-15T18:36:10Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: /* Входные и выходные данные алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(n+m)C&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;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;Jan Jantzen «Neurofuzzy Modelling». Электронное издание.&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt; Нейский И.М. Классификация и сравнение методов кластеризации.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из 4 видов вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин отмечена символом &#039;&#039;&#039;&#039;&#039;M&#039;&#039;&#039;&#039;&#039;. Ей соответствует вычисление минимального расстояния до кластерных центров, а также запись единицы в соответствующий столбец матрицы, обозначающей принадлежность кластерному центру:&lt;br /&gt;
* независимое вычисление расстояний от заданного элемента &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; до каждого из кластерных центров;&lt;br /&gt;
* последовательное сравнение полученных значений с целью отыскания максимума;&lt;br /&gt;
* операция записи 1 в соответствующий столбец матрицы принадлежности кластерным центрам;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; вершина отмечена символом &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит итоговый расчёт объектной функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; вершина помечена &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит проверка условия достижения требуемой точности.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Четвертая&#039;&#039;&#039; соответствует операции пересчёта кластерных центров, она отмечена как &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmeans.png|thumb|800px|center|Рисунок 1. Информационный граф алгоритма. Здесь &#039;&#039;&#039;&#039;&#039;in&#039;&#039;&#039;&#039;&#039; — ввод входных данных, &#039;&#039;&#039;&#039;&#039;D&#039;&#039;&#039;&#039;&#039; — вычисление минимального расстояния до кластерных центров и проставление принадлежности соответствующему кластерному центру, &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039; — вычисление объектной функции по результатам полученных вычислений, &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039; — проверка условия достижения желаемой точности, &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039; — пересчёт кластерных центров и &#039;&#039;&#039;&#039;&#039;out&#039;&#039;&#039;&#039;&#039; — вывод полученных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;С(n+m)&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;
&amp;quot;Длинные&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;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=11140</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=11140"/>
		<updated>2016-10-15T18:35:40Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: /* Входные и выходные данные алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(n+m)C&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;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;Jan Jantzen «Neurofuzzy Modelling». Электронное издание.&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt; Нейский И.М. Классификация и сравнение методов кластеризации.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из 4 видов вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин отмечена символом &#039;&#039;&#039;&#039;&#039;M&#039;&#039;&#039;&#039;&#039;. Ей соответствует вычисление минимального расстояния до кластерных центров, а также запись единицы в соответствующий столбец матрицы, обозначающей принадлежность кластерному центру:&lt;br /&gt;
* независимое вычисление расстояний от заданного элемента &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; до каждого из кластерных центров;&lt;br /&gt;
* последовательное сравнение полученных значений с целью отыскания максимума;&lt;br /&gt;
* операция записи 1 в соответствующий столбец матрицы принадлежности кластерным центрам;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; вершина отмечена символом &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит итоговый расчёт объектной функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; вершина помечена &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит проверка условия достижения требуемой точности.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Четвертая&#039;&#039;&#039; соответствует операции пересчёта кластерных центров, она отмечена как &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmeans.png|thumb|800px|center|Рисунок 1. Информационный граф алгоритма. Здесь &#039;&#039;&#039;&#039;&#039;in&#039;&#039;&#039;&#039;&#039; — ввод входных данных, &#039;&#039;&#039;&#039;&#039;D&#039;&#039;&#039;&#039;&#039; — вычисление минимального расстояния до кластерных центров и проставление принадлежности соответствующему кластерному центру, &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039; — вычисление объектной функции по результатам полученных вычислений, &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039; — проверка условия достижения желаемой точности, &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039; — пересчёт кластерных центров и &#039;&#039;&#039;&#039;&#039;out&#039;&#039;&#039;&#039;&#039; — вывод полученных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;С(n+m)&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;
&amp;quot;Длинные&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;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=11126</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=11126"/>
		<updated>2016-10-15T18:33:27Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: /* Входные и выходные данные алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(n+m)C&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;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;Jan Jantzen «Neurofuzzy Modelling». Электронное издание.&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt; Нейский И.М. Классификация и сравнение методов кластеризации.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из 4 видов вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин отмечена символом &#039;&#039;&#039;&#039;&#039;M&#039;&#039;&#039;&#039;&#039;. Ей соответствует вычисление минимального расстояния до кластерных центров, а также запись единицы в соответствующий столбец матрицы, обозначающей принадлежность кластерному центру:&lt;br /&gt;
* независимое вычисление расстояний от заданного элемента &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; до каждого из кластерных центров;&lt;br /&gt;
* последовательное сравнение полученных значений с целью отыскания максимума;&lt;br /&gt;
* операция записи 1 в соответствующий столбец матрицы принадлежности кластерным центрам;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; вершина отмечена символом &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит итоговый расчёт объектной функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; вершина помечена &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит проверка условия достижения требуемой точности.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Четвертая&#039;&#039;&#039; соответствует операции пересчёта кластерных центров, она отмечена как &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmeans.png|thumb|800px|center|Рисунок 1. Информационный граф алгоритма. Здесь &#039;&#039;&#039;&#039;&#039;in&#039;&#039;&#039;&#039;&#039; — ввод входных данных, &#039;&#039;&#039;&#039;&#039;D&#039;&#039;&#039;&#039;&#039; — вычисление минимального расстояния до кластерных центров и проставление принадлежности соответствующему кластерному центру, &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039; — вычисление объектной функции по результатам полученных вычислений, &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039; — проверка условия достижения желаемой точности, &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039; — пересчёт кластерных центров и &#039;&#039;&#039;&#039;&#039;out&#039;&#039;&#039;&#039;&#039; — вывод полученных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;C(n+m)&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;
&amp;quot;Длинные&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;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=11104</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=11104"/>
		<updated>2016-10-15T18:27:12Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(n+m)C&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;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;Jan Jantzen «Neurofuzzy Modelling». Электронное издание.&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt; Нейский И.М. Классификация и сравнение методов кластеризации.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из 4 видов вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин отмечена символом &#039;&#039;&#039;&#039;&#039;M&#039;&#039;&#039;&#039;&#039;. Ей соответствует вычисление минимального расстояния до кластерных центров, а также запись единицы в соответствующий столбец матрицы, обозначающей принадлежность кластерному центру:&lt;br /&gt;
* независимое вычисление расстояний от заданного элемента &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; до каждого из кластерных центров;&lt;br /&gt;
* последовательное сравнение полученных значений с целью отыскания максимума;&lt;br /&gt;
* операция записи 1 в соответствующий столбец матрицы принадлежности кластерным центрам;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; вершина отмечена символом &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит итоговый расчёт объектной функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; вершина помечена &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит проверка условия достижения требуемой точности.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Четвертая&#039;&#039;&#039; соответствует операции пересчёта кластерных центров, она отмечена как &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmeans.png|thumb|800px|center|Рисунок 1. Информационный граф алгоритма. Здесь &#039;&#039;&#039;&#039;&#039;in&#039;&#039;&#039;&#039;&#039; — ввод входных данных, &#039;&#039;&#039;&#039;&#039;D&#039;&#039;&#039;&#039;&#039; — вычисление минимального расстояния до кластерных центров и проставление принадлежности соответствующему кластерному центру, &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039; — вычисление объектной функции по результатам полученных вычислений, &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039; — проверка условия достижения желаемой точности, &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039; — пересчёт кластерных центров и &#039;&#039;&#039;&#039;&#039;out&#039;&#039;&#039;&#039;&#039; — вывод полученных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; вектор &amp;lt;math&amp;gt;y \in \mathbb{N}^m&amp;lt;/math&amp;gt;, содержащий номер найденного кластера для каждого объекта &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;mC + 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;
&amp;quot;Длинные&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;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=11099</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=11099"/>
		<updated>2016-10-15T18:26:02Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(n+m)C&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;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;Jan Jantzen «Neurofuzzy Modelling». Электронное издание.&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; матрица &amp;lt;math&amp;gt;M\in \mathbb{N}^{n\times C}&amp;lt;/math&amp;gt; c информацией о разбиении объектов на кластера. Элемент &amp;lt;math&amp;gt;m_{ij}=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;u_j \in C_i&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math. Остальные элементы &amp;lt;math&amp;gt;m_{ij}=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt; Нейский И.М. Классификация и сравнение методов кластеризации.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из 4 видов вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин отмечена символом &#039;&#039;&#039;&#039;&#039;M&#039;&#039;&#039;&#039;&#039;. Ей соответствует вычисление минимального расстояния до кластерных центров, а также запись единицы в соответствующий столбец матрицы, обозначающей принадлежность кластерному центру:&lt;br /&gt;
* независимое вычисление расстояний от заданного элемента &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; до каждого из кластерных центров;&lt;br /&gt;
* последовательное сравнение полученных значений с целью отыскания максимума;&lt;br /&gt;
* операция записи 1 в соответствующий столбец матрицы принадлежности кластерным центрам;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; вершина отмечена символом &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит итоговый расчёт объектной функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; вершина помечена &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит проверка условия достижения требуемой точности.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Четвертая&#039;&#039;&#039; соответствует операции пересчёта кластерных центров, она отмечена как &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmeans.png|thumb|800px|center|Рисунок 1. Информационный граф алгоритма. Здесь &#039;&#039;&#039;&#039;&#039;in&#039;&#039;&#039;&#039;&#039; — ввод входных данных, &#039;&#039;&#039;&#039;&#039;D&#039;&#039;&#039;&#039;&#039; — вычисление минимального расстояния до кластерных центров и проставление принадлежности соответствующему кластерному центру, &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039; — вычисление объектной функции по результатам полученных вычислений, &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039; — проверка условия достижения желаемой точности, &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039; — пересчёт кластерных центров и &#039;&#039;&#039;&#039;&#039;out&#039;&#039;&#039;&#039;&#039; — вывод полученных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; вектор &amp;lt;math&amp;gt;y \in \mathbb{N}^m&amp;lt;/math&amp;gt;, содержащий номер найденного кластера для каждого объекта &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;mC + 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;
&amp;quot;Длинные&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;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Cmeans.png&amp;diff=10932</id>
		<title>Файл:Cmeans.png</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Cmeans.png&amp;diff=10932"/>
		<updated>2016-10-15T17:49:57Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: Каледа Александр загрузил новую версию Файл:Cmeans.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Cmeans.png&amp;diff=10908</id>
		<title>Файл:Cmeans.png</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Cmeans.png&amp;diff=10908"/>
		<updated>2016-10-15T17:46:34Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=9746</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=9746"/>
		<updated>2016-10-15T13:41:11Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(n+m)C&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;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;Jan Jantzen «Neurofuzzy Modelling». Электронное издание.&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; вектор &amp;lt;math&amp;gt;y \in \mathbb{N}^m&amp;lt;/math&amp;gt;, содержащий номер найденного кластера для каждого объекта &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i = \{u_k\}, m_{ik} = 1&amp;lt;/math&amp;gt;. То есть &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt; Нейский И.М. Классификация и сравнение методов кластеризации.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
Граф алгоритма состоит из 4 видов вершин:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин отмечена символом &#039;&#039;&#039;&#039;&#039;M&#039;&#039;&#039;&#039;&#039;. Ей соответствует вычисление минимального расстояния до кластерных центров, а также запись единицы в соответствующий столбец матрицы, обозначающей принадлежность кластерному центру:&lt;br /&gt;
* независимое вычисление расстояний от заданного элемента &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; до каждого из кластерных центров;&lt;br /&gt;
* последовательное сравнение полученных значений с целью отыскания максимума;&lt;br /&gt;
* операция записи 1 в соответствующий столбец матрицы принадлежности кластерным центрам;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; вершина отмечена символом &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит итоговый расчёт объектной функции.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; вершина помечена &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039;, на этом этапе происходит проверка условия достижения требуемой точности.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Четвертая&#039;&#039;&#039; соответствует операции пересчёта кластерных центров, она отмечена как &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmeans.png|thumb|800px|center|Рисунок 1. Информационный граф алгоритма. Здесь &#039;&#039;&#039;&#039;&#039;in&#039;&#039;&#039;&#039;&#039; — ввод входных данных, &#039;&#039;&#039;&#039;&#039;D&#039;&#039;&#039;&#039;&#039; — вычисление минимального расстояния до кластерных центров и проставление принадлежности соответствующему кластерному центру, &#039;&#039;&#039;&#039;&#039;J&#039;&#039;&#039;&#039;&#039; — вычисление объектной функции по результатам полученных вычислений, &#039;&#039;&#039;&#039;&#039;if&#039;&#039;&#039;&#039;&#039; — проверка условия достижения желаемой точности, &#039;&#039;&#039;&#039;&#039;C&#039;&#039;&#039;&#039;&#039; — пересчёт кластерных центров и &#039;&#039;&#039;&#039;&#039;out&#039;&#039;&#039;&#039;&#039; — вывод полученных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; вектор &amp;lt;math&amp;gt;y \in \mathbb{N}^m&amp;lt;/math&amp;gt;, содержащий номер найденного кластера для каждого объекта &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;mC + 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;
&amp;quot;Длинные&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;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%A8%D0%B0%D0%BF%D1%83%D0%BB%D0%B8%D0%BD_%D0%90%D0%BD%D0%B4%D1%80%D0%B5%D0%B9&amp;diff=9505</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%A8%D0%B0%D0%BF%D1%83%D0%BB%D0%B8%D0%BD_%D0%90%D0%BD%D0%B4%D1%80%D0%B5%D0%B9&amp;diff=9505"/>
		<updated>2016-10-15T12:38:04Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: Новая страница: «Шапулин Андрей Валентинович — студент 617 группы (2016/2017) факультета ВМК МГУ им. М.В.Ломонос…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Шапулин Андрей Валентинович — студент 617 группы (2016/2017) факультета ВМК МГУ им. М.В.Ломоносова.&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80&amp;diff=9496</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80&amp;diff=9496"/>
		<updated>2016-10-15T12:36:27Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: Новая страница: «Каледа Александр Васильевич — студент 619 группы (2016/2017) факультета ВМК МГУ им. М.В.Ломонос…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Каледа Александр Васильевич — студент 619 группы (2016/2017) факультета ВМК МГУ им. М.В.Ломоносова.&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=9487</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=9487"/>
		<updated>2016-10-15T12:35:01Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;(n+m)C&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;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;Jan Jantzen «Neurofuzzy Modelling». Электронное издание.&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; вектор &amp;lt;math&amp;gt;y \in \mathbb{N}^m&amp;lt;/math&amp;gt;, содержащий номер найденного кластера для каждого объекта &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i = \{u_k\}, m_{ik} = 1&amp;lt;/math&amp;gt;. То есть &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt; Нейский И.М. Классификация и сравнение методов кластеризации.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; вектор &amp;lt;math&amp;gt;y \in \mathbb{N}^m&amp;lt;/math&amp;gt;, содержащий номер найденного кластера для каждого объекта &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;mC + 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;
&amp;quot;Длинные&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;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=9309</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=9309"/>
		<updated>2016-10-15T11:39:42Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: /* Свойства алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n+mC&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;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;Jan Jantzen «Neurofuzzy Modelling». Электронное издание.&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; вектор &amp;lt;math&amp;gt;y \in \mathbb{N}^m&amp;lt;/math&amp;gt;, содержащий номер найденного кластера для каждого объекта &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i = \{u_k\}, m_{ik} = 1&amp;lt;/math&amp;gt;. То есть &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt; Нейский И.М. Классификация и сравнение методов кластеризации.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; вектор &amp;lt;math&amp;gt;y \in \mathbb{N}^m&amp;lt;/math&amp;gt;, содержащий номер найденного кластера для каждого объекта &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;mC + 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;
&amp;quot;Длинные&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;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=9304</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=9304"/>
		<updated>2016-10-15T11:39:05Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n+mC&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;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;Jan Jantzen «Neurofuzzy Modelling». Электронное издание.&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; вектор &amp;lt;math&amp;gt;y \in \mathbb{N}^m&amp;lt;/math&amp;gt;, содержащий номер найденного кластера для каждого объекта &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i = \{u_k\}, m_{ik} = 1&amp;lt;/math&amp;gt;. То есть &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt; Нейский И.М. Классификация и сравнение методов кластеризации.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; вектор &amp;lt;math&amp;gt;y \in \mathbb{N}^m&amp;lt;/math&amp;gt;, содержащий номер найденного кластера для каждого объекта &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;mC + 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;
&amp;quot;Длинные&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;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=9297</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=9297"/>
		<updated>2016-10-15T11:37:43Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: /* Программная реализация алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n+Cm&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;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;Jan Jantzen «Neurofuzzy Modelling». Электронное издание.&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; вектор &amp;lt;math&amp;gt;y \in \mathbb{N}^m&amp;lt;/math&amp;gt;, содержащий номер найденного кластера для каждого объекта &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i = \{u_k\}, m_{ik} = 1&amp;lt;/math&amp;gt;. То есть &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt; Нейский И.М. Классификация и сравнение методов кластеризации.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; вектор &amp;lt;math&amp;gt;y \in \mathbb{N}^m&amp;lt;/math&amp;gt;, содержащий номер найденного кластера для каждого объекта &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;mC + 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;
&amp;quot;Длинные&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;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=9292</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=9292"/>
		<updated>2016-10-15T11:36:40Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: /* Свойства алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n+Cm&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;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;Jan Jantzen «Neurofuzzy Modelling». Электронное издание.&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; вектор &amp;lt;math&amp;gt;y \in \mathbb{N}^m&amp;lt;/math&amp;gt;, содержащий номер найденного кластера для каждого объекта &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i = \{u_k\}, m_{ik} = 1&amp;lt;/math&amp;gt;. То есть &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt; Нейский И.М. Классификация и сравнение методов кластеризации.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; вектор &amp;lt;math&amp;gt;y \in \mathbb{N}^m&amp;lt;/math&amp;gt;, содержащий номер найденного кластера для каждого объекта &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;mC + 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;
&amp;quot;Длинные&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;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=9289</id>
		<title>Участник:Каледа Александр/Строгий алгоритм С средних (Hard C-Means)</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%9A%D0%B0%D0%BB%D0%B5%D0%B4%D0%B0_%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80/%D0%A1%D1%82%D1%80%D0%BE%D0%B3%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A1_%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85_(Hard_C-Means)&amp;diff=9289"/>
		<updated>2016-10-15T11:35:32Z</updated>

		<summary type="html">&lt;p&gt;Каледа Александр: /* Входные и выходные данные алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Строгий алгоритм С средних (Hard C-Means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n)&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)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n+Cm&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;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;&#039;&#039;Hard C-Means, HCM&#039;&#039;&#039;&#039;&#039;; &#039;&#039;Jang, Sun and Mizutani, 1997&#039;&#039;) один из наиболее широко используемых алгоритмов кластеризации данных&amp;lt;ref&amp;gt;Jan Jantzen «Neurofuzzy Modelling». Электронное издание.&amp;lt;/ref&amp;gt;. Алгоритм разбивает большие наборы векторов в многомерном пространстве по заранее заданному количеству кластеров (т.е. является управляемым).&lt;br /&gt;
&lt;br /&gt;
На вход алгоритму подается набор векторов и количество кластеров. Дополнительно может задаваться пороговая величина объектной функции, при достижении которой алгоритм останавливается. После окончания работы алгоритма каждый вектор будет отнесет к определенному кластерному центру. Алгоритм, являясь итерационным, зависит от начальных значений кластерных центров, а следовательно может не сходиться к локальному минимуму.&lt;br /&gt;
&lt;br /&gt;
На первом шаге алгоритма происходит инициализация кластерным центров, это можно сделать выбрав случайным образом вектора из входного набора. На следующем шаге начинается итерационный процесс, завершающийся при достижении порогового значения объектной функцией или при минимальном отличии, от значения на предыдущей итерации.&lt;br /&gt;
&lt;br /&gt;
Вычисления, выполняющиеся на очередной итерации алгоритма:&lt;br /&gt;
&lt;br /&gt;
# Расчёт рядовой матрицы (сопоставление вектора соответствующему кластерному центру).&lt;br /&gt;
# Расчёт объектной функции.&lt;br /&gt;
# Пересчёт кластерных центров.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Исходные данные: матрица &amp;lt;math&amp;gt;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; вектор &amp;lt;math&amp;gt;y \in \mathbb{N}^m&amp;lt;/math&amp;gt;, содержащий номер найденного кластера для каждого объекта &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
&lt;br /&gt;
Шаг 1. Инициализация кластерных центров &amp;lt;math&amp;gt;c_i, i = 1, 2, \dots, C.&amp;lt;/math&amp;gt; Это можно сделать выбрав случайным образом C векторов из входного набора &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 2. Вычисление рядовой матрицы M. &lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; состоит из элементов &amp;lt;math&amp;gt;M = \|m_{ik}\|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \;\; \text{for all } i \neq j; \;\; (i,j=1,2,\ldots,C; \; k = 1,2,\ldots,n)\\&lt;br /&gt;
0, &amp;amp; \text{otherwise}.&lt;br /&gt;
\end{cases}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шаг 3. Расчет объектной функции: &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;C_i = \{u_k\}, m_{ik} = 1&amp;lt;/math&amp;gt;. То есть &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; содержит все объекты, принадлежащие кластеру &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На этом шаге происходит остановка и выход из цикла, если полученное значение ниже пороговой величины или полученное значение не сильно отличается от значений, полученных на предыдущих циклах.&lt;br /&gt;
&lt;br /&gt;
Шаг 4. Пересчет кластерных центров. &lt;br /&gt;
&lt;br /&gt;
Пересчет кластерных центров выполняется в соответствии со следующим уравнением: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;|C_i|&amp;lt;/math&amp;gt; -- количество элементов в &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом кластере.&lt;br /&gt;
&lt;br /&gt;
Шаг 5. Переход на шаг 2.&lt;br /&gt;
&lt;br /&gt;
Описание взято из &amp;lt;ref&amp;gt; Нейский И.М. Классификация и сравнение методов кластеризации.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Вычислительное ядро алгоритма Hard C-Means можно составить из множественных (всего их &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt;) вычислений квадратов нормы разности векторов &amp;lt;math&amp;gt;u_k&amp;lt;/math&amp;gt; и кластерных центров &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;\|u_k-c_i\|^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как записано и в описании ядра алгоритма, основную часть метода составляют множественные (&amp;lt;math&amp;gt;Cn&amp;lt;/math&amp;gt;) вычисления квадратов норм:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\|u_k-c_i\|^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;&lt;br /&gt;
J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} \|u_k -c_i \|^2 \right)&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;&lt;br /&gt;
c_i = \frac{1}{|C_i|} \sum\limits_{k:\, u_k \in C_i} u_k&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Итерационный блок алгоритма можно описать на языке Python следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python3&amp;quot;&amp;gt;&lt;br /&gt;
for i in range(n):&lt;br /&gt;
    idx_min = 0&lt;br /&gt;
    dist_min  = ((u[i] - c[0]) ** 2).sum()&lt;br /&gt;
&lt;br /&gt;
    for j in range(1, C):&lt;br /&gt;
        dist  = ((u[i] - c[j]) ** 2).sum()&lt;br /&gt;
        if dist &amp;lt; dist_min:&lt;br /&gt;
            idx_min = j&lt;br /&gt;
            dist_min = dist&lt;br /&gt;
&lt;br /&gt;
    M[i, idx_min] = 1&lt;br /&gt;
    c_next[idx_min] += u[i]&lt;br /&gt;
    c_next_cnt[idx_min] += 1&lt;br /&gt;
    J += dist_min&lt;br /&gt;
&amp;lt;/source&amp;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;m&amp;lt;/math&amp;gt; и количество кластерных центров &amp;lt;math&amp;gt;C&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;m-1&amp;lt;/math&amp;gt; арифметических операций сложения, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций вычитания и &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Каждая итерация алгоритма требует выполнения:&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций вычисления квадрата нормы разности векторов;&lt;br /&gt;
* &amp;lt;math&amp;gt;nC&amp;lt;/math&amp;gt; операций сравнения квадрата нормы;&lt;br /&gt;
* &amp;lt;math&amp;gt;3n&amp;lt;/math&amp;gt; операций сложения;&lt;br /&gt;
&lt;br /&gt;
Таким образом, на каждой итерации имеем:&lt;br /&gt;
* &amp;lt;math&amp;gt;mnC&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;(2mC + 3)n&amp;lt;/math&amp;gt; арифметических операций сложения и вычитания;&lt;br /&gt;
&lt;br /&gt;
В итоге имеем сложность последовательной реализации алгоритма &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Основной ресурс параллелизма алгоритма составляет итерационный блок. Эта последовательность итераций может быть выполнена для каждого входного вектора &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt; независимо. Однако, в конце выполнения каждого итерационного блока имеют место последовательные вычисления - сложение значений объектной функции, полученных независимо на каждом процессоре, а также перерасчет кластерных центров.&lt;br /&gt;
&lt;br /&gt;
Высота [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] оценивается как &amp;lt;math&amp;gt;O(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;.&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;U\in \mathbb{R}^{n\times m}&amp;lt;/math&amp;gt;, представляющая собой набор векторов &amp;lt;math&amp;gt;\{u_i\}_{i=1}^{n}, u_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; количество кластеров &amp;lt;math&amp;gt;C \in \mathbb{N}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;nm+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; набор векторов - кластерных центров &amp;lt;math&amp;gt;\{c_i\}_{i=1}^{C}, c_i \in \mathbb{R}^m&amp;lt;/math&amp;gt;; вектор &amp;lt;math&amp;gt;y \in \mathbb{N}^m&amp;lt;/math&amp;gt;, содержащий номер найденного кластера для каждого объекта &amp;lt;math&amp;gt;u_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;mC + 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;
* [http://projects.jasmeet.me/2013/03/HardCMeans.html Последовательная реализация алгоритма на MatLab]&lt;br /&gt;
* [https://github.com/artpar/Hard-Clustering-implementation Последовательная реализация алгоритма на С++]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Каледа Александр</name></author>
	</entry>
</feed>