<?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=Urandon</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=Urandon"/>
	<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/Urandon"/>
	<updated>2026-10-22T17:18:00Z</updated>
	<subtitle>Вклад</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Urandon/%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,_HCM)&amp;diff=22487</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=22487"/>
		<updated>2017-02-08T20:20:01Z</updated>

		<summary type="html">&lt;p&gt;Urandon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&lt;br /&gt;
&lt;br /&gt;
Автор описания [[Участник:Urandon|Хомутов Никита]]&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;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
Целевая функция алгоритма полностью аналогична целевой функции K-Means[https://ru.wikipedia.org/wiki/K-means].&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \qquad \forall j \neq i \\&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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt; арифметичеких операций.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой итерационный процесс, в котором поочерёдно происходит покоординатная оптимизация функционала &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
J(M, C) \to \max_{M}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
J(M, C) \to \max_{C}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оптимизация функционала по &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; приводит к вычислению расстояний между объектами и центроидами, поиском ближайших.&lt;br /&gt;
&lt;br /&gt;
Оптимизация по &amp;lt;math&amp;gt;C&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;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
Данная операция сводится к использованию ассоциативной &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt; и паттерна Reduse&amp;lt;ref&amp;gt;Reduce paralle pattern [http://www.drdobbs.com/architecture-and-design/parallel-pattern-7-reduce/222000718]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
Последовательная схема реализована в виде python-подобного псевдокода. Для оптимизации вычислений хранится структура, хранящая номер кластера для каждой точки. Это оптимизация с учётом разреженности матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# Инициализация&lt;br /&gt;
J_history = []&lt;br /&gt;
# центроиды выбираются случайно среди объектов&lt;br /&gt;
c = u[random.choice(N, C), :] &lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
# хранилище индексов кластеров для каждого объекта&lt;br /&gt;
# используется для обновления ранговой матрицы M&lt;br /&gt;
clusterization = zeros(N) &lt;br /&gt;
&lt;br /&gt;
# Основной цикл оптимизации&lt;br /&gt;
# повторяем его пока не сработает критерий останова&lt;br /&gt;
# предполагаем, что критерий использует значения&lt;br /&gt;
# функционала качества кластеризации&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
&lt;br /&gt;
    # Оптимизация матрицы M&lt;br /&gt;
    # при фиксированных центроидах&lt;br /&gt;
    # пообъектный цикл&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        # вычисляем расстояния до кластеров&lt;br /&gt;
        # находим минимальный&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
        # добавляем расстояние до ближайшего &lt;br /&gt;
        # кластера к фунционалу качества кластеризации&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
&lt;br /&gt;
        # обнуление старого соответствия объекта кластеру&lt;br /&gt;
        # передача соответствия новому кластеру&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, clusterization[i]] = 1&lt;br /&gt;
 &lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    # Оптимизация центроидов при &lt;br /&gt;
    # фиксированной ранговой матрице&lt;br /&gt;
    # покластерный цикл&lt;br /&gt;
    c = zeros(N, C)&lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        # заводим счётчик, сколько объектов в кластере&lt;br /&gt;
        # он далее будет использоваться для&lt;br /&gt;
        # нормализации центроида&lt;br /&gt;
        n_pts_in_cluster = 0&lt;br /&gt;
&lt;br /&gt;
        for i in range(N):&lt;br /&gt;
            # складываем центроид покоординатно только&lt;br /&gt;
            # с точками, принадлежащими кластеру&lt;br /&gt;
            if not M[i, j]:&lt;br /&gt;
                continue&lt;br /&gt;
            n_pts_in_cluster += 1&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                c[j, k] += u[i, k]&lt;br /&gt;
&lt;br /&gt;
        # нормализация центроида&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c[j, k] /= n_pts_in_cluster&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На каждой итерации основного цикла алгоритма:&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; операций вычисления квадратов расстояний до центров кластеров: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; разностей, возведеий в квадрат и &amp;lt;math&amp;gt;NC(D-1)&amp;lt;/math&amp;gt; сумм&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
* Шаг 3 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; сложений&lt;br /&gt;
* Шаг 4 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; векторных умножений на скаляр, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; сложений: &amp;lt;math&amp;gt;ND+C&amp;lt;/math&amp;gt; сложений и &amp;lt;math&amp;gt;CD&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
Итого, одна итерация основного цикла стоит &amp;lt;math&amp;gt;O(3NCD)&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;
&#039;&#039;&#039;Группа 1&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;d(p,c)&amp;lt;/math&amp;gt;, выделена зелёным цветом.&lt;br /&gt;
Отвечает за вычисление расстояний между точками &amp;lt;math&amp;gt;p, u_i&amp;lt;/math&amp;gt; и центроидами &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt;. Расстояния вычисляются независимо как по точкам, так и по центроидам. Несмотря на независимость вычислений, их следует группировать по точкам, так как в дальнейшем результатов (расстояния до центров) будут аггрерироваться по точкам (операция &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 2&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;, выделена жёлтым цветом.&lt;br /&gt;
Отвечает за поиск ближайшего центроида до данной точки (при уже вычисленных расстояниях). Фактически, применяет паттерн Reduce с участием ассоциативной операцией &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;. Находит как индекс ближайшего центроида (используется для обновления матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;), так и расстояние до него (входит в сумму &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 3&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, выделена красным цветом. Обновляет значения матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; для каждой точки. Индикатор, соответствующий старому центроиду обнуляется, а новому - выставляется 1.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 4&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;J sum&amp;lt;/math&amp;gt;, выделена сиреневым цветом.&lt;br /&gt;
Осуществляет суммирование расстояний до ближайших центроидов. Применение паттерна Reduce с участием операции &amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 5&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;upd c&amp;lt;/math&amp;gt;, выделена синим цветом. Обновляет координаты центроидов. Для каждого центроида &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; перебираются все точки &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;M[c, p] = 1&amp;lt;/math&amp;gt;. Координаты таких точек суммируются (независимо покоординатно), возможно, с применением паттерна Reduce по точкам. Так же заводятся счётчики: сколько точек принадлежит кластеру с данным центроидом. Затем покоординатно производится нормировка.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:HCM_IG.png|thumb|800px|center| Информационный граф алгоритма. Здесь &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - точки &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерного пространства, соответствующие исследуемым объектам (входные данные); &amp;lt;math&amp;gt;d(p,c)&amp;lt;/math&amp;gt; вычисление расстояний от точки то центров; &amp;lt;math&amp;gt;\arg\,\min&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;; &amp;lt;math&amp;gt;J, J_{sum}&amp;lt;/math&amp;gt; вычисление и аггрерирование функционала оптимизации; &amp;lt;math&amp;gt;upd 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;
В первой (зелёной) группе необходимо вычислить &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; расстояний. Каждое вычисление расстояния сопоставляется вычислению &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; покоординатных расстояний с последующим суммированием. Ширина ЯПФ &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log D)&amp;lt;/math&amp;gt;. Отметим, что на практике суммрование сдваиванием может не быть самой оптимальной стратегией из-за оверхеда на обеспечение синхронизации: выходом может быть тоже иерархический паттерн Reduce, но арргерирующий больше двух результатов на одной вычислительной единице. Асимптотическая высота такого паттерна так же &amp;lt;math&amp;gt;O(\log NC)&amp;lt;/math&amp;gt;. При достаточно малых значениях &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; оптимальная стратения может выродится в цикл на одной вычислительной единице.&lt;br /&gt;
&lt;br /&gt;
Во второй группе (желтой) по каждой из &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; точек проводится &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt;-аггрегация &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; результатов. Таким образом, ширина ЯПФ &amp;lt;math&amp;gt;O(NC)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В третьей (красной) группе всё примитивно. &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; событий по опусканию одного и поднятию другого флага. Ширина &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В четвёртой (сиреневой) группе: SUM-аггрерация &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; результатов. Ширина ЯПФ &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В пятой (синей) группе: по каждому из &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; центроидов независимо покоординатно (&amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; координат) надо найти сумму произведений &amp;lt;math&amp;gt;u_{ik} \cdot M_{ij}&amp;lt;/math&amp;gt;. Так же надо завести счётчик. Ширина ЯПФ &amp;lt;math&amp;gt;O(C(D+1)N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N + 1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итого, ширина ЯПФ алгоритма &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N + \log C)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_k \}_{k=1}^N \subset \mathbb{R}^D&amp;lt;/math&amp;gt; — исходный набор точек признакового пространства.&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — количество кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;criteria\, params&amp;lt;/math&amp;gt; — параметры критерия останова.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;ND + const&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;M \in \mathbb{R}^{N \times C} &amp;lt;/math&amp;gt; — рядовая матрица&lt;br /&gt;
* &amp;lt;math&amp;gt;\{c_k\}_{k=1}^C&amp;lt;/math&amp;gt; — координаты кластерных центров&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;C(N+D)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Назначение:&#039;&#039;&#039; кластеризация больших наборов числовых данных  представленных признаковыми описаниями объектов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Достоинства:&#039;&#039;&#039;&lt;br /&gt;
* лёгкость реализации&lt;br /&gt;
* вычислительная простота&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки:&#039;&#039;&#039;&lt;br /&gt;
* явное задание количества кластеров&lt;br /&gt;
* отсутствие гарантии нахождения оптимального решения&lt;br /&gt;
* чувствительность к начальному приближению координат кластерных центров&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt; и параллельной &amp;lt;math&amp;gt;(\log N + \log C)&amp;lt;/math&amp;gt; сложности в случае неограниченных ресурсов сублинейна по &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (по количеству объектов и кластеров), линейна по &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; (по размерности признакового пространства).&lt;br /&gt;
&lt;br /&gt;
Вычислительная мощность, как отношение числа операций к суммарному объёму входных и выходных данных, &#039;&#039;линейна&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм детерменирован при явном задании начального приближения для центроидов. Алгоритм чувствителен к выбору начального приближения.&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
Для проверки масштабируемости алгоритма была создана собственная реализация алгоритма&amp;lt;ref&amp;gt;https://github.com/urandon/hcm_tbb&amp;lt;/ref&amp;gt; с использованием фреймворка Intel® Threading Building Blocks &amp;lt;ref&amp;gt;https://www.threadingbuildingblocks.org/&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Хотя реализация имеет ряд ограничений для полноценной оценки масштабируемости: предполагается запуск на одной машине используя мультитрединг -- всё же она может дать интерпретируемые результаты.&lt;br /&gt;
&lt;br /&gt;
Используемый компилятор: оптимизирующий компилятор Microsoft® С/C++ версии 19.00.24215.1. Процессор: Intel Core i7-3157U (2 ядра, 4 потока).&lt;br /&gt;
&lt;br /&gt;
Решалась задача в 128-мерном пространстве с поиском 10 кластеров.&lt;br /&gt;
Результаты тестов:&lt;br /&gt;
{|border = &amp;quot;1&amp;quot;&lt;br /&gt;
! № объектов \ № потоков&lt;br /&gt;
! 1&lt;br /&gt;
! 2&lt;br /&gt;
! 4&lt;br /&gt;
|-&lt;br /&gt;
!100&lt;br /&gt;
|165ms&lt;br /&gt;
|89ms&lt;br /&gt;
|49ms&lt;br /&gt;
|-&lt;br /&gt;
!1000&lt;br /&gt;
|1612ms&lt;br /&gt;
|886ms&lt;br /&gt;
|485ms&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Так как ресурсы тестовой системы сильно лимитированы, то получить сложность &amp;lt;math&amp;gt;O(\log N + \log 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;
1) [http://projects.jasmeet.me/2013/03/HardCMeans.html Matlab, последовательная реализация]&lt;br /&gt;
&lt;br /&gt;
2) [https://github.com/artpar/Hard-Clustering-implementation С++, последовательная реализация ]&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=22486</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=22486"/>
		<updated>2017-02-08T20:19:23Z</updated>

		<summary type="html">&lt;p&gt;Urandon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assigned}}&lt;br /&gt;
&lt;br /&gt;
Автор описания [[Участник:Urandon|Хомутов Никита]]&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;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
Целевая функция алгоритма полностью аналогична целевой функции K-Means[https://ru.wikipedia.org/wiki/K-means].&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \qquad \forall j \neq i \\&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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt; арифметичеких операций.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой итерационный процесс, в котором поочерёдно происходит покоординатная оптимизация функционала &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
J(M, C) \to \max_{M}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
J(M, C) \to \max_{C}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оптимизация функционала по &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; приводит к вычислению расстояний между объектами и центроидами, поиском ближайших.&lt;br /&gt;
&lt;br /&gt;
Оптимизация по &amp;lt;math&amp;gt;C&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;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
Данная операция сводится к использованию ассоциативной &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt; и паттерна Reduse&amp;lt;ref&amp;gt;Reduce paralle pattern [http://www.drdobbs.com/architecture-and-design/parallel-pattern-7-reduce/222000718]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
Последовательная схема реализована в виде python-подобного псевдокода. Для оптимизации вычислений хранится структура, хранящая номер кластера для каждой точки. Это оптимизация с учётом разреженности матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# Инициализация&lt;br /&gt;
J_history = []&lt;br /&gt;
# центроиды выбираются случайно среди объектов&lt;br /&gt;
c = u[random.choice(N, C), :] &lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
# хранилище индексов кластеров для каждого объекта&lt;br /&gt;
# используется для обновления ранговой матрицы M&lt;br /&gt;
clusterization = zeros(N) &lt;br /&gt;
&lt;br /&gt;
# Основной цикл оптимизации&lt;br /&gt;
# повторяем его пока не сработает критерий останова&lt;br /&gt;
# предполагаем, что критерий использует значения&lt;br /&gt;
# функционала качества кластеризации&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
&lt;br /&gt;
    # Оптимизация матрицы M&lt;br /&gt;
    # при фиксированных центроидах&lt;br /&gt;
    # пообъектный цикл&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        # вычисляем расстояния до кластеров&lt;br /&gt;
        # находим минимальный&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
        # добавляем расстояние до ближайшего &lt;br /&gt;
        # кластера к фунционалу качества кластеризации&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
&lt;br /&gt;
        # обнуление старого соответствия объекта кластеру&lt;br /&gt;
        # передача соответствия новому кластеру&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, clusterization[i]] = 1&lt;br /&gt;
 &lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    # Оптимизация центроидов при &lt;br /&gt;
    # фиксированной ранговой матрице&lt;br /&gt;
    # покластерный цикл&lt;br /&gt;
    c = zeros(N, C)&lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        # заводим счётчик, сколько объектов в кластере&lt;br /&gt;
        # он далее будет использоваться для&lt;br /&gt;
        # нормализации центроида&lt;br /&gt;
        n_pts_in_cluster = 0&lt;br /&gt;
&lt;br /&gt;
        for i in range(N):&lt;br /&gt;
            # складываем центроид покоординатно только&lt;br /&gt;
            # с точками, принадлежащими кластеру&lt;br /&gt;
            if not M[i, j]:&lt;br /&gt;
                continue&lt;br /&gt;
            n_pts_in_cluster += 1&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                c[j, k] += u[i, k]&lt;br /&gt;
&lt;br /&gt;
        # нормализация центроида&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c[j, k] /= n_pts_in_cluster&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На каждой итерации основного цикла алгоритма:&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; операций вычисления квадратов расстояний до центров кластеров: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; разностей, возведеий в квадрат и &amp;lt;math&amp;gt;NC(D-1)&amp;lt;/math&amp;gt; сумм&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
* Шаг 3 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; сложений&lt;br /&gt;
* Шаг 4 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; векторных умножений на скаляр, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; сложений: &amp;lt;math&amp;gt;ND+C&amp;lt;/math&amp;gt; сложений и &amp;lt;math&amp;gt;CD&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
Итого, одна итерация основного цикла стоит &amp;lt;math&amp;gt;O(3NCD)&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;
&#039;&#039;&#039;Группа 1&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;d(p,c)&amp;lt;/math&amp;gt;, выделена зелёным цветом.&lt;br /&gt;
Отвечает за вычисление расстояний между точками &amp;lt;math&amp;gt;p, u_i&amp;lt;/math&amp;gt; и центроидами &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt;. Расстояния вычисляются независимо как по точкам, так и по центроидам. Несмотря на независимость вычислений, их следует группировать по точкам, так как в дальнейшем результатов (расстояния до центров) будут аггрерироваться по точкам (операция &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 2&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;, выделена жёлтым цветом.&lt;br /&gt;
Отвечает за поиск ближайшего центроида до данной точки (при уже вычисленных расстояниях). Фактически, применяет паттерн Reduce с участием ассоциативной операцией &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;. Находит как индекс ближайшего центроида (используется для обновления матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;), так и расстояние до него (входит в сумму &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 3&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, выделена красным цветом. Обновляет значения матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; для каждой точки. Индикатор, соответствующий старому центроиду обнуляется, а новому - выставляется 1.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 4&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;J sum&amp;lt;/math&amp;gt;, выделена сиреневым цветом.&lt;br /&gt;
Осуществляет суммирование расстояний до ближайших центроидов. Применение паттерна Reduce с участием операции &amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 5&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;upd c&amp;lt;/math&amp;gt;, выделена синим цветом. Обновляет координаты центроидов. Для каждого центроида &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; перебираются все точки &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;M[c, p] = 1&amp;lt;/math&amp;gt;. Координаты таких точек суммируются (независимо покоординатно), возможно, с применением паттерна Reduce по точкам. Так же заводятся счётчики: сколько точек принадлежит кластеру с данным центроидом. Затем покоординатно производится нормировка.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:HCM_IG.png|thumb|800px|center| Информационный граф алгоритма. Здесь &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - точки &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерного пространства, соответствующие исследуемым объектам (входные данные); &amp;lt;math&amp;gt;d(p,c)&amp;lt;/math&amp;gt; вычисление расстояний от точки то центров; &amp;lt;math&amp;gt;\arg\,\min&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;; &amp;lt;math&amp;gt;J, J_{sum}&amp;lt;/math&amp;gt; вычисление и аггрерирование функционала оптимизации; &amp;lt;math&amp;gt;upd 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;
В первой (зелёной) группе необходимо вычислить &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; расстояний. Каждое вычисление расстояния сопоставляется вычислению &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; покоординатных расстояний с последующим суммированием. Ширина ЯПФ &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log D)&amp;lt;/math&amp;gt;. Отметим, что на практике суммрование сдваиванием может не быть самой оптимальной стратегией из-за оверхеда на обеспечение синхронизации: выходом может быть тоже иерархический паттерн Reduce, но арргерирующий больше двух результатов на одной вычислительной единице. Асимптотическая высота такого паттерна так же &amp;lt;math&amp;gt;O(\log NC)&amp;lt;/math&amp;gt;. При достаточно малых значениях &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; оптимальная стратения может выродится в цикл на одной вычислительной единице.&lt;br /&gt;
&lt;br /&gt;
Во второй группе (желтой) по каждой из &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; точек проводится &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt;-аггрегация &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; результатов. Таким образом, ширина ЯПФ &amp;lt;math&amp;gt;O(NC)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В третьей (красной) группе всё примитивно. &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; событий по опусканию одного и поднятию другого флага. Ширина &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В четвёртой (сиреневой) группе: SUM-аггрерация &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; результатов. Ширина ЯПФ &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В пятой (синей) группе: по каждому из &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; центроидов независимо покоординатно (&amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; координат) надо найти сумму произведений &amp;lt;math&amp;gt;u_{ik} \cdot M_{ij}&amp;lt;/math&amp;gt;. Так же надо завести счётчик. Ширина ЯПФ &amp;lt;math&amp;gt;O(C(D+1)N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N + 1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итого, ширина ЯПФ алгоритма &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N + \log C)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_k \}_{k=1}^N \subset \mathbb{R}^D&amp;lt;/math&amp;gt; — исходный набор точек признакового пространства.&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — количество кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;criteria\, params&amp;lt;/math&amp;gt; — параметры критерия останова.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;ND + const&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;M \in \mathbb{R}^{N \times C} &amp;lt;/math&amp;gt; — рядовая матрица&lt;br /&gt;
* &amp;lt;math&amp;gt;\{c_k\}_{k=1}^C&amp;lt;/math&amp;gt; — координаты кластерных центров&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;C(N+D)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Назначение:&#039;&#039;&#039; кластеризация больших наборов числовых данных  представленных признаковыми описаниями объектов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Достоинства:&#039;&#039;&#039;&lt;br /&gt;
* лёгкость реализации&lt;br /&gt;
* вычислительная простота&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки:&#039;&#039;&#039;&lt;br /&gt;
* явное задание количества кластеров&lt;br /&gt;
* отсутствие гарантии нахождения оптимального решения&lt;br /&gt;
* чувствительность к начальному приближению координат кластерных центров&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt; и параллельной &amp;lt;math&amp;gt;(\log N + \log C)&amp;lt;/math&amp;gt; сложности в случае неограниченных ресурсов сублинейна по &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (по количеству объектов и кластеров), линейна по &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; (по размерности признакового пространства).&lt;br /&gt;
&lt;br /&gt;
Вычислительная мощность, как отношение числа операций к суммарному объёму входных и выходных данных, &#039;&#039;линейна&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм детерменирован при явном задании начального приближения для центроидов. Алгоритм чувствителен к выбору начального приближения.&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
Для проверки масштабируемости алгоритма была создана собственная реализация алгоритма&amp;lt;ref&amp;gt;https://github.com/urandon/hcm_tbb&amp;lt;/ref&amp;gt; с использованием фреймворка Intel® Threading Building Blocks &amp;lt;ref&amp;gt;https://www.threadingbuildingblocks.org/&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Хотя реализация имеет ряд ограничений для полноценной оценки масштабируемости: предполагается запуск на одной машине используя мультитрединг -- всё же она может дать интерпретируемые результаты.&lt;br /&gt;
&lt;br /&gt;
Используемый компилятор: оптимизирующий компилятор Microsoft® С/C++ версии 19.00.24215.1. Процессор: Intel Core i7-3157U (2 ядра, 4 потока).&lt;br /&gt;
&lt;br /&gt;
Решалась задача в 128-мерном пространстве с поиском 10 кластеров.&lt;br /&gt;
Результаты тестов:&lt;br /&gt;
{|border = &amp;quot;1&amp;quot;&lt;br /&gt;
! № объектов \ № потоков&lt;br /&gt;
! 1&lt;br /&gt;
! 2&lt;br /&gt;
! 4&lt;br /&gt;
|-&lt;br /&gt;
!100&lt;br /&gt;
|165ms&lt;br /&gt;
|89ms&lt;br /&gt;
|49ms&lt;br /&gt;
|-&lt;br /&gt;
!1000&lt;br /&gt;
|1612ms&lt;br /&gt;
|886ms&lt;br /&gt;
|485ms&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Так как ресурсы тестовой системы сильно лимитированы, то получить сложность &amp;lt;math&amp;gt;O(\log N + \log 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;
1) [http://projects.jasmeet.me/2013/03/HardCMeans.html Matlab, последовательная реализация]&lt;br /&gt;
&lt;br /&gt;
2) [https://github.com/artpar/Hard-Clustering-implementation С++, последовательная реализация ]&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=22485</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=22485"/>
		<updated>2017-02-08T20:19:05Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Макроструктура алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор описания [[Участник:Urandon|Хомутов Никита]]&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;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
Целевая функция алгоритма полностью аналогична целевой функции K-Means[https://ru.wikipedia.org/wiki/K-means].&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \qquad \forall j \neq i \\&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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt; арифметичеких операций.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой итерационный процесс, в котором поочерёдно происходит покоординатная оптимизация функционала &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
J(M, C) \to \max_{M}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
J(M, C) \to \max_{C}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оптимизация функционала по &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; приводит к вычислению расстояний между объектами и центроидами, поиском ближайших.&lt;br /&gt;
&lt;br /&gt;
Оптимизация по &amp;lt;math&amp;gt;C&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;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
Данная операция сводится к использованию ассоциативной &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt; и паттерна Reduse&amp;lt;ref&amp;gt;Reduce paralle pattern [http://www.drdobbs.com/architecture-and-design/parallel-pattern-7-reduce/222000718]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
Последовательная схема реализована в виде python-подобного псевдокода. Для оптимизации вычислений хранится структура, хранящая номер кластера для каждой точки. Это оптимизация с учётом разреженности матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# Инициализация&lt;br /&gt;
J_history = []&lt;br /&gt;
# центроиды выбираются случайно среди объектов&lt;br /&gt;
c = u[random.choice(N, C), :] &lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
# хранилище индексов кластеров для каждого объекта&lt;br /&gt;
# используется для обновления ранговой матрицы M&lt;br /&gt;
clusterization = zeros(N) &lt;br /&gt;
&lt;br /&gt;
# Основной цикл оптимизации&lt;br /&gt;
# повторяем его пока не сработает критерий останова&lt;br /&gt;
# предполагаем, что критерий использует значения&lt;br /&gt;
# функционала качества кластеризации&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
&lt;br /&gt;
    # Оптимизация матрицы M&lt;br /&gt;
    # при фиксированных центроидах&lt;br /&gt;
    # пообъектный цикл&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        # вычисляем расстояния до кластеров&lt;br /&gt;
        # находим минимальный&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
        # добавляем расстояние до ближайшего &lt;br /&gt;
        # кластера к фунционалу качества кластеризации&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
&lt;br /&gt;
        # обнуление старого соответствия объекта кластеру&lt;br /&gt;
        # передача соответствия новому кластеру&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, clusterization[i]] = 1&lt;br /&gt;
 &lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    # Оптимизация центроидов при &lt;br /&gt;
    # фиксированной ранговой матрице&lt;br /&gt;
    # покластерный цикл&lt;br /&gt;
    c = zeros(N, C)&lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        # заводим счётчик, сколько объектов в кластере&lt;br /&gt;
        # он далее будет использоваться для&lt;br /&gt;
        # нормализации центроида&lt;br /&gt;
        n_pts_in_cluster = 0&lt;br /&gt;
&lt;br /&gt;
        for i in range(N):&lt;br /&gt;
            # складываем центроид покоординатно только&lt;br /&gt;
            # с точками, принадлежащими кластеру&lt;br /&gt;
            if not M[i, j]:&lt;br /&gt;
                continue&lt;br /&gt;
            n_pts_in_cluster += 1&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                c[j, k] += u[i, k]&lt;br /&gt;
&lt;br /&gt;
        # нормализация центроида&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c[j, k] /= n_pts_in_cluster&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На каждой итерации основного цикла алгоритма:&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; операций вычисления квадратов расстояний до центров кластеров: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; разностей, возведеий в квадрат и &amp;lt;math&amp;gt;NC(D-1)&amp;lt;/math&amp;gt; сумм&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
* Шаг 3 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; сложений&lt;br /&gt;
* Шаг 4 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; векторных умножений на скаляр, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; сложений: &amp;lt;math&amp;gt;ND+C&amp;lt;/math&amp;gt; сложений и &amp;lt;math&amp;gt;CD&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
Итого, одна итерация основного цикла стоит &amp;lt;math&amp;gt;O(3NCD)&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;
&#039;&#039;&#039;Группа 1&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;d(p,c)&amp;lt;/math&amp;gt;, выделена зелёным цветом.&lt;br /&gt;
Отвечает за вычисление расстояний между точками &amp;lt;math&amp;gt;p, u_i&amp;lt;/math&amp;gt; и центроидами &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt;. Расстояния вычисляются независимо как по точкам, так и по центроидам. Несмотря на независимость вычислений, их следует группировать по точкам, так как в дальнейшем результатов (расстояния до центров) будут аггрерироваться по точкам (операция &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 2&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;, выделена жёлтым цветом.&lt;br /&gt;
Отвечает за поиск ближайшего центроида до данной точки (при уже вычисленных расстояниях). Фактически, применяет паттерн Reduce с участием ассоциативной операцией &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;. Находит как индекс ближайшего центроида (используется для обновления матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;), так и расстояние до него (входит в сумму &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 3&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, выделена красным цветом. Обновляет значения матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; для каждой точки. Индикатор, соответствующий старому центроиду обнуляется, а новому - выставляется 1.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 4&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;J sum&amp;lt;/math&amp;gt;, выделена сиреневым цветом.&lt;br /&gt;
Осуществляет суммирование расстояний до ближайших центроидов. Применение паттерна Reduce с участием операции &amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 5&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;upd c&amp;lt;/math&amp;gt;, выделена синим цветом. Обновляет координаты центроидов. Для каждого центроида &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; перебираются все точки &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;M[c, p] = 1&amp;lt;/math&amp;gt;. Координаты таких точек суммируются (независимо покоординатно), возможно, с применением паттерна Reduce по точкам. Так же заводятся счётчики: сколько точек принадлежит кластеру с данным центроидом. Затем покоординатно производится нормировка.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:HCM_IG.png|thumb|800px|center| Информационный граф алгоритма. Здесь &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - точки &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерного пространства, соответствующие исследуемым объектам (входные данные); &amp;lt;math&amp;gt;d(p,c)&amp;lt;/math&amp;gt; вычисление расстояний от точки то центров; &amp;lt;math&amp;gt;\arg\,\min&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;; &amp;lt;math&amp;gt;J, J_{sum}&amp;lt;/math&amp;gt; вычисление и аггрерирование функционала оптимизации; &amp;lt;math&amp;gt;upd 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;
В первой (зелёной) группе необходимо вычислить &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; расстояний. Каждое вычисление расстояния сопоставляется вычислению &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; покоординатных расстояний с последующим суммированием. Ширина ЯПФ &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log D)&amp;lt;/math&amp;gt;. Отметим, что на практике суммрование сдваиванием может не быть самой оптимальной стратегией из-за оверхеда на обеспечение синхронизации: выходом может быть тоже иерархический паттерн Reduce, но арргерирующий больше двух результатов на одной вычислительной единице. Асимптотическая высота такого паттерна так же &amp;lt;math&amp;gt;O(\log NC)&amp;lt;/math&amp;gt;. При достаточно малых значениях &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; оптимальная стратения может выродится в цикл на одной вычислительной единице.&lt;br /&gt;
&lt;br /&gt;
Во второй группе (желтой) по каждой из &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; точек проводится &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt;-аггрегация &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; результатов. Таким образом, ширина ЯПФ &amp;lt;math&amp;gt;O(NC)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В третьей (красной) группе всё примитивно. &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; событий по опусканию одного и поднятию другого флага. Ширина &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В четвёртой (сиреневой) группе: SUM-аггрерация &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; результатов. Ширина ЯПФ &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В пятой (синей) группе: по каждому из &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; центроидов независимо покоординатно (&amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; координат) надо найти сумму произведений &amp;lt;math&amp;gt;u_{ik} \cdot M_{ij}&amp;lt;/math&amp;gt;. Так же надо завести счётчик. Ширина ЯПФ &amp;lt;math&amp;gt;O(C(D+1)N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N + 1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итого, ширина ЯПФ алгоритма &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N + \log C)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_k \}_{k=1}^N \subset \mathbb{R}^D&amp;lt;/math&amp;gt; — исходный набор точек признакового пространства.&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — количество кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;criteria\, params&amp;lt;/math&amp;gt; — параметры критерия останова.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;ND + const&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;M \in \mathbb{R}^{N \times C} &amp;lt;/math&amp;gt; — рядовая матрица&lt;br /&gt;
* &amp;lt;math&amp;gt;\{c_k\}_{k=1}^C&amp;lt;/math&amp;gt; — координаты кластерных центров&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;C(N+D)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Назначение:&#039;&#039;&#039; кластеризация больших наборов числовых данных  представленных признаковыми описаниями объектов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Достоинства:&#039;&#039;&#039;&lt;br /&gt;
* лёгкость реализации&lt;br /&gt;
* вычислительная простота&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки:&#039;&#039;&#039;&lt;br /&gt;
* явное задание количества кластеров&lt;br /&gt;
* отсутствие гарантии нахождения оптимального решения&lt;br /&gt;
* чувствительность к начальному приближению координат кластерных центров&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt; и параллельной &amp;lt;math&amp;gt;(\log N + \log C)&amp;lt;/math&amp;gt; сложности в случае неограниченных ресурсов сублинейна по &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (по количеству объектов и кластеров), линейна по &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; (по размерности признакового пространства).&lt;br /&gt;
&lt;br /&gt;
Вычислительная мощность, как отношение числа операций к суммарному объёму входных и выходных данных, &#039;&#039;линейна&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм детерменирован при явном задании начального приближения для центроидов. Алгоритм чувствителен к выбору начального приближения.&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
Для проверки масштабируемости алгоритма была создана собственная реализация алгоритма&amp;lt;ref&amp;gt;https://github.com/urandon/hcm_tbb&amp;lt;/ref&amp;gt; с использованием фреймворка Intel® Threading Building Blocks &amp;lt;ref&amp;gt;https://www.threadingbuildingblocks.org/&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Хотя реализация имеет ряд ограничений для полноценной оценки масштабируемости: предполагается запуск на одной машине используя мультитрединг -- всё же она может дать интерпретируемые результаты.&lt;br /&gt;
&lt;br /&gt;
Используемый компилятор: оптимизирующий компилятор Microsoft® С/C++ версии 19.00.24215.1. Процессор: Intel Core i7-3157U (2 ядра, 4 потока).&lt;br /&gt;
&lt;br /&gt;
Решалась задача в 128-мерном пространстве с поиском 10 кластеров.&lt;br /&gt;
Результаты тестов:&lt;br /&gt;
{|border = &amp;quot;1&amp;quot;&lt;br /&gt;
! № объектов \ № потоков&lt;br /&gt;
! 1&lt;br /&gt;
! 2&lt;br /&gt;
! 4&lt;br /&gt;
|-&lt;br /&gt;
!100&lt;br /&gt;
|165ms&lt;br /&gt;
|89ms&lt;br /&gt;
|49ms&lt;br /&gt;
|-&lt;br /&gt;
!1000&lt;br /&gt;
|1612ms&lt;br /&gt;
|886ms&lt;br /&gt;
|485ms&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Так как ресурсы тестовой системы сильно лимитированы, то получить сложность &amp;lt;math&amp;gt;O(\log N + \log 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;
1) [http://projects.jasmeet.me/2013/03/HardCMeans.html Matlab, последовательная реализация]&lt;br /&gt;
&lt;br /&gt;
2) [https://github.com/artpar/Hard-Clustering-implementation С++, последовательная реализация ]&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=22484</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=22484"/>
		<updated>2017-02-08T20:17:09Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Макроструктура алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор описания [[Участник:Urandon|Хомутов Никита]]&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;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
Целевая функция алгоритма полностью аналогична целевой функции K-Means[https://ru.wikipedia.org/wiki/K-means].&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \qquad \forall j \neq i \\&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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt; арифметичеких операций.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм представляет собой итерационный процесс, в котором поочерёдно происходит покоординатная оптимизация функционала &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
J(M, C) \to \max_{M}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
J(M, C) \to \max_{C}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Алгоритм распадается на макрооперации, примитивами которых выступают вектора линейных пространств.&lt;br /&gt;
&lt;br /&gt;
Вычисление разностей векторов с последующим вычислением евклидовой нормы на втором шаге алгоритма.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
Данная операция сводится к использованию ассоциативной &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt; и паттерна Reduse&amp;lt;ref&amp;gt;Reduce paralle pattern [http://www.drdobbs.com/architecture-and-design/parallel-pattern-7-reduce/222000718]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
Последовательная схема реализована в виде python-подобного псевдокода. Для оптимизации вычислений хранится структура, хранящая номер кластера для каждой точки. Это оптимизация с учётом разреженности матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# Инициализация&lt;br /&gt;
J_history = []&lt;br /&gt;
# центроиды выбираются случайно среди объектов&lt;br /&gt;
c = u[random.choice(N, C), :] &lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
# хранилище индексов кластеров для каждого объекта&lt;br /&gt;
# используется для обновления ранговой матрицы M&lt;br /&gt;
clusterization = zeros(N) &lt;br /&gt;
&lt;br /&gt;
# Основной цикл оптимизации&lt;br /&gt;
# повторяем его пока не сработает критерий останова&lt;br /&gt;
# предполагаем, что критерий использует значения&lt;br /&gt;
# функционала качества кластеризации&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
&lt;br /&gt;
    # Оптимизация матрицы M&lt;br /&gt;
    # при фиксированных центроидах&lt;br /&gt;
    # пообъектный цикл&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        # вычисляем расстояния до кластеров&lt;br /&gt;
        # находим минимальный&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
        # добавляем расстояние до ближайшего &lt;br /&gt;
        # кластера к фунционалу качества кластеризации&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
&lt;br /&gt;
        # обнуление старого соответствия объекта кластеру&lt;br /&gt;
        # передача соответствия новому кластеру&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, clusterization[i]] = 1&lt;br /&gt;
 &lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    # Оптимизация центроидов при &lt;br /&gt;
    # фиксированной ранговой матрице&lt;br /&gt;
    # покластерный цикл&lt;br /&gt;
    c = zeros(N, C)&lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        # заводим счётчик, сколько объектов в кластере&lt;br /&gt;
        # он далее будет использоваться для&lt;br /&gt;
        # нормализации центроида&lt;br /&gt;
        n_pts_in_cluster = 0&lt;br /&gt;
&lt;br /&gt;
        for i in range(N):&lt;br /&gt;
            # складываем центроид покоординатно только&lt;br /&gt;
            # с точками, принадлежащими кластеру&lt;br /&gt;
            if not M[i, j]:&lt;br /&gt;
                continue&lt;br /&gt;
            n_pts_in_cluster += 1&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                c[j, k] += u[i, k]&lt;br /&gt;
&lt;br /&gt;
        # нормализация центроида&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c[j, k] /= n_pts_in_cluster&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На каждой итерации основного цикла алгоритма:&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; операций вычисления квадратов расстояний до центров кластеров: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; разностей, возведеий в квадрат и &amp;lt;math&amp;gt;NC(D-1)&amp;lt;/math&amp;gt; сумм&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
* Шаг 3 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; сложений&lt;br /&gt;
* Шаг 4 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; векторных умножений на скаляр, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; сложений: &amp;lt;math&amp;gt;ND+C&amp;lt;/math&amp;gt; сложений и &amp;lt;math&amp;gt;CD&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
Итого, одна итерация основного цикла стоит &amp;lt;math&amp;gt;O(3NCD)&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;
&#039;&#039;&#039;Группа 1&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;d(p,c)&amp;lt;/math&amp;gt;, выделена зелёным цветом.&lt;br /&gt;
Отвечает за вычисление расстояний между точками &amp;lt;math&amp;gt;p, u_i&amp;lt;/math&amp;gt; и центроидами &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt;. Расстояния вычисляются независимо как по точкам, так и по центроидам. Несмотря на независимость вычислений, их следует группировать по точкам, так как в дальнейшем результатов (расстояния до центров) будут аггрерироваться по точкам (операция &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 2&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;, выделена жёлтым цветом.&lt;br /&gt;
Отвечает за поиск ближайшего центроида до данной точки (при уже вычисленных расстояниях). Фактически, применяет паттерн Reduce с участием ассоциативной операцией &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;. Находит как индекс ближайшего центроида (используется для обновления матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;), так и расстояние до него (входит в сумму &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 3&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, выделена красным цветом. Обновляет значения матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; для каждой точки. Индикатор, соответствующий старому центроиду обнуляется, а новому - выставляется 1.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 4&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;J sum&amp;lt;/math&amp;gt;, выделена сиреневым цветом.&lt;br /&gt;
Осуществляет суммирование расстояний до ближайших центроидов. Применение паттерна Reduce с участием операции &amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 5&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;upd c&amp;lt;/math&amp;gt;, выделена синим цветом. Обновляет координаты центроидов. Для каждого центроида &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; перебираются все точки &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;M[c, p] = 1&amp;lt;/math&amp;gt;. Координаты таких точек суммируются (независимо покоординатно), возможно, с применением паттерна Reduce по точкам. Так же заводятся счётчики: сколько точек принадлежит кластеру с данным центроидом. Затем покоординатно производится нормировка.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:HCM_IG.png|thumb|800px|center| Информационный граф алгоритма. Здесь &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - точки &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерного пространства, соответствующие исследуемым объектам (входные данные); &amp;lt;math&amp;gt;d(p,c)&amp;lt;/math&amp;gt; вычисление расстояний от точки то центров; &amp;lt;math&amp;gt;\arg\,\min&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;; &amp;lt;math&amp;gt;J, J_{sum}&amp;lt;/math&amp;gt; вычисление и аггрерирование функционала оптимизации; &amp;lt;math&amp;gt;upd 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;
В первой (зелёной) группе необходимо вычислить &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; расстояний. Каждое вычисление расстояния сопоставляется вычислению &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; покоординатных расстояний с последующим суммированием. Ширина ЯПФ &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log D)&amp;lt;/math&amp;gt;. Отметим, что на практике суммрование сдваиванием может не быть самой оптимальной стратегией из-за оверхеда на обеспечение синхронизации: выходом может быть тоже иерархический паттерн Reduce, но арргерирующий больше двух результатов на одной вычислительной единице. Асимптотическая высота такого паттерна так же &amp;lt;math&amp;gt;O(\log NC)&amp;lt;/math&amp;gt;. При достаточно малых значениях &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; оптимальная стратения может выродится в цикл на одной вычислительной единице.&lt;br /&gt;
&lt;br /&gt;
Во второй группе (желтой) по каждой из &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; точек проводится &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt;-аггрегация &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; результатов. Таким образом, ширина ЯПФ &amp;lt;math&amp;gt;O(NC)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В третьей (красной) группе всё примитивно. &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; событий по опусканию одного и поднятию другого флага. Ширина &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В четвёртой (сиреневой) группе: SUM-аггрерация &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; результатов. Ширина ЯПФ &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В пятой (синей) группе: по каждому из &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; центроидов независимо покоординатно (&amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; координат) надо найти сумму произведений &amp;lt;math&amp;gt;u_{ik} \cdot M_{ij}&amp;lt;/math&amp;gt;. Так же надо завести счётчик. Ширина ЯПФ &amp;lt;math&amp;gt;O(C(D+1)N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N + 1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итого, ширина ЯПФ алгоритма &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N + \log C)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_k \}_{k=1}^N \subset \mathbb{R}^D&amp;lt;/math&amp;gt; — исходный набор точек признакового пространства.&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — количество кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;criteria\, params&amp;lt;/math&amp;gt; — параметры критерия останова.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;ND + const&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;M \in \mathbb{R}^{N \times C} &amp;lt;/math&amp;gt; — рядовая матрица&lt;br /&gt;
* &amp;lt;math&amp;gt;\{c_k\}_{k=1}^C&amp;lt;/math&amp;gt; — координаты кластерных центров&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;C(N+D)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Назначение:&#039;&#039;&#039; кластеризация больших наборов числовых данных  представленных признаковыми описаниями объектов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Достоинства:&#039;&#039;&#039;&lt;br /&gt;
* лёгкость реализации&lt;br /&gt;
* вычислительная простота&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки:&#039;&#039;&#039;&lt;br /&gt;
* явное задание количества кластеров&lt;br /&gt;
* отсутствие гарантии нахождения оптимального решения&lt;br /&gt;
* чувствительность к начальному приближению координат кластерных центров&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt; и параллельной &amp;lt;math&amp;gt;(\log N + \log C)&amp;lt;/math&amp;gt; сложности в случае неограниченных ресурсов сублинейна по &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (по количеству объектов и кластеров), линейна по &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; (по размерности признакового пространства).&lt;br /&gt;
&lt;br /&gt;
Вычислительная мощность, как отношение числа операций к суммарному объёму входных и выходных данных, &#039;&#039;линейна&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм детерменирован при явном задании начального приближения для центроидов. Алгоритм чувствителен к выбору начального приближения.&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
Для проверки масштабируемости алгоритма была создана собственная реализация алгоритма&amp;lt;ref&amp;gt;https://github.com/urandon/hcm_tbb&amp;lt;/ref&amp;gt; с использованием фреймворка Intel® Threading Building Blocks &amp;lt;ref&amp;gt;https://www.threadingbuildingblocks.org/&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Хотя реализация имеет ряд ограничений для полноценной оценки масштабируемости: предполагается запуск на одной машине используя мультитрединг -- всё же она может дать интерпретируемые результаты.&lt;br /&gt;
&lt;br /&gt;
Используемый компилятор: оптимизирующий компилятор Microsoft® С/C++ версии 19.00.24215.1. Процессор: Intel Core i7-3157U (2 ядра, 4 потока).&lt;br /&gt;
&lt;br /&gt;
Решалась задача в 128-мерном пространстве с поиском 10 кластеров.&lt;br /&gt;
Результаты тестов:&lt;br /&gt;
{|border = &amp;quot;1&amp;quot;&lt;br /&gt;
! № объектов \ № потоков&lt;br /&gt;
! 1&lt;br /&gt;
! 2&lt;br /&gt;
! 4&lt;br /&gt;
|-&lt;br /&gt;
!100&lt;br /&gt;
|165ms&lt;br /&gt;
|89ms&lt;br /&gt;
|49ms&lt;br /&gt;
|-&lt;br /&gt;
!1000&lt;br /&gt;
|1612ms&lt;br /&gt;
|886ms&lt;br /&gt;
|485ms&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Так как ресурсы тестовой системы сильно лимитированы, то получить сложность &amp;lt;math&amp;gt;O(\log N + \log 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;
1) [http://projects.jasmeet.me/2013/03/HardCMeans.html Matlab, последовательная реализация]&lt;br /&gt;
&lt;br /&gt;
2) [https://github.com/artpar/Hard-Clustering-implementation С++, последовательная реализация ]&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=22483</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=22483"/>
		<updated>2017-02-08T20:09:25Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор описания [[Участник:Urandon|Хомутов Никита]]&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;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
Целевая функция алгоритма полностью аналогична целевой функции K-Means[https://ru.wikipedia.org/wiki/K-means].&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \qquad \forall j \neq i \\&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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
Данная операция сводится к использованию ассоциативной &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt; и паттерна Reduse&amp;lt;ref&amp;gt;Reduce paralle pattern [http://www.drdobbs.com/architecture-and-design/parallel-pattern-7-reduce/222000718]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
Последовательная схема реализована в виде python-подобного псевдокода. Для оптимизации вычислений хранится структура, хранящая номер кластера для каждой точки. Это оптимизация с учётом разреженности матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# Инициализация&lt;br /&gt;
J_history = []&lt;br /&gt;
# центроиды выбираются случайно среди объектов&lt;br /&gt;
c = u[random.choice(N, C), :] &lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
# хранилище индексов кластеров для каждого объекта&lt;br /&gt;
# используется для обновления ранговой матрицы M&lt;br /&gt;
clusterization = zeros(N) &lt;br /&gt;
&lt;br /&gt;
# Основной цикл оптимизации&lt;br /&gt;
# повторяем его пока не сработает критерий останова&lt;br /&gt;
# предполагаем, что критерий использует значения&lt;br /&gt;
# функционала качества кластеризации&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
&lt;br /&gt;
    # Оптимизация матрицы M&lt;br /&gt;
    # при фиксированных центроидах&lt;br /&gt;
    # пообъектный цикл&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        # вычисляем расстояния до кластеров&lt;br /&gt;
        # находим минимальный&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
        # добавляем расстояние до ближайшего &lt;br /&gt;
        # кластера к фунционалу качества кластеризации&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
&lt;br /&gt;
        # обнуление старого соответствия объекта кластеру&lt;br /&gt;
        # передача соответствия новому кластеру&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, clusterization[i]] = 1&lt;br /&gt;
 &lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    # Оптимизация центроидов при &lt;br /&gt;
    # фиксированной ранговой матрице&lt;br /&gt;
    # покластерный цикл&lt;br /&gt;
    c = zeros(N, C)&lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        # заводим счётчик, сколько объектов в кластере&lt;br /&gt;
        # он далее будет использоваться для&lt;br /&gt;
        # нормализации центроида&lt;br /&gt;
        n_pts_in_cluster = 0&lt;br /&gt;
&lt;br /&gt;
        for i in range(N):&lt;br /&gt;
            # складываем центроид покоординатно только&lt;br /&gt;
            # с точками, принадлежащими кластеру&lt;br /&gt;
            if not M[i, j]:&lt;br /&gt;
                continue&lt;br /&gt;
            n_pts_in_cluster += 1&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                c[j, k] += u[i, k]&lt;br /&gt;
&lt;br /&gt;
        # нормализация центроида&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c[j, k] /= n_pts_in_cluster&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На каждой итерации основного цикла алгоритма:&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; операций вычисления квадратов расстояний до центров кластеров: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; разностей, возведеий в квадрат и &amp;lt;math&amp;gt;NC(D-1)&amp;lt;/math&amp;gt; сумм&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
* Шаг 3 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; сложений&lt;br /&gt;
* Шаг 4 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; векторных умножений на скаляр, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; сложений: &amp;lt;math&amp;gt;ND+C&amp;lt;/math&amp;gt; сложений и &amp;lt;math&amp;gt;CD&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
Итого, одна итерация основного цикла стоит &amp;lt;math&amp;gt;O(3NCD)&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;
&#039;&#039;&#039;Группа 1&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;d(p,c)&amp;lt;/math&amp;gt;, выделена зелёным цветом.&lt;br /&gt;
Отвечает за вычисление расстояний между точками &amp;lt;math&amp;gt;p, u_i&amp;lt;/math&amp;gt; и центроидами &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt;. Расстояния вычисляются независимо как по точкам, так и по центроидам. Несмотря на независимость вычислений, их следует группировать по точкам, так как в дальнейшем результатов (расстояния до центров) будут аггрерироваться по точкам (операция &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 2&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;, выделена жёлтым цветом.&lt;br /&gt;
Отвечает за поиск ближайшего центроида до данной точки (при уже вычисленных расстояниях). Фактически, применяет паттерн Reduce с участием ассоциативной операцией &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;. Находит как индекс ближайшего центроида (используется для обновления матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;), так и расстояние до него (входит в сумму &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 3&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, выделена красным цветом. Обновляет значения матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; для каждой точки. Индикатор, соответствующий старому центроиду обнуляется, а новому - выставляется 1.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 4&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;J sum&amp;lt;/math&amp;gt;, выделена сиреневым цветом.&lt;br /&gt;
Осуществляет суммирование расстояний до ближайших центроидов. Применение паттерна Reduce с участием операции &amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 5&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;upd c&amp;lt;/math&amp;gt;, выделена синим цветом. Обновляет координаты центроидов. Для каждого центроида &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; перебираются все точки &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;M[c, p] = 1&amp;lt;/math&amp;gt;. Координаты таких точек суммируются (независимо покоординатно), возможно, с применением паттерна Reduce по точкам. Так же заводятся счётчики: сколько точек принадлежит кластеру с данным центроидом. Затем покоординатно производится нормировка.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:HCM_IG.png|thumb|800px|center| Информационный граф алгоритма. Здесь &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - точки &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерного пространства, соответствующие исследуемым объектам (входные данные); &amp;lt;math&amp;gt;d(p,c)&amp;lt;/math&amp;gt; вычисление расстояний от точки то центров; &amp;lt;math&amp;gt;\arg\,\min&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;; &amp;lt;math&amp;gt;J, J_{sum}&amp;lt;/math&amp;gt; вычисление и аггрерирование функционала оптимизации; &amp;lt;math&amp;gt;upd 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;
В первой (зелёной) группе необходимо вычислить &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; расстояний. Каждое вычисление расстояния сопоставляется вычислению &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; покоординатных расстояний с последующим суммированием. Ширина ЯПФ &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log D)&amp;lt;/math&amp;gt;. Отметим, что на практике суммрование сдваиванием может не быть самой оптимальной стратегией из-за оверхеда на обеспечение синхронизации: выходом может быть тоже иерархический паттерн Reduce, но арргерирующий больше двух результатов на одной вычислительной единице. Асимптотическая высота такого паттерна так же &amp;lt;math&amp;gt;O(\log NC)&amp;lt;/math&amp;gt;. При достаточно малых значениях &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; оптимальная стратения может выродится в цикл на одной вычислительной единице.&lt;br /&gt;
&lt;br /&gt;
Во второй группе (желтой) по каждой из &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; точек проводится &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt;-аггрегация &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; результатов. Таким образом, ширина ЯПФ &amp;lt;math&amp;gt;O(NC)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В третьей (красной) группе всё примитивно. &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; событий по опусканию одного и поднятию другого флага. Ширина &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В четвёртой (сиреневой) группе: SUM-аггрерация &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; результатов. Ширина ЯПФ &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В пятой (синей) группе: по каждому из &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; центроидов независимо покоординатно (&amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; координат) надо найти сумму произведений &amp;lt;math&amp;gt;u_{ik} \cdot M_{ij}&amp;lt;/math&amp;gt;. Так же надо завести счётчик. Ширина ЯПФ &amp;lt;math&amp;gt;O(C(D+1)N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N + 1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итого, ширина ЯПФ алгоритма &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N + \log C)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_k \}_{k=1}^N \subset \mathbb{R}^D&amp;lt;/math&amp;gt; — исходный набор точек признакового пространства.&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — количество кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;criteria\, params&amp;lt;/math&amp;gt; — параметры критерия останова.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;ND + const&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;M \in \mathbb{R}^{N \times C} &amp;lt;/math&amp;gt; — рядовая матрица&lt;br /&gt;
* &amp;lt;math&amp;gt;\{c_k\}_{k=1}^C&amp;lt;/math&amp;gt; — координаты кластерных центров&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;C(N+D)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Назначение:&#039;&#039;&#039; кластеризация больших наборов числовых данных  представленных признаковыми описаниями объектов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Достоинства:&#039;&#039;&#039;&lt;br /&gt;
* лёгкость реализации&lt;br /&gt;
* вычислительная простота&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки:&#039;&#039;&#039;&lt;br /&gt;
* явное задание количества кластеров&lt;br /&gt;
* отсутствие гарантии нахождения оптимального решения&lt;br /&gt;
* чувствительность к начальному приближению координат кластерных центров&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt; и параллельной &amp;lt;math&amp;gt;(\log N + \log C)&amp;lt;/math&amp;gt; сложности в случае неограниченных ресурсов сублинейна по &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (по количеству объектов и кластеров), линейна по &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; (по размерности признакового пространства).&lt;br /&gt;
&lt;br /&gt;
Вычислительная мощность, как отношение числа операций к суммарному объёму входных и выходных данных, &#039;&#039;линейна&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм детерменирован при явном задании начального приближения для центроидов. Алгоритм чувствителен к выбору начального приближения.&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
Для проверки масштабируемости алгоритма была создана собственная реализация алгоритма&amp;lt;ref&amp;gt;https://github.com/urandon/hcm_tbb&amp;lt;/ref&amp;gt; с использованием фреймворка Intel® Threading Building Blocks &amp;lt;ref&amp;gt;https://www.threadingbuildingblocks.org/&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Хотя реализация имеет ряд ограничений для полноценной оценки масштабируемости: предполагается запуск на одной машине используя мультитрединг -- всё же она может дать интерпретируемые результаты.&lt;br /&gt;
&lt;br /&gt;
Используемый компилятор: оптимизирующий компилятор Microsoft® С/C++ версии 19.00.24215.1. Процессор: Intel Core i7-3157U (2 ядра, 4 потока).&lt;br /&gt;
&lt;br /&gt;
Решалась задача в 128-мерном пространстве с поиском 10 кластеров.&lt;br /&gt;
Результаты тестов:&lt;br /&gt;
{|border = &amp;quot;1&amp;quot;&lt;br /&gt;
! № объектов \ № потоков&lt;br /&gt;
! 1&lt;br /&gt;
! 2&lt;br /&gt;
! 4&lt;br /&gt;
|-&lt;br /&gt;
!100&lt;br /&gt;
|165ms&lt;br /&gt;
|89ms&lt;br /&gt;
|49ms&lt;br /&gt;
|-&lt;br /&gt;
!1000&lt;br /&gt;
|1612ms&lt;br /&gt;
|886ms&lt;br /&gt;
|485ms&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Так как ресурсы тестовой системы сильно лимитированы, то получить сложность &amp;lt;math&amp;gt;O(\log N + \log 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;
1) [http://projects.jasmeet.me/2013/03/HardCMeans.html Matlab, последовательная реализация]&lt;br /&gt;
&lt;br /&gt;
2) [https://github.com/artpar/Hard-Clustering-implementation С++, последовательная реализация ]&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=22482</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=22482"/>
		<updated>2017-02-08T20:03:27Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор описания [[Участник:Urandon|Хомутов Никита]]&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;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
Целевая функция алгоритма полностью аналогична целевой функции K-Means[https://ru.wikipedia.org/wiki/K-means].&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \qquad \forall j \neq i \\&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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
Данная операция сводится к использованию ассоциативной &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt; и паттерна Reduse&amp;lt;ref&amp;gt;Reduce paralle pattern [http://www.drdobbs.com/architecture-and-design/parallel-pattern-7-reduce/222000718]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
Последовательная схема реализована в виде python-подобного псевдокода. Для оптимизации вычислений хранится структура, хранящая номер кластера для каждой точки. Это оптимизация с учётом разреженности матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# Инициализация&lt;br /&gt;
J_history = []&lt;br /&gt;
# центроиды выбираются случайно среди объектов&lt;br /&gt;
c = u[random.choice(N, C), :] &lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
# хранилище индексов кластеров для каждого объекта&lt;br /&gt;
# используется для обновления ранговой матрицы M&lt;br /&gt;
clusterization = zeros(N) &lt;br /&gt;
&lt;br /&gt;
# Основной цикл оптимизации&lt;br /&gt;
# повторяем его пока не сработает критерий останова&lt;br /&gt;
# предполагаем, что критерий использует значения&lt;br /&gt;
# функционала качества кластеризации&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
&lt;br /&gt;
    # Оптимизация матрицы M&lt;br /&gt;
    # при фиксированных центроидах&lt;br /&gt;
    # пообъектный цикл&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        # вычисляем расстояния до кластеров&lt;br /&gt;
        # находим минимальный&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
        # добавляем расстояние до ближайшего &lt;br /&gt;
        # кластера к фунционалу качества кластеризации&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
&lt;br /&gt;
        # обнуление старого соответствия объекта кластеру&lt;br /&gt;
        # передача соответствия новому кластеру&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, clusterization[i]] = 1&lt;br /&gt;
 &lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    # Оптимизация центроидов при &lt;br /&gt;
    # фиксированной ранговой матрице&lt;br /&gt;
    # покластерный цикл&lt;br /&gt;
    c = zeros(N, C)&lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        # заводим счётчик, сколько объектов в кластере&lt;br /&gt;
        # он далее будет использоваться для&lt;br /&gt;
        # нормализации центроида&lt;br /&gt;
        n_pts_in_cluster = 0&lt;br /&gt;
&lt;br /&gt;
        for i in range(N):&lt;br /&gt;
            # складываем центроид покоординатно только&lt;br /&gt;
            # с точками, принадлежащими кластеру&lt;br /&gt;
            if not M[i, j]:&lt;br /&gt;
                continue&lt;br /&gt;
            n_pts_in_cluster += 1&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                c[j, k] += u[i, k]&lt;br /&gt;
&lt;br /&gt;
        # нормализация центроида&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c[j, k] /= n_pts_in_cluster&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На каждой итерации основного цикла алгоритма:&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; операций вычисления квадратов расстояний до центров кластеров: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; разностей, возведеий в квадрат и &amp;lt;math&amp;gt;NC(D-1)&amp;lt;/math&amp;gt; сумм&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
* Шаг 3 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; сложений&lt;br /&gt;
* Шаг 4 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; векторных умножений на скаляр, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; сложений: &amp;lt;math&amp;gt;ND+C&amp;lt;/math&amp;gt; сложений и &amp;lt;math&amp;gt;CD&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
Итого, одна итерация основного цикла стоит &amp;lt;math&amp;gt;O(3NCD)&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;
&#039;&#039;&#039;Группа 1&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;d(p,c)&amp;lt;/math&amp;gt;, выделена зелёным цветом.&lt;br /&gt;
Отвечает за вычисление расстояний между точками &amp;lt;math&amp;gt;p, u_i&amp;lt;/math&amp;gt; и центроидами &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt;. Расстояния вычисляются независимо как по точкам, так и по центроидам. Несмотря на независимость вычислений, их следует группировать по точкам, так как в дальнейшем результатов (расстояния до центров) будут аггрерироваться по точкам (операция &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 2&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;, выделена жёлтым цветом.&lt;br /&gt;
Отвечает за поиск ближайшего центроида до данной точки (при уже вычисленных расстояниях). Фактически, применяет паттерн Reduce с участием ассоциативной операцией &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;. Находит как индекс ближайшего центроида (используется для обновления матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;), так и расстояние до него (входит в сумму &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 3&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, выделена красным цветом. Обновляет значения матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; для каждой точки. Индикатор, соответствующий старому центроиду обнуляется, а новому - выставляется 1.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 4&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;J sum&amp;lt;/math&amp;gt;, выделена сиреневым цветом.&lt;br /&gt;
Осуществляет суммирование расстояний до ближайших центроидов. Применение паттерна Reduce с участием операции &amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 5&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;upd c&amp;lt;/math&amp;gt;, выделена синим цветом. Обновляет координаты центроидов. Для каждого центроида &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; перебираются все точки &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;M[c, p] = 1&amp;lt;/math&amp;gt;. Координаты таких точек суммируются (независимо покоординатно), возможно, с применением паттерна Reduce по точкам. Так же заводятся счётчики: сколько точек принадлежит кластеру с данным центроидом. Затем покоординатно производится нормировка.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:HCM_IG.png|thumb|800px|center| Информационный граф алгоритма. Здесь &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - точки &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерного пространства, соответствующие исследуемым объектам (входные данные); &amp;lt;math&amp;gt;d(p,c)&amp;lt;/math&amp;gt; вычисление расстояний от точки то центров; &amp;lt;math&amp;gt;\arg\,\min&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;; &amp;lt;math&amp;gt;J, J_{sum}&amp;lt;/math&amp;gt; вычисление и аггрерирование функционала оптимизации; &amp;lt;math&amp;gt;upd 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;
В первой (зелёной) группе необходимо вычислить &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; расстояний. Каждое вычисление расстояния сопоставляется вычислению &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; покоординатных расстояний с последующим суммированием. Ширина ЯПФ &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log D)&amp;lt;/math&amp;gt;. Отметим, что на практике суммрование сдваиванием может не быть самой оптимальной стратегией из-за оверхеда на обеспечение синхронизации: выходом может быть тоже иерархический паттерн Reduce, но арргерирующий больше двух результатов на одной вычислительной единице. Асимптотическая высота такого паттерна так же &amp;lt;math&amp;gt;O(\log NC)&amp;lt;/math&amp;gt;. При достаточно малых значениях &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; оптимальная стратения может выродится в цикл на одной вычислительной единице.&lt;br /&gt;
&lt;br /&gt;
Во второй группе (желтой) по каждой из &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; точек проводится &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt;-аггрегация &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; результатов. Таким образом, ширина ЯПФ &amp;lt;math&amp;gt;O(NC)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В третьей (красной) группе всё примитивно. &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; событий по опусканию одного и поднятию другого флага. Ширина &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В четвёртой (сиреневой) группе: SUM-аггрерация &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; результатов. Ширина ЯПФ &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В пятой (синей) группе: по каждому из &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; центроидов независимо покоординатно (&amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; координат) надо найти сумму произведений &amp;lt;math&amp;gt;u_{ik} \cdot M_{ij}&amp;lt;/math&amp;gt;. Так же надо завести счётчик. Ширина ЯПФ &amp;lt;math&amp;gt;O(C(D+1)N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N + 1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итого, ширина ЯПФ алгоритма &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N + \log C)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_k \}_{k=1}^N \subset \mathbb{R}^D&amp;lt;/math&amp;gt; — исходный набор точек признакового пространства.&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — количество кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;criteria\, params&amp;lt;/math&amp;gt; — параметры критерия останова.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;ND + const&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;M \in \mathbb{R}^{N \times C} &amp;lt;/math&amp;gt; — рядовая матрица&lt;br /&gt;
* &amp;lt;math&amp;gt;\{c_k\}_{k=1}^C&amp;lt;/math&amp;gt; — координаты кластерных центров&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;C(N+D)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Назначение:&#039;&#039;&#039; кластеризация больших наборов числовых данных  представленных признаковыми описаниями объектов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Достоинства:&#039;&#039;&#039;&lt;br /&gt;
* лёгкость реализации&lt;br /&gt;
* вычислительная простота&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки:&#039;&#039;&#039;&lt;br /&gt;
* явное задание количества кластеров&lt;br /&gt;
* отсутствие гарантии нахождения оптимального решения&lt;br /&gt;
* чувствительность к начальному приближению координат кластерных центров&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt; и параллельной &amp;lt;math&amp;gt;(\log N + \log C)&amp;lt;/math&amp;gt; сложности в случае неограниченных ресурсов сублинейна по &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (по количеству объектов и кластеров), линейна по &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; (по размерности признакового пространства).&lt;br /&gt;
&lt;br /&gt;
Вычислительная мощность, как отношение числа операций к суммарному объёму входных и выходных данных, &#039;&#039;линейна&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм детерменирован при явном задании начального приближения для центроидов. Алгоритм чувствителен к выбору начального приближения.&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
Для проверки масштабируемости алгоритма была создана собственная реализация алгоритма&amp;lt;ref&amp;gt;https://github.com/urandon/hcm_tbb&amp;lt;/ref&amp;gt; с использованием фреймворка Intel® Threading Building Blocks &amp;lt;ref&amp;gt;https://www.threadingbuildingblocks.org/&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Хотя реализация имеет ряд ограничений для полноценной оценки масштабируемости: предполагается запуск на одной машине используя мультитрединг -- всё же она может дать интерпретируемые результаты.&lt;br /&gt;
&lt;br /&gt;
Используемый компилятор: оптимизирующий компилятор Microsoft® С/C++ версии 19.00.24215.1. Процессор: Intel Core i7-3157U (2 ядра, 4 потока).&lt;br /&gt;
&lt;br /&gt;
Решалась задача в 128-мерном пространстве с поиском 10 кластеров.&lt;br /&gt;
Результаты тестов:&lt;br /&gt;
{|border = &amp;quot;1&amp;quot;&lt;br /&gt;
! № объектов \ № потоков&lt;br /&gt;
! 1&lt;br /&gt;
! 2&lt;br /&gt;
! 4&lt;br /&gt;
|-&lt;br /&gt;
!100&lt;br /&gt;
|165ms&lt;br /&gt;
|89ms&lt;br /&gt;
|49ms&lt;br /&gt;
|-&lt;br /&gt;
!1000&lt;br /&gt;
|1612ms&lt;br /&gt;
|886ms&lt;br /&gt;
|485ms&lt;br /&gt;
|-&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Так как ресурсы тестовой системы сильно лимитированы, то получить сложность $O(\log N + \log C)$ и не удалось бы: распараллелены только покоординатные операции. Видно, что покоординатное распараллеливание даёт реальное ускорение в рамках столь ограниченной системы.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
1) [http://projects.jasmeet.me/2013/03/HardCMeans.html Matlab, последовательная реализация]&lt;br /&gt;
&lt;br /&gt;
2) [https://github.com/artpar/Hard-Clustering-implementation С++, последовательная реализация ]&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=22480</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=22480"/>
		<updated>2017-02-08T19:57:31Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Программная реализация алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор описания [[Участник:Urandon|Хомутов Никита]]&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;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
Целевая функция алгоритма полностью аналогична целевой функции K-Means[https://ru.wikipedia.org/wiki/K-means].&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \qquad \forall j \neq i \\&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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
Данная операция сводится к использованию ассоциативной &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt; и паттерна Reduse&amp;lt;ref&amp;gt;Reduce paralle pattern [http://www.drdobbs.com/architecture-and-design/parallel-pattern-7-reduce/222000718]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
Последовательная схема реализована в виде python-подобного псевдокода. Для оптимизации вычислений хранится структура, хранящая номер кластера для каждой точки. Это оптимизация с учётом разреженности матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# Инициализация&lt;br /&gt;
J_history = []&lt;br /&gt;
# центроиды выбираются случайно среди объектов&lt;br /&gt;
c = u[random.choice(N, C), :] &lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
# хранилище индексов кластеров для каждого объекта&lt;br /&gt;
# используется для обновления ранговой матрицы M&lt;br /&gt;
clusterization = zeros(N) &lt;br /&gt;
&lt;br /&gt;
# Основной цикл оптимизации&lt;br /&gt;
# повторяем его пока не сработает критерий останова&lt;br /&gt;
# предполагаем, что критерий использует значения&lt;br /&gt;
# функционала качества кластеризации&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
&lt;br /&gt;
    # Оптимизация матрицы M&lt;br /&gt;
    # при фиксированных центроидах&lt;br /&gt;
    # пообъектный цикл&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        # вычисляем расстояния до кластеров&lt;br /&gt;
        # находим минимальный&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
        # добавляем расстояние до ближайшего &lt;br /&gt;
        # кластера к фунционалу качества кластеризации&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
&lt;br /&gt;
        # обнуление старого соответствия объекта кластеру&lt;br /&gt;
        # передача соответствия новому кластеру&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, clusterization[i]] = 1&lt;br /&gt;
 &lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    # Оптимизация центроидов при &lt;br /&gt;
    # фиксированной ранговой матрице&lt;br /&gt;
    # покластерный цикл&lt;br /&gt;
    c = zeros(N, C)&lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        # заводим счётчик, сколько объектов в кластере&lt;br /&gt;
        # он далее будет использоваться для&lt;br /&gt;
        # нормализации центроида&lt;br /&gt;
        n_pts_in_cluster = 0&lt;br /&gt;
&lt;br /&gt;
        for i in range(N):&lt;br /&gt;
            # складываем центроид покоординатно только&lt;br /&gt;
            # с точками, принадлежащими кластеру&lt;br /&gt;
            if not M[i, j]:&lt;br /&gt;
                continue&lt;br /&gt;
            n_pts_in_cluster += 1&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                c[j, k] += u[i, k]&lt;br /&gt;
&lt;br /&gt;
        # нормализация центроида&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c[j, k] /= n_pts_in_cluster&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На каждой итерации основного цикла алгоритма:&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; операций вычисления квадратов расстояний до центров кластеров: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; разностей, возведеий в квадрат и &amp;lt;math&amp;gt;NC(D-1)&amp;lt;/math&amp;gt; сумм&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
* Шаг 3 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; сложений&lt;br /&gt;
* Шаг 4 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; векторных умножений на скаляр, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; сложений: &amp;lt;math&amp;gt;ND+C&amp;lt;/math&amp;gt; сложений и &amp;lt;math&amp;gt;CD&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
Итого, одна итерация основного цикла стоит &amp;lt;math&amp;gt;O(3NCD)&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;
&#039;&#039;&#039;Группа 1&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;d(p,c)&amp;lt;/math&amp;gt;, выделена зелёным цветом.&lt;br /&gt;
Отвечает за вычисление расстояний между точками &amp;lt;math&amp;gt;p, u_i&amp;lt;/math&amp;gt; и центроидами &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt;. Расстояния вычисляются независимо как по точкам, так и по центроидам. Несмотря на независимость вычислений, их следует группировать по точкам, так как в дальнейшем результатов (расстояния до центров) будут аггрерироваться по точкам (операция &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 2&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;, выделена жёлтым цветом.&lt;br /&gt;
Отвечает за поиск ближайшего центроида до данной точки (при уже вычисленных расстояниях). Фактически, применяет паттерн Reduce с участием ассоциативной операцией &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;. Находит как индекс ближайшего центроида (используется для обновления матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;), так и расстояние до него (входит в сумму &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 3&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, выделена красным цветом. Обновляет значения матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; для каждой точки. Индикатор, соответствующий старому центроиду обнуляется, а новому - выставляется 1.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 4&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;J sum&amp;lt;/math&amp;gt;, выделена сиреневым цветом.&lt;br /&gt;
Осуществляет суммирование расстояний до ближайших центроидов. Применение паттерна Reduce с участием операции &amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 5&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;upd c&amp;lt;/math&amp;gt;, выделена синим цветом. Обновляет координаты центроидов. Для каждого центроида &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; перебираются все точки &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;M[c, p] = 1&amp;lt;/math&amp;gt;. Координаты таких точек суммируются (независимо покоординатно), возможно, с применением паттерна Reduce по точкам. Так же заводятся счётчики: сколько точек принадлежит кластеру с данным центроидом. Затем покоординатно производится нормировка.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:HCM_IG.png|thumb|800px|center| Информационный граф алгоритма. Здесь &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - точки &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерного пространства, соответствующие исследуемым объектам (входные данные); &amp;lt;math&amp;gt;d(p,c)&amp;lt;/math&amp;gt; вычисление расстояний от точки то центров; &amp;lt;math&amp;gt;\arg\,\min&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;; &amp;lt;math&amp;gt;J, J_{sum}&amp;lt;/math&amp;gt; вычисление и аггрерирование функционала оптимизации; &amp;lt;math&amp;gt;upd 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;
В первой (зелёной) группе необходимо вычислить &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; расстояний. Каждое вычисление расстояния сопоставляется вычислению &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; покоординатных расстояний с последующим суммированием. Ширина ЯПФ &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log D)&amp;lt;/math&amp;gt;. Отметим, что на практике суммрование сдваиванием может не быть самой оптимальной стратегией из-за оверхеда на обеспечение синхронизации: выходом может быть тоже иерархический паттерн Reduce, но арргерирующий больше двух результатов на одной вычислительной единице. Асимптотическая высота такого паттерна так же &amp;lt;math&amp;gt;O(\log NC)&amp;lt;/math&amp;gt;. При достаточно малых значениях &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; оптимальная стратения может выродится в цикл на одной вычислительной единице.&lt;br /&gt;
&lt;br /&gt;
Во второй группе (желтой) по каждой из &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; точек проводится &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt;-аггрегация &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; результатов. Таким образом, ширина ЯПФ &amp;lt;math&amp;gt;O(NC)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В третьей (красной) группе всё примитивно. &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; событий по опусканию одного и поднятию другого флага. Ширина &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В четвёртой (сиреневой) группе: SUM-аггрерация &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; результатов. Ширина ЯПФ &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В пятой (синей) группе: по каждому из &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; центроидов независимо покоординатно (&amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; координат) надо найти сумму произведений &amp;lt;math&amp;gt;u_{ik} \cdot M_{ij}&amp;lt;/math&amp;gt;. Так же надо завести счётчик. Ширина ЯПФ &amp;lt;math&amp;gt;O(C(D+1)N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N + 1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итого, ширина ЯПФ алгоритма &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N + \log C)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_k \}_{k=1}^N \subset \mathbb{R}^D&amp;lt;/math&amp;gt; — исходный набор точек признакового пространства.&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — количество кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;criteria\, params&amp;lt;/math&amp;gt; — параметры критерия останова.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;ND + const&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;M \in \mathbb{R}^{N \times C} &amp;lt;/math&amp;gt; — рядовая матрица&lt;br /&gt;
* &amp;lt;math&amp;gt;\{c_k\}_{k=1}^C&amp;lt;/math&amp;gt; — координаты кластерных центров&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;C(N+D)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Назначение:&#039;&#039;&#039; кластеризация больших наборов числовых данных  представленных признаковыми описаниями объектов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Достоинства:&#039;&#039;&#039;&lt;br /&gt;
* лёгкость реализации&lt;br /&gt;
* вычислительная простота&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки:&#039;&#039;&#039;&lt;br /&gt;
* явное задание количества кластеров&lt;br /&gt;
* отсутствие гарантии нахождения оптимального решения&lt;br /&gt;
* чувствительность к начальному приближению координат кластерных центров&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt; и параллельной &amp;lt;math&amp;gt;(\log N + \log C)&amp;lt;/math&amp;gt; сложности в случае неограниченных ресурсов сублинейна по &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (по количеству объектов и кластеров), линейна по &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; (по размерности признакового пространства).&lt;br /&gt;
&lt;br /&gt;
Вычислительная мощность, как отношение числа операций к суммарному объёму входных и выходных данных, &#039;&#039;линейна&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм детерменирован при явном задании начального приближения для центроидов. Алгоритм чувствителен к выбору начального приближения.&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
Для проверки масштабируемости алгоритма была создана собственная реализация алгоритма&amp;lt;ref&amp;gt;https://github.com/urandon/hcm_tbb&amp;lt;/ref&amp;gt; с использованием фреймворка Intel® Threading Building Blocks &amp;lt;ref&amp;gt;https://www.threadingbuildingblocks.org/&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Хотя реализация имеет ряд ограничений для полноценной оценки масштабируемости: предполагается запуск на одной машине используя мультитрединг -- всё же она может дать интерпретируемые результаты.&lt;br /&gt;
&lt;br /&gt;
Используемый компилятор: оптимизирующий компилятор Microsoft® С/C++ версии 19.00.24215.1. Процессор: Intel Core i7-3157U (2 ядра, 4 потока).&lt;br /&gt;
&lt;br /&gt;
Результаты тестов:&lt;br /&gt;
{|border = &amp;quot;1&amp;quot;&lt;br /&gt;
! № объектов \ № потоков ! 1 ! 2 ! 4&lt;br /&gt;
|-&lt;br /&gt;
!(100) | 165ms | 89ms | 60ms |&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
1) [http://projects.jasmeet.me/2013/03/HardCMeans.html Matlab, последовательная реализация]&lt;br /&gt;
&lt;br /&gt;
2) [https://github.com/artpar/Hard-Clustering-implementation С++, последовательная реализация ]&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=22478</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=22478"/>
		<updated>2017-02-08T19:19:50Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Схема реализации последовательного алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор описания [[Участник:Urandon|Хомутов Никита]]&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;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
Целевая функция алгоритма полностью аналогична целевой функции K-Means[https://ru.wikipedia.org/wiki/K-means].&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \qquad \forall j \neq i \\&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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
Данная операция сводится к использованию ассоциативной &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt; и паттерна Reduse&amp;lt;ref&amp;gt;Reduce paralle pattern [http://www.drdobbs.com/architecture-and-design/parallel-pattern-7-reduce/222000718]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
Последовательная схема реализована в виде python-подобного псевдокода. Для оптимизации вычислений хранится структура, хранящая номер кластера для каждой точки. Это оптимизация с учётом разреженности матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# Инициализация&lt;br /&gt;
J_history = []&lt;br /&gt;
# центроиды выбираются случайно среди объектов&lt;br /&gt;
c = u[random.choice(N, C), :] &lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
# хранилище индексов кластеров для каждого объекта&lt;br /&gt;
# используется для обновления ранговой матрицы M&lt;br /&gt;
clusterization = zeros(N) &lt;br /&gt;
&lt;br /&gt;
# Основной цикл оптимизации&lt;br /&gt;
# повторяем его пока не сработает критерий останова&lt;br /&gt;
# предполагаем, что критерий использует значения&lt;br /&gt;
# функционала качества кластеризации&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
&lt;br /&gt;
    # Оптимизация матрицы M&lt;br /&gt;
    # при фиксированных центроидах&lt;br /&gt;
    # пообъектный цикл&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        # вычисляем расстояния до кластеров&lt;br /&gt;
        # находим минимальный&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
        # добавляем расстояние до ближайшего &lt;br /&gt;
        # кластера к фунционалу качества кластеризации&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
&lt;br /&gt;
        # обнуление старого соответствия объекта кластеру&lt;br /&gt;
        # передача соответствия новому кластеру&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, clusterization[i]] = 1&lt;br /&gt;
 &lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    # Оптимизация центроидов при &lt;br /&gt;
    # фиксированной ранговой матрице&lt;br /&gt;
    # покластерный цикл&lt;br /&gt;
    c = zeros(N, C)&lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        # заводим счётчик, сколько объектов в кластере&lt;br /&gt;
        # он далее будет использоваться для&lt;br /&gt;
        # нормализации центроида&lt;br /&gt;
        n_pts_in_cluster = 0&lt;br /&gt;
&lt;br /&gt;
        for i in range(N):&lt;br /&gt;
            # складываем центроид покоординатно только&lt;br /&gt;
            # с точками, принадлежащими кластеру&lt;br /&gt;
            if not M[i, j]:&lt;br /&gt;
                continue&lt;br /&gt;
            n_pts_in_cluster += 1&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                c[j, k] += u[i, k]&lt;br /&gt;
&lt;br /&gt;
        # нормализация центроида&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c[j, k] /= n_pts_in_cluster&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На каждой итерации основного цикла алгоритма:&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; операций вычисления квадратов расстояний до центров кластеров: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; разностей, возведеий в квадрат и &amp;lt;math&amp;gt;NC(D-1)&amp;lt;/math&amp;gt; сумм&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
* Шаг 3 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; сложений&lt;br /&gt;
* Шаг 4 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; векторных умножений на скаляр, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; сложений: &amp;lt;math&amp;gt;ND+C&amp;lt;/math&amp;gt; сложений и &amp;lt;math&amp;gt;CD&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
Итого, одна итерация основного цикла стоит &amp;lt;math&amp;gt;O(3NCD)&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;
&#039;&#039;&#039;Группа 1&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;d(p,c)&amp;lt;/math&amp;gt;, выделена зелёным цветом.&lt;br /&gt;
Отвечает за вычисление расстояний между точками &amp;lt;math&amp;gt;p, u_i&amp;lt;/math&amp;gt; и центроидами &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt;. Расстояния вычисляются независимо как по точкам, так и по центроидам. Несмотря на независимость вычислений, их следует группировать по точкам, так как в дальнейшем результатов (расстояния до центров) будут аггрерироваться по точкам (операция &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 2&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;, выделена жёлтым цветом.&lt;br /&gt;
Отвечает за поиск ближайшего центроида до данной точки (при уже вычисленных расстояниях). Фактически, применяет паттерн Reduce с участием ассоциативной операцией &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;. Находит как индекс ближайшего центроида (используется для обновления матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;), так и расстояние до него (входит в сумму &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 3&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, выделена красным цветом. Обновляет значения матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; для каждой точки. Индикатор, соответствующий старому центроиду обнуляется, а новому - выставляется 1.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 4&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;J sum&amp;lt;/math&amp;gt;, выделена сиреневым цветом.&lt;br /&gt;
Осуществляет суммирование расстояний до ближайших центроидов. Применение паттерна Reduce с участием операции &amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 5&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;upd c&amp;lt;/math&amp;gt;, выделена синим цветом. Обновляет координаты центроидов. Для каждого центроида &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; перебираются все точки &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;M[c, p] = 1&amp;lt;/math&amp;gt;. Координаты таких точек суммируются (независимо покоординатно), возможно, с применением паттерна Reduce по точкам. Так же заводятся счётчики: сколько точек принадлежит кластеру с данным центроидом. Затем покоординатно производится нормировка.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:HCM_IG.png|thumb|800px|center| Информационный граф алгоритма. Здесь &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - точки &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерного пространства, соответствующие исследуемым объектам (входные данные); &amp;lt;math&amp;gt;d(p,c)&amp;lt;/math&amp;gt; вычисление расстояний от точки то центров; &amp;lt;math&amp;gt;\arg\,\min&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;; &amp;lt;math&amp;gt;J, J_{sum}&amp;lt;/math&amp;gt; вычисление и аггрерирование функционала оптимизации; &amp;lt;math&amp;gt;upd 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;
В первой (зелёной) группе необходимо вычислить &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; расстояний. Каждое вычисление расстояния сопоставляется вычислению &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; покоординатных расстояний с последующим суммированием. Ширина ЯПФ &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log D)&amp;lt;/math&amp;gt;. Отметим, что на практике суммрование сдваиванием может не быть самой оптимальной стратегией из-за оверхеда на обеспечение синхронизации: выходом может быть тоже иерархический паттерн Reduce, но арргерирующий больше двух результатов на одной вычислительной единице. Асимптотическая высота такого паттерна так же &amp;lt;math&amp;gt;O(\log NC)&amp;lt;/math&amp;gt;. При достаточно малых значениях &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; оптимальная стратения может выродится в цикл на одной вычислительной единице.&lt;br /&gt;
&lt;br /&gt;
Во второй группе (желтой) по каждой из &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; точек проводится &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt;-аггрегация &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; результатов. Таким образом, ширина ЯПФ &amp;lt;math&amp;gt;O(NC)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В третьей (красной) группе всё примитивно. &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; событий по опусканию одного и поднятию другого флага. Ширина &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В четвёртой (сиреневой) группе: SUM-аггрерация &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; результатов. Ширина ЯПФ &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В пятой (синей) группе: по каждому из &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; центроидов независимо покоординатно (&amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; координат) надо найти сумму произведений &amp;lt;math&amp;gt;u_{ik} \cdot M_{ij}&amp;lt;/math&amp;gt;. Так же надо завести счётчик. Ширина ЯПФ &amp;lt;math&amp;gt;O(C(D+1)N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N + 1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итого, ширина ЯПФ алгоритма &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N + \log C)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_k \}_{k=1}^N \subset \mathbb{R}^D&amp;lt;/math&amp;gt; — исходный набор точек признакового пространства.&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — количество кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;criteria\, params&amp;lt;/math&amp;gt; — параметры критерия останова.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;ND + const&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;M \in \mathbb{R}^{N \times C} &amp;lt;/math&amp;gt; — рядовая матрица&lt;br /&gt;
* &amp;lt;math&amp;gt;\{c_k\}_{k=1}^C&amp;lt;/math&amp;gt; — координаты кластерных центров&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;C(N+D)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Назначение:&#039;&#039;&#039; кластеризация больших наборов числовых данных  представленных признаковыми описаниями объектов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Достоинства:&#039;&#039;&#039;&lt;br /&gt;
* лёгкость реализации&lt;br /&gt;
* вычислительная простота&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки:&#039;&#039;&#039;&lt;br /&gt;
* явное задание количества кластеров&lt;br /&gt;
* отсутствие гарантии нахождения оптимального решения&lt;br /&gt;
* чувствительность к начальному приближению координат кластерных центров&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt; и параллельной &amp;lt;math&amp;gt;(\log N + \log C)&amp;lt;/math&amp;gt; сложности в случае неограниченных ресурсов сублинейна по &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (по количеству объектов и кластеров), линейна по &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; (по размерности признакового пространства).&lt;br /&gt;
&lt;br /&gt;
Вычислительная мощность, как отношение числа операций к суммарному объёму входных и выходных данных, &#039;&#039;линейна&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм детерменирован при явном задании начального приближения для центроидов. Алгоритм чувствителен к выбору начального приближения.&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
Для демонстрации работы алгоритма была создана собственная реализация алгоритма&amp;lt;ref&amp;gt;https://github.com/urandon/hcm_tbb&amp;lt;/ref&amp;gt; с использованием фреймворка Intel® Threading Building Blocks &amp;lt;ref&amp;gt;https://www.threadingbuildingblocks.org/&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;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
1) [http://projects.jasmeet.me/2013/03/HardCMeans.html Matlab, последовательная реализация]&lt;br /&gt;
&lt;br /&gt;
2) [https://github.com/artpar/Hard-Clustering-implementation С++, последовательная реализация ]&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=22477</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=22477"/>
		<updated>2017-02-08T19:03:52Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Свойства алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор описания [[Участник:Urandon|Хомутов Никита]]&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;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
Целевая функция алгоритма полностью аналогична целевой функции K-Means[https://ru.wikipedia.org/wiki/K-means].&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \qquad \forall j \neq i \\&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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
Данная операция сводится к использованию ассоциативной &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt; и паттерна Reduse&amp;lt;ref&amp;gt;Reduce paralle pattern [http://www.drdobbs.com/architecture-and-design/parallel-pattern-7-reduce/222000718]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
Последовательная схема реализована в виде python-подобного псевдокода. Для оптимизации вычислений хранится структура, хранящая номер кластера для каждой точки. Это оптимизация с учётом разреженности матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
J_history = []&lt;br /&gt;
c = u[random.choice(N, C), :]&lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
clusterization = zeros(N) # sparse version of M&lt;br /&gt;
&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
&lt;br /&gt;
    # update M, J&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, clusterization[i]] = 1&lt;br /&gt;
 &lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
    # update C&lt;br /&gt;
    c = zeros(N, C)&lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        n_pts_in_cluster = 0&lt;br /&gt;
        for i in range(N):&lt;br /&gt;
            if not M[i, j]:&lt;br /&gt;
                continue&lt;br /&gt;
            n_pts_in_cluster += 1&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                c[j, k] += u[i, k]&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c[j, k] /= n_pts_in_cluster&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На каждой итерации основного цикла алгоритма:&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; операций вычисления квадратов расстояний до центров кластеров: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; разностей, возведеий в квадрат и &amp;lt;math&amp;gt;NC(D-1)&amp;lt;/math&amp;gt; сумм&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
* Шаг 3 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; сложений&lt;br /&gt;
* Шаг 4 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; векторных умножений на скаляр, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; сложений: &amp;lt;math&amp;gt;ND+C&amp;lt;/math&amp;gt; сложений и &amp;lt;math&amp;gt;CD&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
Итого, одна итерация основного цикла стоит &amp;lt;math&amp;gt;O(3NCD)&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;
&#039;&#039;&#039;Группа 1&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;d(p,c)&amp;lt;/math&amp;gt;, выделена зелёным цветом.&lt;br /&gt;
Отвечает за вычисление расстояний между точками &amp;lt;math&amp;gt;p, u_i&amp;lt;/math&amp;gt; и центроидами &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt;. Расстояния вычисляются независимо как по точкам, так и по центроидам. Несмотря на независимость вычислений, их следует группировать по точкам, так как в дальнейшем результатов (расстояния до центров) будут аггрерироваться по точкам (операция &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 2&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;, выделена жёлтым цветом.&lt;br /&gt;
Отвечает за поиск ближайшего центроида до данной точки (при уже вычисленных расстояниях). Фактически, применяет паттерн Reduce с участием ассоциативной операцией &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;. Находит как индекс ближайшего центроида (используется для обновления матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;), так и расстояние до него (входит в сумму &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 3&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, выделена красным цветом. Обновляет значения матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; для каждой точки. Индикатор, соответствующий старому центроиду обнуляется, а новому - выставляется 1.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 4&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;J sum&amp;lt;/math&amp;gt;, выделена сиреневым цветом.&lt;br /&gt;
Осуществляет суммирование расстояний до ближайших центроидов. Применение паттерна Reduce с участием операции &amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 5&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;upd c&amp;lt;/math&amp;gt;, выделена синим цветом. Обновляет координаты центроидов. Для каждого центроида &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; перебираются все точки &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;M[c, p] = 1&amp;lt;/math&amp;gt;. Координаты таких точек суммируются (независимо покоординатно), возможно, с применением паттерна Reduce по точкам. Так же заводятся счётчики: сколько точек принадлежит кластеру с данным центроидом. Затем покоординатно производится нормировка.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:HCM_IG.png|thumb|800px|center| Информационный граф алгоритма. Здесь &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - точки &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерного пространства, соответствующие исследуемым объектам (входные данные); &amp;lt;math&amp;gt;d(p,c)&amp;lt;/math&amp;gt; вычисление расстояний от точки то центров; &amp;lt;math&amp;gt;\arg\,\min&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;; &amp;lt;math&amp;gt;J, J_{sum}&amp;lt;/math&amp;gt; вычисление и аггрерирование функционала оптимизации; &amp;lt;math&amp;gt;upd 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;
В первой (зелёной) группе необходимо вычислить &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; расстояний. Каждое вычисление расстояния сопоставляется вычислению &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; покоординатных расстояний с последующим суммированием. Ширина ЯПФ &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log D)&amp;lt;/math&amp;gt;. Отметим, что на практике суммрование сдваиванием может не быть самой оптимальной стратегией из-за оверхеда на обеспечение синхронизации: выходом может быть тоже иерархический паттерн Reduce, но арргерирующий больше двух результатов на одной вычислительной единице. Асимптотическая высота такого паттерна так же &amp;lt;math&amp;gt;O(\log NC)&amp;lt;/math&amp;gt;. При достаточно малых значениях &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; оптимальная стратения может выродится в цикл на одной вычислительной единице.&lt;br /&gt;
&lt;br /&gt;
Во второй группе (желтой) по каждой из &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; точек проводится &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt;-аггрегация &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; результатов. Таким образом, ширина ЯПФ &amp;lt;math&amp;gt;O(NC)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В третьей (красной) группе всё примитивно. &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; событий по опусканию одного и поднятию другого флага. Ширина &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В четвёртой (сиреневой) группе: SUM-аггрерация &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; результатов. Ширина ЯПФ &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В пятой (синей) группе: по каждому из &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; центроидов независимо покоординатно (&amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; координат) надо найти сумму произведений &amp;lt;math&amp;gt;u_{ik} \cdot M_{ij}&amp;lt;/math&amp;gt;. Так же надо завести счётчик. Ширина ЯПФ &amp;lt;math&amp;gt;O(C(D+1)N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N + 1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итого, ширина ЯПФ алгоритма &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N + \log C)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_k \}_{k=1}^N \subset \mathbb{R}^D&amp;lt;/math&amp;gt; — исходный набор точек признакового пространства.&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — количество кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;criteria\, params&amp;lt;/math&amp;gt; — параметры критерия останова.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;ND + const&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;M \in \mathbb{R}^{N \times C} &amp;lt;/math&amp;gt; — рядовая матрица&lt;br /&gt;
* &amp;lt;math&amp;gt;\{c_k\}_{k=1}^C&amp;lt;/math&amp;gt; — координаты кластерных центров&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;C(N+D)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Назначение:&#039;&#039;&#039; кластеризация больших наборов числовых данных  представленных признаковыми описаниями объектов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Достоинства:&#039;&#039;&#039;&lt;br /&gt;
* лёгкость реализации&lt;br /&gt;
* вычислительная простота&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки:&#039;&#039;&#039;&lt;br /&gt;
* явное задание количества кластеров&lt;br /&gt;
* отсутствие гарантии нахождения оптимального решения&lt;br /&gt;
* чувствительность к начальному приближению координат кластерных центров&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt; и параллельной &amp;lt;math&amp;gt;(\log N + \log C)&amp;lt;/math&amp;gt; сложности в случае неограниченных ресурсов сублинейна по &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (по количеству объектов и кластеров), линейна по &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; (по размерности признакового пространства).&lt;br /&gt;
&lt;br /&gt;
Вычислительная мощность, как отношение числа операций к суммарному объёму входных и выходных данных, &#039;&#039;линейна&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм детерменирован при явном задании начального приближения для центроидов. Алгоритм чувствителен к выбору начального приближения.&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
Для демонстрации работы алгоритма была создана собственная реализация алгоритма&amp;lt;ref&amp;gt;https://github.com/urandon/hcm_tbb&amp;lt;/ref&amp;gt; с использованием фреймворка Intel® Threading Building Blocks &amp;lt;ref&amp;gt;https://www.threadingbuildingblocks.org/&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;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
1) [http://projects.jasmeet.me/2013/03/HardCMeans.html Matlab, последовательная реализация]&lt;br /&gt;
&lt;br /&gt;
2) [https://github.com/artpar/Hard-Clustering-implementation С++, последовательная реализация ]&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=22476</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=22476"/>
		<updated>2017-02-08T19:03:27Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Свойства алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор описания [[Участник:Urandon|Хомутов Никита]]&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;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
Целевая функция алгоритма полностью аналогична целевой функции K-Means[https://ru.wikipedia.org/wiki/K-means].&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \qquad \forall j \neq i \\&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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
Данная операция сводится к использованию ассоциативной &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt; и паттерна Reduse&amp;lt;ref&amp;gt;Reduce paralle pattern [http://www.drdobbs.com/architecture-and-design/parallel-pattern-7-reduce/222000718]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
Последовательная схема реализована в виде python-подобного псевдокода. Для оптимизации вычислений хранится структура, хранящая номер кластера для каждой точки. Это оптимизация с учётом разреженности матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
J_history = []&lt;br /&gt;
c = u[random.choice(N, C), :]&lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
clusterization = zeros(N) # sparse version of M&lt;br /&gt;
&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
&lt;br /&gt;
    # update M, J&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, clusterization[i]] = 1&lt;br /&gt;
 &lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
    # update C&lt;br /&gt;
    c = zeros(N, C)&lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        n_pts_in_cluster = 0&lt;br /&gt;
        for i in range(N):&lt;br /&gt;
            if not M[i, j]:&lt;br /&gt;
                continue&lt;br /&gt;
            n_pts_in_cluster += 1&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                c[j, k] += u[i, k]&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c[j, k] /= n_pts_in_cluster&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На каждой итерации основного цикла алгоритма:&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; операций вычисления квадратов расстояний до центров кластеров: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; разностей, возведеий в квадрат и &amp;lt;math&amp;gt;NC(D-1)&amp;lt;/math&amp;gt; сумм&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
* Шаг 3 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; сложений&lt;br /&gt;
* Шаг 4 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; векторных умножений на скаляр, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; сложений: &amp;lt;math&amp;gt;ND+C&amp;lt;/math&amp;gt; сложений и &amp;lt;math&amp;gt;CD&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
Итого, одна итерация основного цикла стоит &amp;lt;math&amp;gt;O(3NCD)&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;
&#039;&#039;&#039;Группа 1&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;d(p,c)&amp;lt;/math&amp;gt;, выделена зелёным цветом.&lt;br /&gt;
Отвечает за вычисление расстояний между точками &amp;lt;math&amp;gt;p, u_i&amp;lt;/math&amp;gt; и центроидами &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt;. Расстояния вычисляются независимо как по точкам, так и по центроидам. Несмотря на независимость вычислений, их следует группировать по точкам, так как в дальнейшем результатов (расстояния до центров) будут аггрерироваться по точкам (операция &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 2&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;, выделена жёлтым цветом.&lt;br /&gt;
Отвечает за поиск ближайшего центроида до данной точки (при уже вычисленных расстояниях). Фактически, применяет паттерн Reduce с участием ассоциативной операцией &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;. Находит как индекс ближайшего центроида (используется для обновления матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;), так и расстояние до него (входит в сумму &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 3&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, выделена красным цветом. Обновляет значения матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; для каждой точки. Индикатор, соответствующий старому центроиду обнуляется, а новому - выставляется 1.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 4&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;J sum&amp;lt;/math&amp;gt;, выделена сиреневым цветом.&lt;br /&gt;
Осуществляет суммирование расстояний до ближайших центроидов. Применение паттерна Reduce с участием операции &amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 5&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;upd c&amp;lt;/math&amp;gt;, выделена синим цветом. Обновляет координаты центроидов. Для каждого центроида &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; перебираются все точки &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;M[c, p] = 1&amp;lt;/math&amp;gt;. Координаты таких точек суммируются (независимо покоординатно), возможно, с применением паттерна Reduce по точкам. Так же заводятся счётчики: сколько точек принадлежит кластеру с данным центроидом. Затем покоординатно производится нормировка.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:HCM_IG.png|thumb|800px|center| Информационный граф алгоритма. Здесь &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - точки &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерного пространства, соответствующие исследуемым объектам (входные данные); &amp;lt;math&amp;gt;d(p,c)&amp;lt;/math&amp;gt; вычисление расстояний от точки то центров; &amp;lt;math&amp;gt;\arg\,\min&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;; &amp;lt;math&amp;gt;J, J_{sum}&amp;lt;/math&amp;gt; вычисление и аггрерирование функционала оптимизации; &amp;lt;math&amp;gt;upd 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;
В первой (зелёной) группе необходимо вычислить &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; расстояний. Каждое вычисление расстояния сопоставляется вычислению &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; покоординатных расстояний с последующим суммированием. Ширина ЯПФ &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log D)&amp;lt;/math&amp;gt;. Отметим, что на практике суммрование сдваиванием может не быть самой оптимальной стратегией из-за оверхеда на обеспечение синхронизации: выходом может быть тоже иерархический паттерн Reduce, но арргерирующий больше двух результатов на одной вычислительной единице. Асимптотическая высота такого паттерна так же &amp;lt;math&amp;gt;O(\log NC)&amp;lt;/math&amp;gt;. При достаточно малых значениях &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; оптимальная стратения может выродится в цикл на одной вычислительной единице.&lt;br /&gt;
&lt;br /&gt;
Во второй группе (желтой) по каждой из &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; точек проводится &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt;-аггрегация &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; результатов. Таким образом, ширина ЯПФ &amp;lt;math&amp;gt;O(NC)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В третьей (красной) группе всё примитивно. &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; событий по опусканию одного и поднятию другого флага. Ширина &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В четвёртой (сиреневой) группе: SUM-аггрерация &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; результатов. Ширина ЯПФ &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В пятой (синей) группе: по каждому из &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; центроидов независимо покоординатно (&amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; координат) надо найти сумму произведений &amp;lt;math&amp;gt;u_{ik} \cdot M_{ij}&amp;lt;/math&amp;gt;. Так же надо завести счётчик. Ширина ЯПФ &amp;lt;math&amp;gt;O(C(D+1)N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N + 1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итого, ширина ЯПФ алгоритма &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N + \log C)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_k \}_{k=1}^N \subset \mathbb{R}^D&amp;lt;/math&amp;gt; — исходный набор точек признакового пространства.&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — количество кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;criteria\, params&amp;lt;/math&amp;gt; — параметры критерия останова.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;ND + const&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;M \in \mathbb{R}^{N \times C} &amp;lt;/math&amp;gt; — рядовая матрица&lt;br /&gt;
* &amp;lt;math&amp;gt;\{c_k\}_{k=1}^C&amp;lt;/math&amp;gt; — координаты кластерных центров&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;C(N+D)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Назначение:&#039;&#039;&#039; кластеризация больших наборов числовых данных  представленных признаковыми описаниями объектов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Достоинства:&#039;&#039;&#039;&lt;br /&gt;
* лёгкость реализации&lt;br /&gt;
* вычислительная простота&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки:&#039;&#039;&#039;&lt;br /&gt;
* явное задание количества кластеров&lt;br /&gt;
* отсутствие гарантии нахождения оптимального решения&lt;br /&gt;
* чувствительность к начальному приближению координат кластерных центров&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной (&amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt;) и параллельной (&amp;lt;math&amp;gt;(\log N + \log C)&amp;lt;/math&amp;gt;) сложности в случае неограниченных ресурсов сублинейна по &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (по количеству объектов и кластеров), линейна по &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; (по размерности признакового пространства).&lt;br /&gt;
&lt;br /&gt;
Вычислительная мощность, как отношение числа операций к суммарному объёму входных и выходных данных, &#039;&#039;линейна&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм детерменирован при явном задании начального приближения для центроидов. Алгоритм чувствителен к выбору начального приближения.&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
Для демонстрации работы алгоритма была создана собственная реализация алгоритма&amp;lt;ref&amp;gt;https://github.com/urandon/hcm_tbb&amp;lt;/ref&amp;gt; с использованием фреймворка Intel® Threading Building Blocks &amp;lt;ref&amp;gt;https://www.threadingbuildingblocks.org/&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;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
1) [http://projects.jasmeet.me/2013/03/HardCMeans.html Matlab, последовательная реализация]&lt;br /&gt;
&lt;br /&gt;
2) [https://github.com/artpar/Hard-Clustering-implementation С++, последовательная реализация ]&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=22475</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=22475"/>
		<updated>2017-02-08T19:02:44Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Свойства алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор описания [[Участник:Urandon|Хомутов Никита]]&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;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
Целевая функция алгоритма полностью аналогична целевой функции K-Means[https://ru.wikipedia.org/wiki/K-means].&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \qquad \forall j \neq i \\&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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
Данная операция сводится к использованию ассоциативной &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt; и паттерна Reduse&amp;lt;ref&amp;gt;Reduce paralle pattern [http://www.drdobbs.com/architecture-and-design/parallel-pattern-7-reduce/222000718]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
Последовательная схема реализована в виде python-подобного псевдокода. Для оптимизации вычислений хранится структура, хранящая номер кластера для каждой точки. Это оптимизация с учётом разреженности матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
J_history = []&lt;br /&gt;
c = u[random.choice(N, C), :]&lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
clusterization = zeros(N) # sparse version of M&lt;br /&gt;
&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
&lt;br /&gt;
    # update M, J&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, clusterization[i]] = 1&lt;br /&gt;
 &lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
    # update C&lt;br /&gt;
    c = zeros(N, C)&lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        n_pts_in_cluster = 0&lt;br /&gt;
        for i in range(N):&lt;br /&gt;
            if not M[i, j]:&lt;br /&gt;
                continue&lt;br /&gt;
            n_pts_in_cluster += 1&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                c[j, k] += u[i, k]&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c[j, k] /= n_pts_in_cluster&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На каждой итерации основного цикла алгоритма:&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; операций вычисления квадратов расстояний до центров кластеров: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; разностей, возведеий в квадрат и &amp;lt;math&amp;gt;NC(D-1)&amp;lt;/math&amp;gt; сумм&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
* Шаг 3 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; сложений&lt;br /&gt;
* Шаг 4 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; векторных умножений на скаляр, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; сложений: &amp;lt;math&amp;gt;ND+C&amp;lt;/math&amp;gt; сложений и &amp;lt;math&amp;gt;CD&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
Итого, одна итерация основного цикла стоит &amp;lt;math&amp;gt;O(3NCD)&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;
&#039;&#039;&#039;Группа 1&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;d(p,c)&amp;lt;/math&amp;gt;, выделена зелёным цветом.&lt;br /&gt;
Отвечает за вычисление расстояний между точками &amp;lt;math&amp;gt;p, u_i&amp;lt;/math&amp;gt; и центроидами &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt;. Расстояния вычисляются независимо как по точкам, так и по центроидам. Несмотря на независимость вычислений, их следует группировать по точкам, так как в дальнейшем результатов (расстояния до центров) будут аггрерироваться по точкам (операция &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 2&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;, выделена жёлтым цветом.&lt;br /&gt;
Отвечает за поиск ближайшего центроида до данной точки (при уже вычисленных расстояниях). Фактически, применяет паттерн Reduce с участием ассоциативной операцией &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;. Находит как индекс ближайшего центроида (используется для обновления матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;), так и расстояние до него (входит в сумму &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 3&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, выделена красным цветом. Обновляет значения матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; для каждой точки. Индикатор, соответствующий старому центроиду обнуляется, а новому - выставляется 1.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 4&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;J sum&amp;lt;/math&amp;gt;, выделена сиреневым цветом.&lt;br /&gt;
Осуществляет суммирование расстояний до ближайших центроидов. Применение паттерна Reduce с участием операции &amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 5&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;upd c&amp;lt;/math&amp;gt;, выделена синим цветом. Обновляет координаты центроидов. Для каждого центроида &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; перебираются все точки &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;M[c, p] = 1&amp;lt;/math&amp;gt;. Координаты таких точек суммируются (независимо покоординатно), возможно, с применением паттерна Reduce по точкам. Так же заводятся счётчики: сколько точек принадлежит кластеру с данным центроидом. Затем покоординатно производится нормировка.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:HCM_IG.png|thumb|800px|center| Информационный граф алгоритма. Здесь &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - точки &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерного пространства, соответствующие исследуемым объектам (входные данные); &amp;lt;math&amp;gt;d(p,c)&amp;lt;/math&amp;gt; вычисление расстояний от точки то центров; &amp;lt;math&amp;gt;\arg\,\min&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;; &amp;lt;math&amp;gt;J, J_{sum}&amp;lt;/math&amp;gt; вычисление и аггрерирование функционала оптимизации; &amp;lt;math&amp;gt;upd 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;
В первой (зелёной) группе необходимо вычислить &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; расстояний. Каждое вычисление расстояния сопоставляется вычислению &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; покоординатных расстояний с последующим суммированием. Ширина ЯПФ &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log D)&amp;lt;/math&amp;gt;. Отметим, что на практике суммрование сдваиванием может не быть самой оптимальной стратегией из-за оверхеда на обеспечение синхронизации: выходом может быть тоже иерархический паттерн Reduce, но арргерирующий больше двух результатов на одной вычислительной единице. Асимптотическая высота такого паттерна так же &amp;lt;math&amp;gt;O(\log NC)&amp;lt;/math&amp;gt;. При достаточно малых значениях &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; оптимальная стратения может выродится в цикл на одной вычислительной единице.&lt;br /&gt;
&lt;br /&gt;
Во второй группе (желтой) по каждой из &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; точек проводится &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt;-аггрегация &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; результатов. Таким образом, ширина ЯПФ &amp;lt;math&amp;gt;O(NC)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В третьей (красной) группе всё примитивно. &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; событий по опусканию одного и поднятию другого флага. Ширина &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В четвёртой (сиреневой) группе: SUM-аггрерация &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; результатов. Ширина ЯПФ &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В пятой (синей) группе: по каждому из &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; центроидов независимо покоординатно (&amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; координат) надо найти сумму произведений &amp;lt;math&amp;gt;u_{ik} \cdot M_{ij}&amp;lt;/math&amp;gt;. Так же надо завести счётчик. Ширина ЯПФ &amp;lt;math&amp;gt;O(C(D+1)N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N + 1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итого, ширина ЯПФ алгоритма &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N + \log C)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_k \}_{k=1}^N \subset \mathbb{R}^D&amp;lt;/math&amp;gt; — исходный набор точек признакового пространства.&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — количество кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;criteria\, params&amp;lt;/math&amp;gt; — параметры критерия останова.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;ND + const&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;M \in \mathbb{R}^{N \times C} &amp;lt;/math&amp;gt; — рядовая матрица&lt;br /&gt;
* &amp;lt;math&amp;gt;\{c_k\}_{k=1}^C&amp;lt;/math&amp;gt; — координаты кластерных центров&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;C(N+D)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Назначение:&#039;&#039;&#039; кластеризация больших наборов числовых данных  представленных признаковыми описаниями объектов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Достоинства:&#039;&#039;&#039;&lt;br /&gt;
* лёгкость реализации&lt;br /&gt;
* вычислительная простота&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки:&#039;&#039;&#039;&lt;br /&gt;
* явное задание количества кластеров&lt;br /&gt;
* отсутствие гарантии нахождения оптимального решения&lt;br /&gt;
* чувствительность к начальному приближению координат кластерных центров&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной ($O(NCD)$) и параллельной ($(\log N + \log C)) сложности в случае неограниченных ресурсов сублинейна по $N$ и $C$ (по количеству объектов и кластеров), линейна по $D$ (по размерности признакового пространства).&lt;br /&gt;
&lt;br /&gt;
Вычислительная мощность, как отношение числа операций к суммарному объёму входных и выходных данных, &#039;&#039;линейна&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм детерменирован при явном задании начального приближения для центроидов. Алгоритм чувствителен к выбору начального приближения.&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
Для демонстрации работы алгоритма была создана собственная реализация алгоритма&amp;lt;ref&amp;gt;https://github.com/urandon/hcm_tbb&amp;lt;/ref&amp;gt; с использованием фреймворка Intel® Threading Building Blocks &amp;lt;ref&amp;gt;https://www.threadingbuildingblocks.org/&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;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
1) [http://projects.jasmeet.me/2013/03/HardCMeans.html Matlab, последовательная реализация]&lt;br /&gt;
&lt;br /&gt;
2) [https://github.com/artpar/Hard-Clustering-implementation С++, последовательная реализация ]&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=22474</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=22474"/>
		<updated>2017-02-08T18:47:53Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Программная реализация алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор описания [[Участник:Urandon|Хомутов Никита]]&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;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
Целевая функция алгоритма полностью аналогична целевой функции K-Means[https://ru.wikipedia.org/wiki/K-means].&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \qquad \forall j \neq i \\&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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
Данная операция сводится к использованию ассоциативной &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt; и паттерна Reduse&amp;lt;ref&amp;gt;Reduce paralle pattern [http://www.drdobbs.com/architecture-and-design/parallel-pattern-7-reduce/222000718]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
Последовательная схема реализована в виде python-подобного псевдокода. Для оптимизации вычислений хранится структура, хранящая номер кластера для каждой точки. Это оптимизация с учётом разреженности матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
J_history = []&lt;br /&gt;
c = u[random.choice(N, C), :]&lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
clusterization = zeros(N) # sparse version of M&lt;br /&gt;
&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
&lt;br /&gt;
    # update M, J&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, clusterization[i]] = 1&lt;br /&gt;
 &lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
    # update C&lt;br /&gt;
    c = zeros(N, C)&lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        n_pts_in_cluster = 0&lt;br /&gt;
        for i in range(N):&lt;br /&gt;
            if not M[i, j]:&lt;br /&gt;
                continue&lt;br /&gt;
            n_pts_in_cluster += 1&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                c[j, k] += u[i, k]&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c[j, k] /= n_pts_in_cluster&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На каждой итерации основного цикла алгоритма:&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; операций вычисления квадратов расстояний до центров кластеров: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; разностей, возведеий в квадрат и &amp;lt;math&amp;gt;NC(D-1)&amp;lt;/math&amp;gt; сумм&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
* Шаг 3 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; сложений&lt;br /&gt;
* Шаг 4 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; векторных умножений на скаляр, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; сложений: &amp;lt;math&amp;gt;ND+C&amp;lt;/math&amp;gt; сложений и &amp;lt;math&amp;gt;CD&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
Итого, одна итерация основного цикла стоит &amp;lt;math&amp;gt;O(3NCD)&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;
&#039;&#039;&#039;Группа 1&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;d(p,c)&amp;lt;/math&amp;gt;, выделена зелёным цветом.&lt;br /&gt;
Отвечает за вычисление расстояний между точками &amp;lt;math&amp;gt;p, u_i&amp;lt;/math&amp;gt; и центроидами &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt;. Расстояния вычисляются независимо как по точкам, так и по центроидам. Несмотря на независимость вычислений, их следует группировать по точкам, так как в дальнейшем результатов (расстояния до центров) будут аггрерироваться по точкам (операция &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 2&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;, выделена жёлтым цветом.&lt;br /&gt;
Отвечает за поиск ближайшего центроида до данной точки (при уже вычисленных расстояниях). Фактически, применяет паттерн Reduce с участием ассоциативной операцией &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;. Находит как индекс ближайшего центроида (используется для обновления матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;), так и расстояние до него (входит в сумму &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 3&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, выделена красным цветом. Обновляет значения матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; для каждой точки. Индикатор, соответствующий старому центроиду обнуляется, а новому - выставляется 1.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 4&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;J sum&amp;lt;/math&amp;gt;, выделена сиреневым цветом.&lt;br /&gt;
Осуществляет суммирование расстояний до ближайших центроидов. Применение паттерна Reduce с участием операции &amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 5&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;upd c&amp;lt;/math&amp;gt;, выделена синим цветом. Обновляет координаты центроидов. Для каждого центроида &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; перебираются все точки &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;M[c, p] = 1&amp;lt;/math&amp;gt;. Координаты таких точек суммируются (независимо покоординатно), возможно, с применением паттерна Reduce по точкам. Так же заводятся счётчики: сколько точек принадлежит кластеру с данным центроидом. Затем покоординатно производится нормировка.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:HCM_IG.png|thumb|800px|center| Информационный граф алгоритма. Здесь &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - точки &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерного пространства, соответствующие исследуемым объектам (входные данные); &amp;lt;math&amp;gt;d(p,c)&amp;lt;/math&amp;gt; вычисление расстояний от точки то центров; &amp;lt;math&amp;gt;\arg\,\min&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;; &amp;lt;math&amp;gt;J, J_{sum}&amp;lt;/math&amp;gt; вычисление и аггрерирование функционала оптимизации; &amp;lt;math&amp;gt;upd 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;
В первой (зелёной) группе необходимо вычислить &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; расстояний. Каждое вычисление расстояния сопоставляется вычислению &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; покоординатных расстояний с последующим суммированием. Ширина ЯПФ &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log D)&amp;lt;/math&amp;gt;. Отметим, что на практике суммрование сдваиванием может не быть самой оптимальной стратегией из-за оверхеда на обеспечение синхронизации: выходом может быть тоже иерархический паттерн Reduce, но арргерирующий больше двух результатов на одной вычислительной единице. Асимптотическая высота такого паттерна так же &amp;lt;math&amp;gt;O(\log NC)&amp;lt;/math&amp;gt;. При достаточно малых значениях &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; оптимальная стратения может выродится в цикл на одной вычислительной единице.&lt;br /&gt;
&lt;br /&gt;
Во второй группе (желтой) по каждой из &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; точек проводится &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt;-аггрегация &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; результатов. Таким образом, ширина ЯПФ &amp;lt;math&amp;gt;O(NC)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В третьей (красной) группе всё примитивно. &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; событий по опусканию одного и поднятию другого флага. Ширина &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В четвёртой (сиреневой) группе: SUM-аггрерация &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; результатов. Ширина ЯПФ &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В пятой (синей) группе: по каждому из &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; центроидов независимо покоординатно (&amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; координат) надо найти сумму произведений &amp;lt;math&amp;gt;u_{ik} \cdot M_{ij}&amp;lt;/math&amp;gt;. Так же надо завести счётчик. Ширина ЯПФ &amp;lt;math&amp;gt;O(C(D+1)N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N + 1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итого, ширина ЯПФ алгоритма &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N + \log C)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_k \}_{k=1}^N \subset \mathbb{R}^D&amp;lt;/math&amp;gt; — исходный набор точек признакового пространства.&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — количество кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;criteria\, params&amp;lt;/math&amp;gt; — параметры критерия останова.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;ND + const&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;M \in \mathbb{R}^{N \times C} &amp;lt;/math&amp;gt; — рядовая матрица&lt;br /&gt;
* &amp;lt;math&amp;gt;\{c_k\}_{k=1}^C&amp;lt;/math&amp;gt; — координаты кластерных центров&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;C(N+D)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Назначение:&#039;&#039;&#039; кластеризация больших наборов числовых данных  представленных признаковыми описаниями объектов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Достоинства:&#039;&#039;&#039;&lt;br /&gt;
* лёгкость реализации&lt;br /&gt;
* вычислительная простота&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки:&#039;&#039;&#039;&lt;br /&gt;
* явное задание количества кластеров&lt;br /&gt;
* отсутствие гарантии нахождения оптимального решения&lt;br /&gt;
* чувствительность к начальному приближению координат кластерных центров&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
Для демонстрации работы алгоритма была создана собственная реализация алгоритма&amp;lt;ref&amp;gt;https://github.com/urandon/hcm_tbb&amp;lt;/ref&amp;gt; с использованием фреймворка Intel® Threading Building Blocks &amp;lt;ref&amp;gt;https://www.threadingbuildingblocks.org/&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;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
1) [http://projects.jasmeet.me/2013/03/HardCMeans.html Matlab, последовательная реализация]&lt;br /&gt;
&lt;br /&gt;
2) [https://github.com/artpar/Hard-Clustering-implementation С++, последовательная реализация ]&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=22473</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=22473"/>
		<updated>2017-02-08T18:46:18Z</updated>

		<summary type="html">&lt;p&gt;Urandon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор описания [[Участник:Urandon|Хомутов Никита]]&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;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
Целевая функция алгоритма полностью аналогична целевой функции K-Means[https://ru.wikipedia.org/wiki/K-means].&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \qquad \forall j \neq i \\&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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
Данная операция сводится к использованию ассоциативной &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt; и паттерна Reduse&amp;lt;ref&amp;gt;Reduce paralle pattern [http://www.drdobbs.com/architecture-and-design/parallel-pattern-7-reduce/222000718]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
Последовательная схема реализована в виде python-подобного псевдокода. Для оптимизации вычислений хранится структура, хранящая номер кластера для каждой точки. Это оптимизация с учётом разреженности матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
J_history = []&lt;br /&gt;
c = u[random.choice(N, C), :]&lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
clusterization = zeros(N) # sparse version of M&lt;br /&gt;
&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
&lt;br /&gt;
    # update M, J&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, clusterization[i]] = 1&lt;br /&gt;
 &lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
    # update C&lt;br /&gt;
    c = zeros(N, C)&lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        n_pts_in_cluster = 0&lt;br /&gt;
        for i in range(N):&lt;br /&gt;
            if not M[i, j]:&lt;br /&gt;
                continue&lt;br /&gt;
            n_pts_in_cluster += 1&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                c[j, k] += u[i, k]&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c[j, k] /= n_pts_in_cluster&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На каждой итерации основного цикла алгоритма:&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; операций вычисления квадратов расстояний до центров кластеров: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; разностей, возведеий в квадрат и &amp;lt;math&amp;gt;NC(D-1)&amp;lt;/math&amp;gt; сумм&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
* Шаг 3 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; сложений&lt;br /&gt;
* Шаг 4 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; векторных умножений на скаляр, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; сложений: &amp;lt;math&amp;gt;ND+C&amp;lt;/math&amp;gt; сложений и &amp;lt;math&amp;gt;CD&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
Итого, одна итерация основного цикла стоит &amp;lt;math&amp;gt;O(3NCD)&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;
&#039;&#039;&#039;Группа 1&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;d(p,c)&amp;lt;/math&amp;gt;, выделена зелёным цветом.&lt;br /&gt;
Отвечает за вычисление расстояний между точками &amp;lt;math&amp;gt;p, u_i&amp;lt;/math&amp;gt; и центроидами &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt;. Расстояния вычисляются независимо как по точкам, так и по центроидам. Несмотря на независимость вычислений, их следует группировать по точкам, так как в дальнейшем результатов (расстояния до центров) будут аггрерироваться по точкам (операция &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 2&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;, выделена жёлтым цветом.&lt;br /&gt;
Отвечает за поиск ближайшего центроида до данной точки (при уже вычисленных расстояниях). Фактически, применяет паттерн Reduce с участием ассоциативной операцией &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;. Находит как индекс ближайшего центроида (используется для обновления матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;), так и расстояние до него (входит в сумму &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 3&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, выделена красным цветом. Обновляет значения матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; для каждой точки. Индикатор, соответствующий старому центроиду обнуляется, а новому - выставляется 1.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 4&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;J sum&amp;lt;/math&amp;gt;, выделена сиреневым цветом.&lt;br /&gt;
Осуществляет суммирование расстояний до ближайших центроидов. Применение паттерна Reduce с участием операции &amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 5&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;upd c&amp;lt;/math&amp;gt;, выделена синим цветом. Обновляет координаты центроидов. Для каждого центроида &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; перебираются все точки &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;M[c, p] = 1&amp;lt;/math&amp;gt;. Координаты таких точек суммируются (независимо покоординатно), возможно, с применением паттерна Reduce по точкам. Так же заводятся счётчики: сколько точек принадлежит кластеру с данным центроидом. Затем покоординатно производится нормировка.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:HCM_IG.png|thumb|800px|center| Информационный граф алгоритма. Здесь &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - точки &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерного пространства, соответствующие исследуемым объектам (входные данные); &amp;lt;math&amp;gt;d(p,c)&amp;lt;/math&amp;gt; вычисление расстояний от точки то центров; &amp;lt;math&amp;gt;\arg\,\min&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;; &amp;lt;math&amp;gt;J, J_{sum}&amp;lt;/math&amp;gt; вычисление и аггрерирование функционала оптимизации; &amp;lt;math&amp;gt;upd 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;
В первой (зелёной) группе необходимо вычислить &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; расстояний. Каждое вычисление расстояния сопоставляется вычислению &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; покоординатных расстояний с последующим суммированием. Ширина ЯПФ &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log D)&amp;lt;/math&amp;gt;. Отметим, что на практике суммрование сдваиванием может не быть самой оптимальной стратегией из-за оверхеда на обеспечение синхронизации: выходом может быть тоже иерархический паттерн Reduce, но арргерирующий больше двух результатов на одной вычислительной единице. Асимптотическая высота такого паттерна так же &amp;lt;math&amp;gt;O(\log NC)&amp;lt;/math&amp;gt;. При достаточно малых значениях &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; оптимальная стратения может выродится в цикл на одной вычислительной единице.&lt;br /&gt;
&lt;br /&gt;
Во второй группе (желтой) по каждой из &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; точек проводится &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt;-аггрегация &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; результатов. Таким образом, ширина ЯПФ &amp;lt;math&amp;gt;O(NC)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В третьей (красной) группе всё примитивно. &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; событий по опусканию одного и поднятию другого флага. Ширина &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В четвёртой (сиреневой) группе: SUM-аггрерация &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; результатов. Ширина ЯПФ &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В пятой (синей) группе: по каждому из &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; центроидов независимо покоординатно (&amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; координат) надо найти сумму произведений &amp;lt;math&amp;gt;u_{ik} \cdot M_{ij}&amp;lt;/math&amp;gt;. Так же надо завести счётчик. Ширина ЯПФ &amp;lt;math&amp;gt;O(C(D+1)N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N + 1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итого, ширина ЯПФ алгоритма &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N + \log C)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_k \}_{k=1}^N \subset \mathbb{R}^D&amp;lt;/math&amp;gt; — исходный набор точек признакового пространства.&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — количество кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;criteria\, params&amp;lt;/math&amp;gt; — параметры критерия останова.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;ND + const&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;M \in \mathbb{R}^{N \times C} &amp;lt;/math&amp;gt; — рядовая матрица&lt;br /&gt;
* &amp;lt;math&amp;gt;\{c_k\}_{k=1}^C&amp;lt;/math&amp;gt; — координаты кластерных центров&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;C(N+D)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Назначение:&#039;&#039;&#039; кластеризация больших наборов числовых данных  представленных признаковыми описаниями объектов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Достоинства:&#039;&#039;&#039;&lt;br /&gt;
* лёгкость реализации&lt;br /&gt;
* вычислительная простота&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки:&#039;&#039;&#039;&lt;br /&gt;
* явное задание количества кластеров&lt;br /&gt;
* отсутствие гарантии нахождения оптимального решения&lt;br /&gt;
* чувствительность к начальному приближению координат кластерных центров&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
Для демонстрации работы алгоритма была создана собственная реализация алгоритма&amp;lt;ref&amp;gt;https://github.com/urandon/hcm_tbb&amp;lt;/ref&amp;gt; с использованием фреймворка Intel® Threading Blocks &amp;lt;ref&amp;gt;https://www.threadingbuildingblocks.org/&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;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
1) [http://projects.jasmeet.me/2013/03/HardCMeans.html Matlab, последовательная реализация]&lt;br /&gt;
&lt;br /&gt;
2) [https://github.com/artpar/Hard-Clustering-implementation С++, последовательная реализация ]&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=22358</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=22358"/>
		<updated>2017-02-06T22:46:25Z</updated>

		<summary type="html">&lt;p&gt;Urandon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&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;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
Целевая функция алгоритма полностью аналогична целевой функции K-Means[https://ru.wikipedia.org/wiki/K-means].&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \qquad \forall j \neq i \\&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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
Данная операция сводится к использованию ассоциативной &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt; и паттерна Reduse&amp;lt;ref&amp;gt;Reduce paralle pattern [http://www.drdobbs.com/architecture-and-design/parallel-pattern-7-reduce/222000718]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
Последовательная схема реализована в виде python-подобного псевдокода. Для оптимизации вычислений хранится структура, хранящая номер кластера для каждой точки. Это оптимизация с учётом разреженности матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
J_history = []&lt;br /&gt;
c = u[random.choice(N, C), :]&lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
clusterization = zeros(N) # sparse version of M&lt;br /&gt;
&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
&lt;br /&gt;
    # update M, J&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, clusterization[i]] = 1&lt;br /&gt;
 &lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
    # update C&lt;br /&gt;
    c = zeros(N, C)&lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        n_pts_in_cluster = 0&lt;br /&gt;
        for i in range(N):&lt;br /&gt;
            if not M[i, j]:&lt;br /&gt;
                continue&lt;br /&gt;
            n_pts_in_cluster += 1&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                c[j, k] += u[i, k]&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c[j, k] /= n_pts_in_cluster&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На каждой итерации основного цикла алгоритма:&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; операций вычисления квадратов расстояний до центров кластеров: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; разностей, возведеий в квадрат и &amp;lt;math&amp;gt;NC(D-1)&amp;lt;/math&amp;gt; сумм&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
* Шаг 3 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; сложений&lt;br /&gt;
* Шаг 4 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; векторных умножений на скаляр, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; сложений: &amp;lt;math&amp;gt;ND+C&amp;lt;/math&amp;gt; сложений и &amp;lt;math&amp;gt;CD&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
Итого, одна итерация основного цикла стоит &amp;lt;math&amp;gt;O(3NCD)&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;
&#039;&#039;&#039;Группа 1&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;d(p,c)&amp;lt;/math&amp;gt;, выделена зелёным цветом.&lt;br /&gt;
Отвечает за вычисление расстояний между точками &amp;lt;math&amp;gt;p, u_i&amp;lt;/math&amp;gt; и центроидами &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt;. Расстояния вычисляются независимо как по точкам, так и по центроидам. Несмотря на независимость вычислений, их следует группировать по точкам, так как в дальнейшем результатов (расстояния до центров) будут аггрерироваться по точкам (операция &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 2&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;, выделена жёлтым цветом.&lt;br /&gt;
Отвечает за поиск ближайшего центроида до данной точки (при уже вычисленных расстояниях). Фактически, применяет паттерн Reduce с участием ассоциативной операцией &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;. Находит как индекс ближайшего центроида (используется для обновления матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;), так и расстояние до него (входит в сумму &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 3&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, выделена красным цветом. Обновляет значения матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; для каждой точки. Индикатор, соответствующий старому центроиду обнуляется, а новому - выставляется 1.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 4&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;J sum&amp;lt;/math&amp;gt;, выделена сиреневым цветом.&lt;br /&gt;
Осуществляет суммирование расстояний до ближайших центроидов. Применение паттерна Reduce с участием операции &amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 5&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;upd c&amp;lt;/math&amp;gt;, выделена синим цветом. Обновляет координаты центроидов. Для каждого центроида &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; перебираются все точки &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;M[c, p] = 1&amp;lt;/math&amp;gt;. Координаты таких точек суммируются (независимо покоординатно), возможно, с применением паттерна Reduce по точкам. Так же заводятся счётчики: сколько точек принадлежит кластеру с данным центроидом. Затем покоординатно производится нормировка.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:HCM_IG.png|thumb|800px|center| Информационный граф алгоритма. Здесь &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - точки &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерного пространства, соответствующие исследуемым объектам (входные данные); &amp;lt;math&amp;gt;d(p,c)&amp;lt;/math&amp;gt; вычисление расстояний от точки то центров; &amp;lt;math&amp;gt;\arg\,\min&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;; &amp;lt;math&amp;gt;J, J_{sum}&amp;lt;/math&amp;gt; вычисление и аггрерирование функционала оптимизации; &amp;lt;math&amp;gt;upd 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;
В первой (зелёной) группе необходимо вычислить &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; расстояний. Каждое вычисление расстояния сопоставляется вычислению &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; покоординатных расстояний с последующим суммированием. Ширина ЯПФ &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log D)&amp;lt;/math&amp;gt;. Отметим, что на практике суммрование сдваиванием может не быть самой оптимальной стратегией из-за оверхеда на обеспечение синхронизации: выходом может быть тоже иерархический паттерн Reduce, но арргерирующий больше двух результатов на одной вычислительной единице. Асимптотическая высота такого паттерна так же &amp;lt;math&amp;gt;O(\log NC)&amp;lt;/math&amp;gt;. При достаточно малых значениях &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; оптимальная стратения может выродится в цикл на одной вычислительной единице.&lt;br /&gt;
&lt;br /&gt;
Во второй группе (желтой) по каждой из &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; точек проводится &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt;-аггрегация &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; результатов. Таким образом, ширина ЯПФ &amp;lt;math&amp;gt;O(NC)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В третьей (красной) группе всё примитивно. &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; событий по опусканию одного и поднятию другого флага. Ширина &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В четвёртой (сиреневой) группе: SUM-аггрерация &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; результатов. Ширина ЯПФ &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В пятой (синей) группе: по каждому из &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; центроидов независимо покоординатно (&amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; координат) надо найти сумму произведений &amp;lt;math&amp;gt;u_{ik} \cdot M_{ij}&amp;lt;/math&amp;gt;. Так же надо завести счётчик. Ширина ЯПФ &amp;lt;math&amp;gt;O(C(D+1)N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N + 1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итого, ширина ЯПФ алгоритма &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N + \log C)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_k \}_{k=1}^N \subset \mathbb{R}^D&amp;lt;/math&amp;gt; — исходный набор точек признакового пространства.&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — количество кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;criteria\, params&amp;lt;/math&amp;gt; — параметры критерия останова.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;ND + const&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;M \in \mathbb{R}^{N \times C} &amp;lt;/math&amp;gt; — рядовая матрица&lt;br /&gt;
* &amp;lt;math&amp;gt;\{c_k\}_{k=1}^C&amp;lt;/math&amp;gt; — координаты кластерных центров&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;C(N+D)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Назначение:&#039;&#039;&#039; кластеризация больших наборов числовых данных  представленных признаковыми описаниями объектов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Достоинства:&#039;&#039;&#039;&lt;br /&gt;
* лёгкость реализации&lt;br /&gt;
* вычислительная простота&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки:&#039;&#039;&#039;&lt;br /&gt;
* явное задание количества кластеров&lt;br /&gt;
* отсутствие гарантии нахождения оптимального решения&lt;br /&gt;
* чувствительность к начальному приближению координат кластерных центров&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
Для демонстрации работы алгоритма была создана собственная реализация алгоритма&amp;lt;ref&amp;gt;https://github.com/urandon/hcm_tbb&amp;lt;/ref&amp;gt; с использованием фреймворка Intel® Threading Blocks &amp;lt;ref&amp;gt;https://www.threadingbuildingblocks.org/&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;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
1) [http://projects.jasmeet.me/2013/03/HardCMeans.html Matlab, последовательная реализация]&lt;br /&gt;
&lt;br /&gt;
2) [https://github.com/artpar/Hard-Clustering-implementation С++, последовательная реализация ]&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=22357</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=22357"/>
		<updated>2017-02-06T22:44:02Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Ресурс параллелизма алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
Целевая функция алгоритма полностью аналогична целевой функции K-Means[https://ru.wikipedia.org/wiki/K-means].&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \qquad \forall j \neq i \\&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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
Данная операция сводится к использованию ассоциативной &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt; и паттерна Reduse&amp;lt;ref&amp;gt;Reduce paralle pattern [http://www.drdobbs.com/architecture-and-design/parallel-pattern-7-reduce/222000718]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
Последовательная схема реализована в виде python-подобного псевдокода. Для оптимизации вычислений хранится структура, хранящая номер кластера для каждой точки. Это оптимизация с учётом разреженности матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
J_history = []&lt;br /&gt;
c = u[random.choice(N, C), :]&lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
clusterization = zeros(N) # sparse version of M&lt;br /&gt;
&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
&lt;br /&gt;
    # update M, J&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, clusterization[i]] = 1&lt;br /&gt;
 &lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
    # update C&lt;br /&gt;
    c = zeros(N, C)&lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        n_pts_in_cluster = 0&lt;br /&gt;
        for i in range(N):&lt;br /&gt;
            if not M[i, j]:&lt;br /&gt;
                continue&lt;br /&gt;
            n_pts_in_cluster += 1&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                c[j, k] += u[i, k]&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c[j, k] /= n_pts_in_cluster&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На каждой итерации основного цикла алгоритма:&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; операций вычисления квадратов расстояний до центров кластеров: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; разностей, возведеий в квадрат и &amp;lt;math&amp;gt;NC(D-1)&amp;lt;/math&amp;gt; сумм&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
* Шаг 3 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; сложений&lt;br /&gt;
* Шаг 4 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; векторных умножений на скаляр, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; сложений: &amp;lt;math&amp;gt;ND+C&amp;lt;/math&amp;gt; сложений и &amp;lt;math&amp;gt;CD&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
Итого, одна итерация основного цикла стоит &amp;lt;math&amp;gt;O(3NCD)&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;
&#039;&#039;&#039;Группа 1&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;d(p,c)&amp;lt;/math&amp;gt;, выделена зелёным цветом.&lt;br /&gt;
Отвечает за вычисление расстояний между точками &amp;lt;math&amp;gt;p, u_i&amp;lt;/math&amp;gt; и центроидами &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt;. Расстояния вычисляются независимо как по точкам, так и по центроидам. Несмотря на независимость вычислений, их следует группировать по точкам, так как в дальнейшем результатов (расстояния до центров) будут аггрерироваться по точкам (операция &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 2&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;, выделена жёлтым цветом.&lt;br /&gt;
Отвечает за поиск ближайшего центроида до данной точки (при уже вычисленных расстояниях). Фактически, применяет паттерн Reduce с участием ассоциативной операцией &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;. Находит как индекс ближайшего центроида (используется для обновления матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;), так и расстояние до него (входит в сумму &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 3&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, выделена красным цветом. Обновляет значения матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; для каждой точки. Индикатор, соответствующий старому центроиду обнуляется, а новому - выставляется 1.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 4&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;J sum&amp;lt;/math&amp;gt;, выделена сиреневым цветом.&lt;br /&gt;
Осуществляет суммирование расстояний до ближайших центроидов. Применение паттерна Reduce с участием операции &amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 5&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;upd c&amp;lt;/math&amp;gt;, выделена синим цветом. Обновляет координаты центроидов. Для каждого центроида &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; перебираются все точки &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;M[c, p] = 1&amp;lt;/math&amp;gt;. Координаты таких точек суммируются (независимо покоординатно), возможно, с применением паттерна Reduce по точкам. Так же заводятся счётчики: сколько точек принадлежит кластеру с данным центроидом. Затем покоординатно производится нормировка.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:HCM_IG.png|thumb|800px|center| Информационный граф алгоритма. Здесь &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - точки &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерного пространства, соответствующие исследуемым объектам (входные данные); &amp;lt;math&amp;gt;d(p,c)&amp;lt;/math&amp;gt; вычисление расстояний от точки то центров; &amp;lt;math&amp;gt;\arg\,\min&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;; &amp;lt;math&amp;gt;J, J_{sum}&amp;lt;/math&amp;gt; вычисление и аггрерирование функционала оптимизации; &amp;lt;math&amp;gt;upd 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;
В первой (зелёной) группе необходимо вычислить &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; расстояний. Каждое вычисление расстояния сопоставляется вычислению &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; покоординатных расстояний с последующим суммированием. Ширина ЯПФ &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log D)&amp;lt;/math&amp;gt;. Отметим, что на практике суммрование сдваиванием может не быть самой оптимальной стратегией из-за оверхеда на обеспечение синхронизации: выходом может быть тоже иерархический паттерн Reduce, но арргерирующий больше двух результатов на одной вычислительной единице. Асимптотическая высота такого паттерна так же &amp;lt;math&amp;gt;O(\log NC)&amp;lt;/math&amp;gt;. При достаточно малых значениях &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; оптимальная стратения может выродится в цикл на одной вычислительной единице.&lt;br /&gt;
&lt;br /&gt;
Во второй группе (желтой) по каждой из &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; точек проводится &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt;-аггрегация &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; результатов. Таким образом, ширина ЯПФ &amp;lt;math&amp;gt;O(NC)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log C)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В третьей (красной) группе всё примитивно. &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; событий по опусканию одного и поднятию другого флага. Ширина &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В четвёртой (сиреневой) группе: SUM-аггрерация &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; результатов. Ширина ЯПФ &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В пятой (синей) группе: по каждому из &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; центроидов независимо покоординатно (&amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; координат) надо найти сумму произведений &amp;lt;math&amp;gt;u_{ik} \cdot M_{ij}&amp;lt;/math&amp;gt;. Так же надо завести счётчик. Ширина ЯПФ &amp;lt;math&amp;gt;O(C(D+1)N)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N + 1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итого, ширина ЯПФ алгоритма &amp;lt;math&amp;gt;O(NCD)&amp;lt;/math&amp;gt;, высота &amp;lt;math&amp;gt;O(\log N + \log C)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_k \}_{k=1}^N \subset \mathbb{R}^D&amp;lt;/math&amp;gt; — исходный набор точек признакового пространства.&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — количество кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;criteria\, params&amp;lt;/math&amp;gt; — параметры критерия останова.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;ND + const&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;M \in \mathbb{R}^{N \times C} &amp;lt;/math&amp;gt; — рядовая матрица&lt;br /&gt;
* &amp;lt;math&amp;gt;\{c_k\}_{k=1}^C&amp;lt;/math&amp;gt; — координаты кластерных центров&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;C(N+D)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Назначение:&#039;&#039;&#039; кластеризация больших наборов числовых данных  представленных признаковыми описаниями объектов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Достоинства:&#039;&#039;&#039;&lt;br /&gt;
* лёгкость реализации&lt;br /&gt;
* вычислительная простота&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки:&#039;&#039;&#039;&lt;br /&gt;
* явное задание количества кластеров&lt;br /&gt;
* отсутствие гарантии нахождения оптимального решения&lt;br /&gt;
* чувствительность к начальному приближению координат кластерных центров&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
Для демонстрации работы алгоритма была создана собственная реализация алгоритма&amp;lt;ref&amp;gt;https://github.com/urandon/hcm_tbb&amp;lt;/ref&amp;gt; с использованием фреймворка Intel® Threading Blocks &amp;lt;ref&amp;gt;https://www.threadingbuildingblocks.org/&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;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
1) [http://projects.jasmeet.me/2013/03/HardCMeans.html Matlab, последовательная реализация]&lt;br /&gt;
&lt;br /&gt;
2) [https://github.com/artpar/Hard-Clustering-implementation С++, последовательная реализация ]&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=22356</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=22356"/>
		<updated>2017-02-06T22:09:16Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
Целевая функция алгоритма полностью аналогична целевой функции K-Means[https://ru.wikipedia.org/wiki/K-means].&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \qquad \forall j \neq i \\&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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
Данная операция сводится к использованию ассоциативной &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt; и паттерна Reduse&amp;lt;ref&amp;gt;Reduce paralle pattern [http://www.drdobbs.com/architecture-and-design/parallel-pattern-7-reduce/222000718]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
Последовательная схема реализована в виде python-подобного псевдокода. Для оптимизации вычислений хранится структура, хранящая номер кластера для каждой точки. Это оптимизация с учётом разреженности матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
J_history = []&lt;br /&gt;
c = u[random.choice(N, C), :]&lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
clusterization = zeros(N) # sparse version of M&lt;br /&gt;
&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
&lt;br /&gt;
    # update M, J&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, clusterization[i]] = 1&lt;br /&gt;
 &lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
    # update C&lt;br /&gt;
    c = zeros(N, C)&lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        n_pts_in_cluster = 0&lt;br /&gt;
        for i in range(N):&lt;br /&gt;
            if not M[i, j]:&lt;br /&gt;
                continue&lt;br /&gt;
            n_pts_in_cluster += 1&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                c[j, k] += u[i, k]&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c[j, k] /= n_pts_in_cluster&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На каждой итерации основного цикла алгоритма:&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; операций вычисления квадратов расстояний до центров кластеров: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; разностей, возведеий в квадрат и &amp;lt;math&amp;gt;NC(D-1)&amp;lt;/math&amp;gt; сумм&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
* Шаг 3 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; сложений&lt;br /&gt;
* Шаг 4 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; векторных умножений на скаляр, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; сложений: &amp;lt;math&amp;gt;ND+C&amp;lt;/math&amp;gt; сложений и &amp;lt;math&amp;gt;CD&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
Итого, одна итерация основного цикла стоит &amp;lt;math&amp;gt;O(3NCD)&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;
&#039;&#039;&#039;Группа 1&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;d(p,c)&amp;lt;/math&amp;gt;, выделена зелёным цветом.&lt;br /&gt;
Отвечает за вычисление расстояний между точками &amp;lt;math&amp;gt;p, u_i&amp;lt;/math&amp;gt; и центроидами &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt;. Расстояния вычисляются независимо как по точкам, так и по центроидам. Несмотря на независимость вычислений, их следует группировать по точкам, так как в дальнейшем результатов (расстояния до центров) будут аггрерироваться по точкам (операция &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 2&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;, выделена жёлтым цветом.&lt;br /&gt;
Отвечает за поиск ближайшего центроида до данной точки (при уже вычисленных расстояниях). Фактически, применяет паттерн Reduce с участием ассоциативной операцией &amp;lt;math&amp;gt;\arg\min&amp;lt;/math&amp;gt;. Находит как индекс ближайшего центроида (используется для обновления матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;), так и расстояние до него (входит в сумму &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 3&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, выделена красным цветом. Обновляет значения матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; для каждой точки. Индикатор, соответствующий старому центроиду обнуляется, а новому - выставляется 1.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 4&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;J sum&amp;lt;/math&amp;gt;, выделена сиреневым цветом.&lt;br /&gt;
Осуществляет суммирование расстояний до ближайших центроидов. Применение паттерна Reduce с участием операции &amp;lt;math&amp;gt;+&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Группа 5&#039;&#039;&#039;&lt;br /&gt;
Обозначена &amp;lt;math&amp;gt;upd c&amp;lt;/math&amp;gt;, выделена синим цветом. Обновляет координаты центроидов. Для каждого центроида &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; перебираются все точки &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;M[c, p] = 1&amp;lt;/math&amp;gt;. Координаты таких точек суммируются (независимо покоординатно), возможно, с применением паттерна Reduce по точкам. Так же заводятся счётчики: сколько точек принадлежит кластеру с данным центроидом. Затем покоординатно производится нормировка.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:HCM_IG.png|thumb|800px|center| Информационный граф алгоритма. Здесь &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - точки &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерного пространства, соответствующие исследуемым объектам (входные данные); &amp;lt;math&amp;gt;d(p,c)&amp;lt;/math&amp;gt; вычисление расстояний от точки то центров; &amp;lt;math&amp;gt;\arg\,\min&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;; &amp;lt;math&amp;gt;J, J_{sum}&amp;lt;/math&amp;gt; вычисление и аггрерирование функционала оптимизации; &amp;lt;math&amp;gt;upd c&amp;lt;/math&amp;gt; обновление центров кластеров ]]&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_k \}_{k=1}^N \subset \mathbb{R}^D&amp;lt;/math&amp;gt; — исходный набор точек признакового пространства.&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — количество кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;criteria\, params&amp;lt;/math&amp;gt; — параметры критерия останова.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;ND + const&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;M \in \mathbb{R}^{N \times C} &amp;lt;/math&amp;gt; — рядовая матрица&lt;br /&gt;
* &amp;lt;math&amp;gt;\{c_k\}_{k=1}^C&amp;lt;/math&amp;gt; — координаты кластерных центров&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;C(N+D)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Назначение:&#039;&#039;&#039; кластеризация больших наборов числовых данных  представленных признаковыми описаниями объектов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Достоинства:&#039;&#039;&#039;&lt;br /&gt;
* лёгкость реализации&lt;br /&gt;
* вычислительная простота&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки:&#039;&#039;&#039;&lt;br /&gt;
* явное задание количества кластеров&lt;br /&gt;
* отсутствие гарантии нахождения оптимального решения&lt;br /&gt;
* чувствительность к начальному приближению координат кластерных центров&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
Для демонстрации работы алгоритма была создана собственная реализация алгоритма&amp;lt;ref&amp;gt;https://github.com/urandon/hcm_tbb&amp;lt;/ref&amp;gt; с использованием фреймворка Intel® Threading Blocks &amp;lt;ref&amp;gt;https://www.threadingbuildingblocks.org/&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;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
1) [http://projects.jasmeet.me/2013/03/HardCMeans.html Matlab, последовательная реализация]&lt;br /&gt;
&lt;br /&gt;
2) [https://github.com/artpar/Hard-Clustering-implementation С++, последовательная реализация ]&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=22355</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=22355"/>
		<updated>2017-02-06T21:47:14Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
Целевая функция алгоритма полностью аналогична целевой функции K-Means[https://ru.wikipedia.org/wiki/K-means].&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \qquad \forall j \neq i \\&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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
Данная операция сводится к использованию ассоциативной &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt; и паттерна Reduse&amp;lt;ref&amp;gt;Reduce paralle pattern [http://www.drdobbs.com/architecture-and-design/parallel-pattern-7-reduce/222000718]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
Последовательная схема реализована в виде python-подобного псевдокода. Для оптимизации вычислений хранится структура, хранящая номер кластера для каждой точки. Это оптимизация с учётом разреженности матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
J_history = []&lt;br /&gt;
c = u[random.choice(N, C), :]&lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
clusterization = zeros(N) # sparse version of M&lt;br /&gt;
&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
&lt;br /&gt;
    # update M, J&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, clusterization[i]] = 1&lt;br /&gt;
 &lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
    # update C&lt;br /&gt;
    c = zeros(N, C)&lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        n_pts_in_cluster = 0&lt;br /&gt;
        for i in range(N):&lt;br /&gt;
            if not M[i, j]:&lt;br /&gt;
                continue&lt;br /&gt;
            n_pts_in_cluster += 1&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                c[j, k] += u[i, k]&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c[j, k] /= n_pts_in_cluster&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На каждой итерации основного цикла алгоритма:&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; операций вычисления квадратов расстояний до центров кластеров: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; разностей, возведеий в квадрат и &amp;lt;math&amp;gt;NC(D-1)&amp;lt;/math&amp;gt; сумм&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
* Шаг 3 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; сложений&lt;br /&gt;
* Шаг 4 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; векторных умножений на скаляр, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; сложений: &amp;lt;math&amp;gt;ND+C&amp;lt;/math&amp;gt; сложений и &amp;lt;math&amp;gt;CD&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
Итого, одна итерация основного цикла стоит &amp;lt;math&amp;gt;O(3NCD)&amp;lt;/math&amp;gt; элементарных операций.&lt;br /&gt;
Количество итераций зависит от данных, от начального приближения кластеризации, от критерия останова.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
[[Файл:HCM_IG.png|thumb|800px|center| Информационный граф алгоритма. Здесь &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - точки &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерного пространства, соответствующие исследуемым объектам (входные данные); &amp;lt;math&amp;gt;d(p,c)&amp;lt;/math&amp;gt; вычисление расстояний от точки то центров; &amp;lt;math&amp;gt;\arg\,\min&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;; &amp;lt;math&amp;gt;J, J_{sum}&amp;lt;/math&amp;gt; вычисление и аггрерирование функционала оптимизации; &amp;lt;math&amp;gt;upd c&amp;lt;/math&amp;gt; обновление центров кластеров ]]&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_k \}_{k=1}^N \subset \mathbb{R}^D&amp;lt;/math&amp;gt; — исходный набор точек признакового пространства.&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — количество кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;criteria\, params&amp;lt;/math&amp;gt; — параметры критерия останова.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;ND + const&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;M \in \mathbb{R}^{N \times C} &amp;lt;/math&amp;gt; — рядовая матрица&lt;br /&gt;
* &amp;lt;math&amp;gt;\{c_k\}_{k=1}^C&amp;lt;/math&amp;gt; — координаты кластерных центров&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;C(N+D)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Назначение:&#039;&#039;&#039; кластеризация больших наборов числовых данных  представленных признаковыми описаниями объектов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Достоинства:&#039;&#039;&#039;&lt;br /&gt;
* лёгкость реализации&lt;br /&gt;
* вычислительная простота&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки:&#039;&#039;&#039;&lt;br /&gt;
* явное задание количества кластеров&lt;br /&gt;
* отсутствие гарантии нахождения оптимального решения&lt;br /&gt;
* чувствительность к начальному приближению координат кластерных центров&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
Для демонстрации работы алгоритма была создана собственная реализация алгоритма&amp;lt;ref&amp;gt;https://github.com/urandon/hcm_tbb&amp;lt;/ref&amp;gt; с использованием фреймворка Intel® Threading Blocks &amp;lt;ref&amp;gt;https://www.threadingbuildingblocks.org/&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;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
1) [http://projects.jasmeet.me/2013/03/HardCMeans.html Matlab, последовательная реализация]&lt;br /&gt;
&lt;br /&gt;
2) [https://github.com/artpar/Hard-Clustering-implementation С++, последовательная реализация ]&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=22354</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=22354"/>
		<updated>2017-02-06T21:46:50Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
Целевая функция алгоритма полностью аналогична целевой функции K-Means[https://ru.wikipedia.org/wiki/K-means].&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \qquad \forall j \neq i \\&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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
Данная операция сводится к использованию ассоциативной &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt; и паттерна Reduse&amp;lt;ref&amp;gt;Reduce paralle pattern [http://www.drdobbs.com/architecture-and-design/parallel-pattern-7-reduce/222000718]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
Последовательная схема реализована в виде python-подобного псевдокода. Для оптимизации вычислений хранится структура, хранящая номер кластера для каждой точки. Это оптимизация с учётом разреженности матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
J_history = []&lt;br /&gt;
c = u[random.choice(N, C), :]&lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
clusterization = zeros(N) # sparse version of M&lt;br /&gt;
&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
&lt;br /&gt;
    # update M, J&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, clusterization[i]] = 1&lt;br /&gt;
 &lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
    # update C&lt;br /&gt;
    c = zeros(N, C)&lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        n_pts_in_cluster = 0&lt;br /&gt;
        for i in range(N):&lt;br /&gt;
            if not M[i, j]:&lt;br /&gt;
                continue&lt;br /&gt;
            n_pts_in_cluster += 1&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                c[j, k] += u[i, k]&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c[j, k] /= n_pts_in_cluster&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На каждой итерации основного цикла алгоритма:&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; операций вычисления квадратов расстояний до центров кластеров: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; разностей, возведеий в квадрат и &amp;lt;math&amp;gt;NC(D-1)&amp;lt;/math&amp;gt; сумм&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
* Шаг 3 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; сложений&lt;br /&gt;
* Шаг 4 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; векторных умножений на скаляр, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; сложений: &amp;lt;math&amp;gt;ND+C&amp;lt;/math&amp;gt; сложений и &amp;lt;math&amp;gt;CD&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
Итого, одна итерация основного цикла стоит &amp;lt;math&amp;gt;O(3NCD)&amp;lt;/math&amp;gt; элементарных операций.&lt;br /&gt;
Количество итераций зависит от данных, от начального приближения кластеризации, от критерия останова.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
[[Файл:HCM_IG.png|||center| Информационный граф алгоритма. Здесь &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - точки &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерного пространства, соответствующие исследуемым объектам (входные данные); &amp;lt;math&amp;gt;d(p,c)&amp;lt;/math&amp;gt; вычисление расстояний от точки то центров; &amp;lt;math&amp;gt;\arg\,\min&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;; &amp;lt;math&amp;gt;J, J_{sum}&amp;lt;/math&amp;gt; вычисление и аггрерирование функционала оптимизации; &amp;lt;math&amp;gt;upd c&amp;lt;/math&amp;gt; обновление центров кластеров ]]&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_k \}_{k=1}^N \subset \mathbb{R}^D&amp;lt;/math&amp;gt; — исходный набор точек признакового пространства.&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — количество кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;criteria\, params&amp;lt;/math&amp;gt; — параметры критерия останова.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;ND + const&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;M \in \mathbb{R}^{N \times C} &amp;lt;/math&amp;gt; — рядовая матрица&lt;br /&gt;
* &amp;lt;math&amp;gt;\{c_k\}_{k=1}^C&amp;lt;/math&amp;gt; — координаты кластерных центров&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;C(N+D)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Назначение:&#039;&#039;&#039; кластеризация больших наборов числовых данных  представленных признаковыми описаниями объектов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Достоинства:&#039;&#039;&#039;&lt;br /&gt;
* лёгкость реализации&lt;br /&gt;
* вычислительная простота&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки:&#039;&#039;&#039;&lt;br /&gt;
* явное задание количества кластеров&lt;br /&gt;
* отсутствие гарантии нахождения оптимального решения&lt;br /&gt;
* чувствительность к начальному приближению координат кластерных центров&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
Для демонстрации работы алгоритма была создана собственная реализация алгоритма&amp;lt;ref&amp;gt;https://github.com/urandon/hcm_tbb&amp;lt;/ref&amp;gt; с использованием фреймворка Intel® Threading Blocks &amp;lt;ref&amp;gt;https://www.threadingbuildingblocks.org/&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;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
1) [http://projects.jasmeet.me/2013/03/HardCMeans.html Matlab, последовательная реализация]&lt;br /&gt;
&lt;br /&gt;
2) [https://github.com/artpar/Hard-Clustering-implementation С++, последовательная реализация ]&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=22353</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=22353"/>
		<updated>2017-02-06T21:45:51Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Схема реализации последовательного алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
Целевая функция алгоритма полностью аналогична целевой функции K-Means[https://ru.wikipedia.org/wiki/K-means].&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \qquad \forall j \neq i \\&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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
Данная операция сводится к использованию ассоциативной &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt; и паттерна Reduse&amp;lt;ref&amp;gt;Reduce paralle pattern [http://www.drdobbs.com/architecture-and-design/parallel-pattern-7-reduce/222000718]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
Последовательная схема реализована в виде python-подобного псевдокода. Для оптимизации вычислений хранится структура, хранящая номер кластера для каждой точки. Это оптимизация с учётом разреженности матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
J_history = []&lt;br /&gt;
c = u[random.choice(N, C), :]&lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
clusterization = zeros(N) # sparse version of M&lt;br /&gt;
&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
&lt;br /&gt;
    # update M, J&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, clusterization[i]] = 1&lt;br /&gt;
 &lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
    # update C&lt;br /&gt;
    c = zeros(N, C)&lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        n_pts_in_cluster = 0&lt;br /&gt;
        for i in range(N):&lt;br /&gt;
            if not M[i, j]:&lt;br /&gt;
                continue&lt;br /&gt;
            n_pts_in_cluster += 1&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                c[j, k] += u[i, k]&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c[j, k] /= n_pts_in_cluster&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На каждой итерации основного цикла алгоритма:&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; операций вычисления квадратов расстояний до центров кластеров: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; разностей, возведеий в квадрат и &amp;lt;math&amp;gt;NC(D-1)&amp;lt;/math&amp;gt; сумм&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
* Шаг 3 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; сложений&lt;br /&gt;
* Шаг 4 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; векторных умножений на скаляр, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; сложений: &amp;lt;math&amp;gt;ND+C&amp;lt;/math&amp;gt; сложений и &amp;lt;math&amp;gt;CD&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
Итого, одна итерация основного цикла стоит &amp;lt;math&amp;gt;O(3NCD)&amp;lt;/math&amp;gt; элементарных операций.&lt;br /&gt;
Количество итераций зависит от данных, от начального приближения кластеризации, от критерия останова.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
[[Файл:HCM_IG.png| Информационный граф алгоритма. Здесь &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - точки &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерного пространства, соответствующие исследуемым объектам (входные данные); &amp;lt;math&amp;gt;d(p,c)&amp;lt;/math&amp;gt; вычисление расстояний от точки то центров; &amp;lt;math&amp;gt;\arg\,\min&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;; &amp;lt;math&amp;gt;J, J_{sum}&amp;lt;/math&amp;gt; вычисление и аггрерирование функционала оптимизации; &amp;lt;math&amp;gt;upd c&amp;lt;/math&amp;gt; обновление центров кластеров ]]&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_k \}_{k=1}^N \subset \mathbb{R}^D&amp;lt;/math&amp;gt; — исходный набор точек признакового пространства.&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — количество кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;criteria\, params&amp;lt;/math&amp;gt; — параметры критерия останова.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;ND + const&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;M \in \mathbb{R}^{N \times C} &amp;lt;/math&amp;gt; — рядовая матрица&lt;br /&gt;
* &amp;lt;math&amp;gt;\{c_k\}_{k=1}^C&amp;lt;/math&amp;gt; — координаты кластерных центров&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;C(N+D)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Назначение:&#039;&#039;&#039; кластеризация больших наборов числовых данных  представленных признаковыми описаниями объектов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Достоинства:&#039;&#039;&#039;&lt;br /&gt;
* лёгкость реализации&lt;br /&gt;
* вычислительная простота&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки:&#039;&#039;&#039;&lt;br /&gt;
* явное задание количества кластеров&lt;br /&gt;
* отсутствие гарантии нахождения оптимального решения&lt;br /&gt;
* чувствительность к начальному приближению координат кластерных центров&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
Для демонстрации работы алгоритма была создана собственная реализация алгоритма&amp;lt;ref&amp;gt;https://github.com/urandon/hcm_tbb&amp;lt;/ref&amp;gt; с использованием фреймворка Intel® Threading Blocks &amp;lt;ref&amp;gt;https://www.threadingbuildingblocks.org/&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;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
1) [http://projects.jasmeet.me/2013/03/HardCMeans.html Matlab, последовательная реализация]&lt;br /&gt;
&lt;br /&gt;
2) [https://github.com/artpar/Hard-Clustering-implementation С++, последовательная реализация ]&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:HCM_IG.png&amp;diff=22352</id>
		<title>Файл:HCM IG.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:HCM_IG.png&amp;diff=22352"/>
		<updated>2017-02-06T21:38:32Z</updated>

		<summary type="html">&lt;p&gt;Urandon: Urandon загрузил новую версию Файл:HCM IG.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hard C-Means Information Graph&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=22351</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=22351"/>
		<updated>2017-02-06T21:37:48Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
Целевая функция алгоритма полностью аналогична целевой функции K-Means[https://ru.wikipedia.org/wiki/K-means].&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \qquad \forall j \neq i \\&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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
Данная операция сводится к использованию ассоциативной &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt; и паттерна Reduse&amp;lt;ref&amp;gt;Reduce paralle pattern [http://www.drdobbs.com/architecture-and-design/parallel-pattern-7-reduce/222000718]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
Последовательная схема реализована в виде python-подобного псевдокода. Для оптимизации вычислений хранится структура, хранящая номер кластера для каждой точки. Это оптимизация с учётом разреженности матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
J_history = []&lt;br /&gt;
c = u[random.choice(N, C), :]&lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
clusterization = zeros(N) # sparse version of M&lt;br /&gt;
&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
    c_new_cnt = zeros(C)&lt;br /&gt;
    c_new = zeros(N, C)&lt;br /&gt;
&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, j_min] = 1&lt;br /&gt;
 &lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[clusterization[i], k] += u[i,k]&lt;br /&gt;
        c_new_cnt[clusterization[i]] += 1&lt;br /&gt;
&lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[j, k] /= c_new_cnt[j]&lt;br /&gt;
&lt;br /&gt;
    c = c_new&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На каждой итерации основного цикла алгоритма:&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; операций вычисления квадратов расстояний до центров кластеров: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; разностей, возведеий в квадрат и &amp;lt;math&amp;gt;NC(D-1)&amp;lt;/math&amp;gt; сумм&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
* Шаг 3 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; сложений&lt;br /&gt;
* Шаг 4 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; векторных умножений на скаляр, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; сложений: &amp;lt;math&amp;gt;ND+C&amp;lt;/math&amp;gt; сложений и &amp;lt;math&amp;gt;CD&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
Итого, одна итерация основного цикла стоит &amp;lt;math&amp;gt;O(3NCD)&amp;lt;/math&amp;gt; элементарных операций.&lt;br /&gt;
Количество итераций зависит от данных, от начального приближения кластеризации, от критерия останова.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
[[Файл:HCM_IG.png| Информационный граф алгоритма. Здесь &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - точки &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерного пространства, соответствующие исследуемым объектам (входные данные); &amp;lt;math&amp;gt;d(p,c)&amp;lt;/math&amp;gt; вычисление расстояний от точки то центров; &amp;lt;math&amp;gt;\arg\,\min&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;; &amp;lt;math&amp;gt;J, J_{sum}&amp;lt;/math&amp;gt; вычисление и аггрерирование функционала оптимизации; &amp;lt;math&amp;gt;upd c&amp;lt;/math&amp;gt; обновление центров кластеров ]]&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_k \}_{k=1}^N \subset \mathbb{R}^D&amp;lt;/math&amp;gt; — исходный набор точек признакового пространства.&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — количество кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;criteria\, params&amp;lt;/math&amp;gt; — параметры критерия останова.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;ND + const&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;M \in \mathbb{R}^{N \times C} &amp;lt;/math&amp;gt; — рядовая матрица&lt;br /&gt;
* &amp;lt;math&amp;gt;\{c_k\}_{k=1}^C&amp;lt;/math&amp;gt; — координаты кластерных центров&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;C(N+D)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Назначение:&#039;&#039;&#039; кластеризация больших наборов числовых данных  представленных признаковыми описаниями объектов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Достоинства:&#039;&#039;&#039;&lt;br /&gt;
* лёгкость реализации&lt;br /&gt;
* вычислительная простота&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки:&#039;&#039;&#039;&lt;br /&gt;
* явное задание количества кластеров&lt;br /&gt;
* отсутствие гарантии нахождения оптимального решения&lt;br /&gt;
* чувствительность к начальному приближению координат кластерных центров&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
Для демонстрации работы алгоритма была создана собственная реализация алгоритма&amp;lt;ref&amp;gt;https://github.com/urandon/hcm_tbb&amp;lt;/ref&amp;gt; с использованием фреймворка Intel® Threading Blocks &amp;lt;ref&amp;gt;https://www.threadingbuildingblocks.org/&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;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
1) [http://projects.jasmeet.me/2013/03/HardCMeans.html Matlab, последовательная реализация]&lt;br /&gt;
&lt;br /&gt;
2) [https://github.com/artpar/Hard-Clustering-implementation С++, последовательная реализация ]&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=22350</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=22350"/>
		<updated>2017-02-06T21:19:59Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
Целевая функция алгоритма полностью аналогична целевой функции K-Means[https://ru.wikipedia.org/wiki/K-means].&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \qquad \forall j \neq i \\&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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
Данная операция сводится к использованию ассоциативной &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt; и паттерна Reduse&amp;lt;ref&amp;gt;Reduce paralle pattern [http://www.drdobbs.com/architecture-and-design/parallel-pattern-7-reduce/222000718]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
Последовательная схема реализована в виде python-подобного псевдокода. Для оптимизации вычислений хранится структура, хранящая номер кластера для каждой точки. Это оптимизация с учётом разреженности матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
J_history = []&lt;br /&gt;
c = u[random.choice(N, C), :]&lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
clusterization = zeros(N) # sparse version of M&lt;br /&gt;
&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
    c_new_cnt = zeros(C)&lt;br /&gt;
    c_new = zeros(N, C)&lt;br /&gt;
&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, j_min] = 1&lt;br /&gt;
 &lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[clusterization[i], k] += u[i,k]&lt;br /&gt;
        c_new_cnt[clusterization[i]] += 1&lt;br /&gt;
&lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[j, k] /= c_new_cnt[j]&lt;br /&gt;
&lt;br /&gt;
    c = c_new&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На каждой итерации основного цикла алгоритма:&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; операций вычисления квадратов расстояний до центров кластеров: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; разностей, возведеий в квадрат и &amp;lt;math&amp;gt;NC(D-1)&amp;lt;/math&amp;gt; сумм&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
* Шаг 3 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; сложений&lt;br /&gt;
* Шаг 4 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; векторных умножений на скаляр, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; сложений: &amp;lt;math&amp;gt;ND+C&amp;lt;/math&amp;gt; сложений и &amp;lt;math&amp;gt;CD&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
Итого, одна итерация основного цикла стоит &amp;lt;math&amp;gt;O(3NCD)&amp;lt;/math&amp;gt; элементарных операций.&lt;br /&gt;
Количество итераций зависит от данных, от начального приближения кластеризации, от критерия останова.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
[[Файл:HCM_IG.png]]&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_k \}_{k=1}^N \subset \mathbb{R}^D&amp;lt;/math&amp;gt; — исходный набор точек признакового пространства.&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — количество кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;criteria\, params&amp;lt;/math&amp;gt; — параметры критерия останова.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;ND + const&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;M \in \mathbb{R}^{N \times C} &amp;lt;/math&amp;gt; — рядовая матрица&lt;br /&gt;
* &amp;lt;math&amp;gt;\{c_k\}_{k=1}^C&amp;lt;/math&amp;gt; — координаты кластерных центров&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;C(N+D)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Назначение:&#039;&#039;&#039; кластеризация больших наборов числовых данных  представленных признаковыми описаниями объектов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Достоинства:&#039;&#039;&#039;&lt;br /&gt;
* лёгкость реализации&lt;br /&gt;
* вычислительная простота&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки:&#039;&#039;&#039;&lt;br /&gt;
* явное задание количества кластеров&lt;br /&gt;
* отсутствие гарантии нахождения оптимального решения&lt;br /&gt;
* чувствительность к начальному приближению координат кластерных центров&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
Для демонстрации работы алгоритма была создана собственная реализация алгоритма&amp;lt;ref&amp;gt;https://github.com/urandon/hcm_tbb&amp;lt;/ref&amp;gt; с использованием фреймворка Intel® Threading Blocks &amp;lt;ref&amp;gt;https://www.threadingbuildingblocks.org/&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;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
1) [http://projects.jasmeet.me/2013/03/HardCMeans.html Matlab, последовательная реализация]&lt;br /&gt;
&lt;br /&gt;
2) [https://github.com/artpar/Hard-Clustering-implementation С++, последовательная реализация ]&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:HCM_IG.png&amp;diff=22349</id>
		<title>Файл:HCM IG.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:HCM_IG.png&amp;diff=22349"/>
		<updated>2017-02-06T21:19:34Z</updated>

		<summary type="html">&lt;p&gt;Urandon: Hard C-Means Information Graph&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hard C-Means Information Graph&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=22341</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=22341"/>
		<updated>2017-02-06T20:59:48Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
Целевая функция алгоритма полностью аналогична целевой функции K-Means[https://ru.wikipedia.org/wiki/K-means].&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \qquad \forall j \neq i \\&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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
Данная операция сводится к использованию ассоциативной &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt; и паттерна Reduse&amp;lt;ref&amp;gt;Reduce paralle pattern [http://www.drdobbs.com/architecture-and-design/parallel-pattern-7-reduce/222000718]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
Последовательная схема реализована в виде python-подобного псевдокода. Для оптимизации вычислений хранится структура, хранящая номер кластера для каждой точки. Это оптимизация с учётом разреженности матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
J_history = []&lt;br /&gt;
c = u[random.choice(N, C), :]&lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
clusterization = zeros(N) # sparse version of M&lt;br /&gt;
&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
    c_new_cnt = zeros(C)&lt;br /&gt;
    c_new = zeros(N, C)&lt;br /&gt;
&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, j_min] = 1&lt;br /&gt;
 &lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[clusterization[i], k] += u[i,k]&lt;br /&gt;
        c_new_cnt[clusterization[i]] += 1&lt;br /&gt;
&lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[j, k] /= c_new_cnt[j]&lt;br /&gt;
&lt;br /&gt;
    c = c_new&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На каждой итерации основного цикла алгоритма:&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; операций вычисления квадратов расстояний до центров кластеров: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; разностей, возведеий в квадрат и &amp;lt;math&amp;gt;NC(D-1)&amp;lt;/math&amp;gt; сумм&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
* Шаг 3 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; сложений&lt;br /&gt;
* Шаг 4 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; векторных умножений на скаляр, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; сложений: &amp;lt;math&amp;gt;ND+C&amp;lt;/math&amp;gt; сложений и &amp;lt;math&amp;gt;CD&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
Итого, одна итерация основного цикла стоит &amp;lt;math&amp;gt;O(3NCD)&amp;lt;/math&amp;gt; элементарных операций.&lt;br /&gt;
Количество итераций зависит от данных, от начального приближения кластеризации, от критерия останова.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
[[Файл:HCM.svg]]&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_k \}_{k=1}^N \subset \mathbb{R}^D&amp;lt;/math&amp;gt; — исходный набор точек признакового пространства.&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — количество кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;criteria\, params&amp;lt;/math&amp;gt; — параметры критерия останова.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;ND + const&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;M \in \mathbb{R}^{N \times C} &amp;lt;/math&amp;gt; — рядовая матрица&lt;br /&gt;
* &amp;lt;math&amp;gt;\{c_k\}_{k=1}^C&amp;lt;/math&amp;gt; — координаты кластерных центров&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;C(N+D)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Назначение:&#039;&#039;&#039; кластеризация больших наборов числовых данных  представленных признаковыми описаниями объектов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Достоинства:&#039;&#039;&#039;&lt;br /&gt;
* лёгкость реализации&lt;br /&gt;
* вычислительная простота&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки:&#039;&#039;&#039;&lt;br /&gt;
* явное задание количества кластеров&lt;br /&gt;
* отсутствие гарантии нахождения оптимального решения&lt;br /&gt;
* чувствительность к начальному приближению координат кластерных центров&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
Для демонстрации работы алгоритма была создана собственная реализация алгоритма&amp;lt;ref&amp;gt;https://github.com/urandon/hcm_tbb&amp;lt;/ref&amp;gt; с использованием фреймворка Intel® Threading Blocks &amp;lt;ref&amp;gt;https://www.threadingbuildingblocks.org/&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;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
1) [http://projects.jasmeet.me/2013/03/HardCMeans.html Matlab, последовательная реализация]&lt;br /&gt;
&lt;br /&gt;
2) [https://github.com/artpar/Hard-Clustering-implementation С++, последовательная реализация ]&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=22317</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=22317"/>
		<updated>2017-02-06T18:01:54Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Программная реализация алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
Целевая функция алгоритма полностью аналогична целевой функции K-Means[https://ru.wikipedia.org/wiki/K-means].&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \qquad \forall j \neq i \\&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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
Данная операция сводится к использованию ассоциативной &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt; и паттерна Reduse&amp;lt;ref&amp;gt;Reduce paralle pattern [http://www.drdobbs.com/architecture-and-design/parallel-pattern-7-reduce/222000718]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
Последовательная схема реализована в виде python-подобного псевдокода. Для оптимизации вычислений хранится структура, хранящая номер кластера для каждой точки. Это оптимизация с учётом разреженности матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
J_history = []&lt;br /&gt;
c = u[random.choice(N, C), :]&lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
clusterization = zeros(N) # sparse version of M&lt;br /&gt;
&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
    c_new_cnt = zeros(C)&lt;br /&gt;
    c_new = zeros(N, C)&lt;br /&gt;
&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, j_min] = 1&lt;br /&gt;
 &lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[clusterization[i], k] += u[i,k]&lt;br /&gt;
        c_new_cnt[clusterization[i]] += 1&lt;br /&gt;
&lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[j, k] /= c_new_cnt[j]&lt;br /&gt;
&lt;br /&gt;
    c = c_new&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На каждой итерации основного цикла алгоритма:&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; операций вычисления квадратов расстояний до центров кластеров: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; разностей, возведеий в квадрат и &amp;lt;math&amp;gt;NC(D-1)&amp;lt;/math&amp;gt; сумм&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
* Шаг 3 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; сложений&lt;br /&gt;
* Шаг 4 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; векторных умножений на скаляр, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; сложений: &amp;lt;math&amp;gt;ND+C&amp;lt;/math&amp;gt; сложений и &amp;lt;math&amp;gt;CD&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
Итого, одна итерация основного цикла стоит &amp;lt;math&amp;gt;O(3NCD)&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;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_k \}_{k=1}^N \subset \mathbb{R}^D&amp;lt;/math&amp;gt; — исходный набор точек признакового пространства.&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — количество кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;criteria\, params&amp;lt;/math&amp;gt; — параметры критерия останова.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;ND + const&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;M \in \mathbb{R}^{N \times C} &amp;lt;/math&amp;gt; — рядовая матрица&lt;br /&gt;
* &amp;lt;math&amp;gt;\{c_k\}_{k=1}^C&amp;lt;/math&amp;gt; — координаты кластерных центров&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;C(N+D)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Назначение:&#039;&#039;&#039; кластеризация больших наборов числовых данных  представленных признаковыми описаниями объектов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Достоинства:&#039;&#039;&#039;&lt;br /&gt;
* лёгкость реализации&lt;br /&gt;
* вычислительная простота&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки:&#039;&#039;&#039;&lt;br /&gt;
* явное задание количества кластеров&lt;br /&gt;
* отсутствие гарантии нахождения оптимального решения&lt;br /&gt;
* чувствительность к начальному приближению координат кластерных центров&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
Для демонстрации работы алгоритма была создана собственная реализация алгоритма&amp;lt;ref&amp;gt;https://github.com/urandon/hcm_tbb&amp;lt;/ref&amp;gt; с использованием фреймворка Intel® Threading Blocks &amp;lt;ref&amp;gt;https://www.threadingbuildingblocks.org/&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;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
1) [http://projects.jasmeet.me/2013/03/HardCMeans.html Matlab, последовательная реализация]&lt;br /&gt;
&lt;br /&gt;
2) [https://github.com/artpar/Hard-Clustering-implementation С++, последовательная реализация ]&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=22316</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=22316"/>
		<updated>2017-02-06T17:57:31Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Программная реализация алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
Целевая функция алгоритма полностью аналогична целевой функции K-Means[https://ru.wikipedia.org/wiki/K-means].&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \qquad \forall j \neq i \\&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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
Данная операция сводится к использованию ассоциативной &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt; и паттерна Reduse&amp;lt;ref&amp;gt;Reduce paralle pattern [http://www.drdobbs.com/architecture-and-design/parallel-pattern-7-reduce/222000718]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
Последовательная схема реализована в виде python-подобного псевдокода. Для оптимизации вычислений хранится структура, хранящая номер кластера для каждой точки. Это оптимизация с учётом разреженности матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
J_history = []&lt;br /&gt;
c = u[random.choice(N, C), :]&lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
clusterization = zeros(N) # sparse version of M&lt;br /&gt;
&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
    c_new_cnt = zeros(C)&lt;br /&gt;
    c_new = zeros(N, C)&lt;br /&gt;
&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, j_min] = 1&lt;br /&gt;
 &lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[clusterization[i], k] += u[i,k]&lt;br /&gt;
        c_new_cnt[clusterization[i]] += 1&lt;br /&gt;
&lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[j, k] /= c_new_cnt[j]&lt;br /&gt;
&lt;br /&gt;
    c = c_new&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На каждой итерации основного цикла алгоритма:&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; операций вычисления квадратов расстояний до центров кластеров: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; разностей, возведеий в квадрат и &amp;lt;math&amp;gt;NC(D-1)&amp;lt;/math&amp;gt; сумм&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
* Шаг 3 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; сложений&lt;br /&gt;
* Шаг 4 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; векторных умножений на скаляр, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; сложений: &amp;lt;math&amp;gt;ND+C&amp;lt;/math&amp;gt; сложений и &amp;lt;math&amp;gt;CD&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
Итого, одна итерация основного цикла стоит &amp;lt;math&amp;gt;O(3NCD)&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;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_k \}_{k=1}^N \subset \mathbb{R}^D&amp;lt;/math&amp;gt; — исходный набор точек признакового пространства.&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — количество кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;criteria\, params&amp;lt;/math&amp;gt; — параметры критерия останова.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;ND + const&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;M \in \mathbb{R}^{N \times C} &amp;lt;/math&amp;gt; — рядовая матрица&lt;br /&gt;
* &amp;lt;math&amp;gt;\{c_k\}_{k=1}^C&amp;lt;/math&amp;gt; — координаты кластерных центров&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;C(N+D)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Назначение:&#039;&#039;&#039; кластеризация больших наборов числовых данных  представленных признаковыми описаниями объектов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Достоинства:&#039;&#039;&#039;&lt;br /&gt;
* лёгкость реализации&lt;br /&gt;
* вычислительная простота&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки:&#039;&#039;&#039;&lt;br /&gt;
* явное задание количества кластеров&lt;br /&gt;
* отсутствие гарантии нахождения оптимального решения&lt;br /&gt;
* чувствительность к начальному приближению координат кластерных центров&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
Для демонстрации работы алгоритма была создана собственная реализация алгоритма&amp;lt;ref&amp;gt;https://github.com/urandon/hcm_tbb&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;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
1) Matlab, последовательная реализация [http://projects.jasmeet.me/2013/03/HardCMeans.html]&lt;br /&gt;
&lt;br /&gt;
2) С++, последовательная реализация [https://github.com/artpar/Hard-Clustering-implementation]&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=22315</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=22315"/>
		<updated>2017-02-06T17:46:30Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Общее описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
Целевая функция алгоритма полностью аналогична целевой функции K-Means[https://ru.wikipedia.org/wiki/K-means].&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \qquad \forall j \neq i \\&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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
Данная операция сводится к использованию ассоциативной &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt; и паттерна Reduse&amp;lt;ref&amp;gt;Reduce paralle pattern [http://www.drdobbs.com/architecture-and-design/parallel-pattern-7-reduce/222000718]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
Последовательная схема реализована в виде python-подобного псевдокода. Для оптимизации вычислений хранится структура, хранящая номер кластера для каждой точки. Это оптимизация с учётом разреженности матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
J_history = []&lt;br /&gt;
c = u[random.choice(N, C), :]&lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
clusterization = zeros(N) # sparse version of M&lt;br /&gt;
&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
    c_new_cnt = zeros(C)&lt;br /&gt;
    c_new = zeros(N, C)&lt;br /&gt;
&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, j_min] = 1&lt;br /&gt;
 &lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[clusterization[i], k] += u[i,k]&lt;br /&gt;
        c_new_cnt[clusterization[i]] += 1&lt;br /&gt;
&lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[j, k] /= c_new_cnt[j]&lt;br /&gt;
&lt;br /&gt;
    c = c_new&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На каждой итерации основного цикла алгоритма:&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; операций вычисления квадратов расстояний до центров кластеров: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; разностей, возведеий в квадрат и &amp;lt;math&amp;gt;NC(D-1)&amp;lt;/math&amp;gt; сумм&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
* Шаг 3 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; сложений&lt;br /&gt;
* Шаг 4 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; векторных умножений на скаляр, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; сложений: &amp;lt;math&amp;gt;ND+C&amp;lt;/math&amp;gt; сложений и &amp;lt;math&amp;gt;CD&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
Итого, одна итерация основного цикла стоит &amp;lt;math&amp;gt;O(3NCD)&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;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_k \}_{k=1}^N \subset \mathbb{R}^D&amp;lt;/math&amp;gt; — исходный набор точек признакового пространства.&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — количество кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;criteria\, params&amp;lt;/math&amp;gt; — параметры критерия останова.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;ND + const&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;M \in \mathbb{R}^{N \times C} &amp;lt;/math&amp;gt; — рядовая матрица&lt;br /&gt;
* &amp;lt;math&amp;gt;\{c_k\}_{k=1}^C&amp;lt;/math&amp;gt; — координаты кластерных центров&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;C(N+D)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Назначение:&#039;&#039;&#039; кластеризация больших наборов числовых данных  представленных признаковыми описаниями объектов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Достоинства:&#039;&#039;&#039;&lt;br /&gt;
* лёгкость реализации&lt;br /&gt;
* вычислительная простота&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки:&#039;&#039;&#039;&lt;br /&gt;
* явное задание количества кластеров&lt;br /&gt;
* отсутствие гарантии нахождения оптимального решения&lt;br /&gt;
* чувствительность к начальному приближению координат кластерных центров&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=22314</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=22314"/>
		<updated>2017-02-06T17:45:24Z</updated>

		<summary type="html">&lt;p&gt;Urandon: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Строгий алгоритм C средних&#039;&#039;&#039; (&#039;&#039;&#039;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
Целевая функция алгоритма полностью аналогична целевой функции K-Means[https://ru.wikipedia.org/wiki/K-means].&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \qquad \forall j \neq i \\&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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
Данная операция сводится к использованию ассоциативной &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt; и паттерна Reduse&amp;lt;ref&amp;gt;Reduce paralle pattern [http://www.drdobbs.com/architecture-and-design/parallel-pattern-7-reduce/222000718]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
Последовательная схема реализована в виде python-подобного псевдокода. Для оптимизации вычислений хранится структура, хранящая номер кластера для каждой точки. Это оптимизация с учётом разреженности матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
J_history = []&lt;br /&gt;
c = u[random.choice(N, C), :]&lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
clusterization = zeros(N) # sparse version of M&lt;br /&gt;
&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
    c_new_cnt = zeros(C)&lt;br /&gt;
    c_new = zeros(N, C)&lt;br /&gt;
&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, j_min] = 1&lt;br /&gt;
 &lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[clusterization[i], k] += u[i,k]&lt;br /&gt;
        c_new_cnt[clusterization[i]] += 1&lt;br /&gt;
&lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[j, k] /= c_new_cnt[j]&lt;br /&gt;
&lt;br /&gt;
    c = c_new&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На каждой итерации основного цикла алгоритма:&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; операций вычисления квадратов расстояний до центров кластеров: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; разностей, возведеий в квадрат и &amp;lt;math&amp;gt;NC(D-1)&amp;lt;/math&amp;gt; сумм&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
* Шаг 3 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; сложений&lt;br /&gt;
* Шаг 4 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; векторных умножений на скаляр, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; сложений: &amp;lt;math&amp;gt;ND+C&amp;lt;/math&amp;gt; сложений и &amp;lt;math&amp;gt;CD&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
Итого, одна итерация основного цикла стоит &amp;lt;math&amp;gt;O(3NCD)&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;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_k \}_{k=1}^N \subset \mathbb{R}^D&amp;lt;/math&amp;gt; — исходный набор точек признакового пространства.&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — количество кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;criteria\, params&amp;lt;/math&amp;gt; — параметры критерия останова.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;ND + const&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;M \in \mathbb{R}^{N \times C} &amp;lt;/math&amp;gt; — рядовая матрица&lt;br /&gt;
* &amp;lt;math&amp;gt;\{c_k\}_{k=1}^C&amp;lt;/math&amp;gt; — координаты кластерных центров&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;C(N+D)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Назначение:&#039;&#039;&#039; кластеризация больших наборов числовых данных  представленных признаковыми описаниями объектов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Достоинства:&#039;&#039;&#039;&lt;br /&gt;
* лёгкость реализации&lt;br /&gt;
* вычислительная простота&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки:&#039;&#039;&#039;&lt;br /&gt;
* явное задание количества кластеров&lt;br /&gt;
* отсутствие гарантии нахождения оптимального решения&lt;br /&gt;
* чувствительность к начальному приближению координат кластерных центров&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=22091</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=22091"/>
		<updated>2017-02-03T14:17:29Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Макроструктура алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \qquad \forall j \neq i \\&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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
Данная операция сводится к использованию ассоциативной &amp;lt;math&amp;gt;\min&amp;lt;/math&amp;gt; и паттерна Reduse&amp;lt;ref&amp;gt;Reduce paralle pattern [http://www.drdobbs.com/architecture-and-design/parallel-pattern-7-reduce/222000718]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
Последовательная схема реализована в виде python-подобного псевдокода. Для оптимизации вычислений хранится структура, хранящая номер кластера для каждой точки. Это оптимизация с учётом разреженности матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
J_history = []&lt;br /&gt;
c = u[random.choice(N, C), :]&lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
clusterization = zeros(N) # sparse version of M&lt;br /&gt;
&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
    c_new_cnt = zeros(C)&lt;br /&gt;
    c_new = zeros(N, C)&lt;br /&gt;
&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, j_min] = 1&lt;br /&gt;
 &lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[clusterization[i], k] += u[i,k]&lt;br /&gt;
        c_new_cnt[clusterization[i]] += 1&lt;br /&gt;
&lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[j, k] /= c_new_cnt[j]&lt;br /&gt;
&lt;br /&gt;
    c = c_new&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На каждой итерации основного цикла алгоритма:&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; операций вычисления квадратов расстояний до центров кластеров: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; разностей, возведеий в квадрат и &amp;lt;math&amp;gt;NC(D-1)&amp;lt;/math&amp;gt; сумм&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
* Шаг 3 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; сложений&lt;br /&gt;
* Шаг 4 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; векторных умножений на скаляр, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; сложений: &amp;lt;math&amp;gt;ND+C&amp;lt;/math&amp;gt; сложений и &amp;lt;math&amp;gt;CD&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
Итого, одна итерация основного цикла стоит &amp;lt;math&amp;gt;O(3NCD)&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;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_k \}_{k=1}^N \subset \mathbb{R}^D&amp;lt;/math&amp;gt; — исходный набор точек признакового пространства.&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — количество кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;criteria\, params&amp;lt;/math&amp;gt; — параметры критерия останова.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;ND + const&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;M \in \mathbb{R}^{N \times C} &amp;lt;/math&amp;gt; — рядовая матрица&lt;br /&gt;
* &amp;lt;math&amp;gt;\{c_k\}_{k=1}^C&amp;lt;/math&amp;gt; — координаты кластерных центров&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;C(N+D)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Назначение:&#039;&#039;&#039; кластеризация больших наборов числовых данных  представленных признаковыми описаниями объектов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Достоинства:&#039;&#039;&#039;&lt;br /&gt;
* лёгкость реализации&lt;br /&gt;
* вычислительная простота&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки:&#039;&#039;&#039;&lt;br /&gt;
* явное задание количества кластеров&lt;br /&gt;
* отсутствие гарантии нахождения оптимального решения&lt;br /&gt;
* чувствительность к начальному приближению координат кластерных центров&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=21905</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=21905"/>
		<updated>2017-01-31T23:05:57Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \qquad \forall j \neq i \\&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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
Последовательная схема реализована в виде python-подобного псевдокода. Для оптимизации вычислений хранится структура, хранящая номер кластера для каждой точки. Это оптимизация с учётом разреженности матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
J_history = []&lt;br /&gt;
c = u[random.choice(N, C), :]&lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
clusterization = zeros(N) # sparse version of M&lt;br /&gt;
&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
    c_new_cnt = zeros(C)&lt;br /&gt;
    c_new = zeros(N, C)&lt;br /&gt;
&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, j_min] = 1&lt;br /&gt;
 &lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[clusterization[i], k] += u[i,k]&lt;br /&gt;
        c_new_cnt[clusterization[i]] += 1&lt;br /&gt;
&lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[j, k] /= c_new_cnt[j]&lt;br /&gt;
&lt;br /&gt;
    c = c_new&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На каждой итерации основного цикла алгоритма:&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; операций вычисления квадратов расстояний до центров кластеров: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; разностей, возведеий в квадрат и &amp;lt;math&amp;gt;NC(D-1)&amp;lt;/math&amp;gt; сумм&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
* Шаг 3 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; сложений&lt;br /&gt;
* Шаг 4 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; векторных умножений на скаляр, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; сложений: &amp;lt;math&amp;gt;ND+C&amp;lt;/math&amp;gt; сложений и &amp;lt;math&amp;gt;CD&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
Итого, одна итерация основного цикла стоит &amp;lt;math&amp;gt;O(3NCD)&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;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_k \}_{k=1}^N \subset \mathbb{R}^D&amp;lt;/math&amp;gt; — исходный набор точек признакового пространства.&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — количество кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;criteria\, params&amp;lt;/math&amp;gt; — параметры критерия останова.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;ND + const&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;M \in \mathbb{R}^{N \times C} &amp;lt;/math&amp;gt; — рядовая матрица&lt;br /&gt;
* &amp;lt;math&amp;gt;\{c_k\}_{k=1}^C&amp;lt;/math&amp;gt; — координаты кластерных центров&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;C(N+D)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Назначение:&#039;&#039;&#039; кластеризация больших наборов числовых данных  представленных признаковыми описаниями объектов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Достоинства:&#039;&#039;&#039;&lt;br /&gt;
* лёгкость реализации&lt;br /&gt;
* вычислительная простота&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки:&#039;&#039;&#039;&lt;br /&gt;
* явное задание количества кластеров&lt;br /&gt;
* отсутствие гарантии нахождения оптимального решения&lt;br /&gt;
* чувствительность к начальному приближению координат кластерных центров&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=21904</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=21904"/>
		<updated>2017-01-31T23:04:36Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Входные и выходные данные алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \qquad \forall j \neq i \\&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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
Последовательная схема реализована в виде python-подобного псевдокода. Для оптимизации вычислений хранится структура, хранящая номер кластера для каждой точки. Это оптимизация с учётом разреженности матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
J_history = []&lt;br /&gt;
c = u[random.choice(N, C), :]&lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
clusterization = zeros(N) # sparse version of M&lt;br /&gt;
&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
    c_new_cnt = zeros(C)&lt;br /&gt;
    c_new = zeros(N, C)&lt;br /&gt;
&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, j_min] = 1&lt;br /&gt;
 &lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[clusterization[i], k] += u[i,k]&lt;br /&gt;
        c_new_cnt[clusterization[i]] += 1&lt;br /&gt;
&lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[j, k] /= c_new_cnt[j]&lt;br /&gt;
&lt;br /&gt;
    c = c_new&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На каждой итерации основного цикла алгоритма:&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; операций вычисления квадратов расстояний до центров кластеров: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; разностей, возведеий в квадрат и &amp;lt;math&amp;gt;NC(D-1)&amp;lt;/math&amp;gt; сумм&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
* Шаг 3 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; сложений&lt;br /&gt;
* Шаг 4 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; векторных умножений на скаляр, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; сложений: &amp;lt;math&amp;gt;ND+C&amp;lt;/math&amp;gt; сложений и &amp;lt;math&amp;gt;CD&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
Итого, одна итерация основного цикла стоит &amp;lt;math&amp;gt;O(3NCD)&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;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_k \}_{k=1}^N \subset \mathbb{R}^D&amp;lt;/math&amp;gt; — исходный набор точек признакового пространства.&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — количество кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;criteria\, params&amp;lt;/math&amp;gt; — параметры критерия останова.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;ND + const&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;M \in \mathbb{R}^{N \times C} &amp;lt;/math&amp;gt; — рядовая матрица&lt;br /&gt;
* &amp;lt;math&amp;gt;\{c_k\}_{k=1}^C&amp;lt;/math&amp;gt; — координаты кластерных центров&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;C(N+D)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Назначение:&#039;&#039;&#039; кластеризация больших наборов числовых данных  представленных признаковыми описаниями объектов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Достоинства:&#039;&#039;&#039;&lt;br /&gt;
* лёгкость реализации&lt;br /&gt;
* вычислительная простота&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки:&#039;&#039;&#039;&lt;br /&gt;
* явное задание количества кластеров&lt;br /&gt;
* отсутствие гарантии нахождения оптимального решения&lt;br /&gt;
* чувствительность к начальному приближению координат кластерных центров&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=21903</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=21903"/>
		<updated>2017-01-31T23:03:38Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \qquad \forall j \neq i \\&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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
Последовательная схема реализована в виде python-подобного псевдокода. Для оптимизации вычислений хранится структура, хранящая номер кластера для каждой точки. Это оптимизация с учётом разреженности матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
J_history = []&lt;br /&gt;
c = u[random.choice(N, C), :]&lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
clusterization = zeros(N) # sparse version of M&lt;br /&gt;
&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
    c_new_cnt = zeros(C)&lt;br /&gt;
    c_new = zeros(N, C)&lt;br /&gt;
&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, j_min] = 1&lt;br /&gt;
 &lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[clusterization[i], k] += u[i,k]&lt;br /&gt;
        c_new_cnt[clusterization[i]] += 1&lt;br /&gt;
&lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[j, k] /= c_new_cnt[j]&lt;br /&gt;
&lt;br /&gt;
    c = c_new&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На каждой итерации основного цикла алгоритма:&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; операций вычисления квадратов расстояний до центров кластеров: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; разностей, возведеий в квадрат и &amp;lt;math&amp;gt;NC(D-1)&amp;lt;/math&amp;gt; сумм&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
* Шаг 3 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; сложений&lt;br /&gt;
* Шаг 4 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; векторных умножений на скаляр, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; сложений: &amp;lt;math&amp;gt;ND+C&amp;lt;/math&amp;gt; сложений и &amp;lt;math&amp;gt;CD&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
Итого, одна итерация основного цикла стоит &amp;lt;math&amp;gt;O(3NCD)&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;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_k \}_{k=1}^N \subset \mathbb{R}^D&amp;lt;/math&amp;gt; — исходный набор точек признакового пространства.&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — количество кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;criteria params&amp;lt;/math&amp;gt; — параметры критерия останова.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;ND + const&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;M \in \mathbb{R}^{N \times C} &amp;lt;/math&amp;gt; — рядовая матрица&lt;br /&gt;
* &amp;lt;math&amp;gt;\{c_k\}_{k=1}^C&amp;lt;/math&amp;gt; — координаты кластерных центров&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;C(N+D)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Назначение:&#039;&#039;&#039; кластеризация больших наборов числовых данных  представленных признаковыми описаниями объектов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Достоинства:&#039;&#039;&#039;&lt;br /&gt;
* лёгкость реализации&lt;br /&gt;
* вычислительная простота&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки:&#039;&#039;&#039;&lt;br /&gt;
* явное задание количества кластеров&lt;br /&gt;
* отсутствие гарантии нахождения оптимального решения&lt;br /&gt;
* чувствительность к начальному приближению координат кластерных центров&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=21902</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=21902"/>
		<updated>2017-01-31T23:03:24Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \forall j \neq i \\&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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
Последовательная схема реализована в виде python-подобного псевдокода. Для оптимизации вычислений хранится структура, хранящая номер кластера для каждой точки. Это оптимизация с учётом разреженности матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
J_history = []&lt;br /&gt;
c = u[random.choice(N, C), :]&lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
clusterization = zeros(N) # sparse version of M&lt;br /&gt;
&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
    c_new_cnt = zeros(C)&lt;br /&gt;
    c_new = zeros(N, C)&lt;br /&gt;
&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, j_min] = 1&lt;br /&gt;
 &lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[clusterization[i], k] += u[i,k]&lt;br /&gt;
        c_new_cnt[clusterization[i]] += 1&lt;br /&gt;
&lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[j, k] /= c_new_cnt[j]&lt;br /&gt;
&lt;br /&gt;
    c = c_new&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На каждой итерации основного цикла алгоритма:&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; операций вычисления квадратов расстояний до центров кластеров: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; разностей, возведеий в квадрат и &amp;lt;math&amp;gt;NC(D-1)&amp;lt;/math&amp;gt; сумм&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
* Шаг 3 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; сложений&lt;br /&gt;
* Шаг 4 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; векторных умножений на скаляр, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; сложений: &amp;lt;math&amp;gt;ND+C&amp;lt;/math&amp;gt; сложений и &amp;lt;math&amp;gt;CD&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
Итого, одна итерация основного цикла стоит &amp;lt;math&amp;gt;O(3NCD)&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;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_k \}_{k=1}^N \subset \mathbb{R}^D&amp;lt;/math&amp;gt; — исходный набор точек признакового пространства.&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — количество кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;criteria params&amp;lt;/math&amp;gt; — параметры критерия останова.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;ND + const&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;M \in \mathbb{R}^{N \times C} &amp;lt;/math&amp;gt; — рядовая матрица&lt;br /&gt;
* &amp;lt;math&amp;gt;\{c_k\}_{k=1}^C&amp;lt;/math&amp;gt; — координаты кластерных центров&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;C(N+D)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Назначение:&#039;&#039;&#039; кластеризация больших наборов числовых данных  представленных признаковыми описаниями объектов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Достоинства:&#039;&#039;&#039;&lt;br /&gt;
* лёгкость реализации&lt;br /&gt;
* вычислительная простота&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки:&#039;&#039;&#039;&lt;br /&gt;
* явное задание количества кластеров&lt;br /&gt;
* отсутствие гарантии нахождения оптимального решения&lt;br /&gt;
* чувствительность к начальному приближению координат кластерных центров&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=21901</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=21901"/>
		<updated>2017-01-31T23:01:18Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
m_{ik} = \begin{cases}&lt;br /&gt;
1, &amp;amp; \|u_k-c_i\|^2 \leqslant \|u_k-c_j\|^2 \\&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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
Последовательная схема реализована в виде python-подобного псевдокода. Для оптимизации вычислений хранится структура, хранящая номер кластера для каждой точки. Это оптимизация с учётом разреженности матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
J_history = []&lt;br /&gt;
c = u[random.choice(N, C), :]&lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
clusterization = zeros(N) # sparse version of M&lt;br /&gt;
&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
    c_new_cnt = zeros(C)&lt;br /&gt;
    c_new = zeros(N, C)&lt;br /&gt;
&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, j_min] = 1&lt;br /&gt;
 &lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[clusterization[i], k] += u[i,k]&lt;br /&gt;
        c_new_cnt[clusterization[i]] += 1&lt;br /&gt;
&lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[j, k] /= c_new_cnt[j]&lt;br /&gt;
&lt;br /&gt;
    c = c_new&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На каждой итерации основного цикла алгоритма:&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; операций вычисления квадратов расстояний до центров кластеров: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; разностей, возведеий в квадрат и &amp;lt;math&amp;gt;NC(D-1)&amp;lt;/math&amp;gt; сумм&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
* Шаг 3 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; сложений&lt;br /&gt;
* Шаг 4 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; векторных умножений на скаляр, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; сложений: &amp;lt;math&amp;gt;ND+C&amp;lt;/math&amp;gt; сложений и &amp;lt;math&amp;gt;CD&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
Итого, одна итерация основного цикла стоит &amp;lt;math&amp;gt;O(3NCD)&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;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_k \}_{k=1}^N \subset \mathbb{R}^D&amp;lt;/math&amp;gt; — исходный набор точек признакового пространства.&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — количество кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;criteria params&amp;lt;/math&amp;gt; — параметры критерия останова.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;ND + const&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;M \in \mathbb{R}^{N \times C} &amp;lt;/math&amp;gt; — рядовая матрица&lt;br /&gt;
* &amp;lt;math&amp;gt;\{c_k\}_{k=1}^C&amp;lt;/math&amp;gt; — координаты кластерных центров&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;C(N+D)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Назначение:&#039;&#039;&#039; кластеризация больших наборов числовых данных  представленных признаковыми описаниями объектов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Достоинства:&#039;&#039;&#039;&lt;br /&gt;
* лёгкость реализации&lt;br /&gt;
* вычислительная простота&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки:&#039;&#039;&#039;&lt;br /&gt;
* явное задание количества кластеров&lt;br /&gt;
* отсутствие гарантии нахождения оптимального решения&lt;br /&gt;
* чувствительность к начальному приближению координат кластерных центров&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=21900</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=21900"/>
		<updated>2017-01-31T22:59:51Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Свойства алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
Последовательная схема реализована в виде python-подобного псевдокода. Для оптимизации вычислений хранится структура, хранящая номер кластера для каждой точки. Это оптимизация с учётом разреженности матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
J_history = []&lt;br /&gt;
c = u[random.choice(N, C), :]&lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
clusterization = zeros(N) # sparse version of M&lt;br /&gt;
&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
    c_new_cnt = zeros(C)&lt;br /&gt;
    c_new = zeros(N, C)&lt;br /&gt;
&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, j_min] = 1&lt;br /&gt;
 &lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[clusterization[i], k] += u[i,k]&lt;br /&gt;
        c_new_cnt[clusterization[i]] += 1&lt;br /&gt;
&lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[j, k] /= c_new_cnt[j]&lt;br /&gt;
&lt;br /&gt;
    c = c_new&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На каждой итерации основного цикла алгоритма:&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; операций вычисления квадратов расстояний до центров кластеров: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; разностей, возведеий в квадрат и &amp;lt;math&amp;gt;NC(D-1)&amp;lt;/math&amp;gt; сумм&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
* Шаг 3 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; сложений&lt;br /&gt;
* Шаг 4 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; векторных умножений на скаляр, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; сложений: &amp;lt;math&amp;gt;ND+C&amp;lt;/math&amp;gt; сложений и &amp;lt;math&amp;gt;CD&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
Итого, одна итерация основного цикла стоит &amp;lt;math&amp;gt;O(3NCD)&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;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_k \}_{k=1}^N \subset \mathbb{R}^D&amp;lt;/math&amp;gt; — исходный набор точек признакового пространства.&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — количество кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;criteria params&amp;lt;/math&amp;gt; — параметры критерия останова.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;ND + const&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;M \in \mathbb{R}^{N \times C} &amp;lt;/math&amp;gt; — рядовая матрица&lt;br /&gt;
* &amp;lt;math&amp;gt;\{c_k\}_{k=1}^C&amp;lt;/math&amp;gt; — координаты кластерных центров&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;C(N+D)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Назначение:&#039;&#039;&#039; кластеризация больших наборов числовых данных  представленных признаковыми описаниями объектов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Достоинства:&#039;&#039;&#039;&lt;br /&gt;
* лёгкость реализации&lt;br /&gt;
* вычислительная простота&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Недостатки:&#039;&#039;&#039;&lt;br /&gt;
* явное задание количества кластеров&lt;br /&gt;
* отсутствие гарантии нахождения оптимального решения&lt;br /&gt;
* чувствительность к начальному приближению координат кластерных центров&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=21899</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=21899"/>
		<updated>2017-01-31T22:57:39Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Входные и выходные данные алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
Последовательная схема реализована в виде python-подобного псевдокода. Для оптимизации вычислений хранится структура, хранящая номер кластера для каждой точки. Это оптимизация с учётом разреженности матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
J_history = []&lt;br /&gt;
c = u[random.choice(N, C), :]&lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
clusterization = zeros(N) # sparse version of M&lt;br /&gt;
&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
    c_new_cnt = zeros(C)&lt;br /&gt;
    c_new = zeros(N, C)&lt;br /&gt;
&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, j_min] = 1&lt;br /&gt;
 &lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[clusterization[i], k] += u[i,k]&lt;br /&gt;
        c_new_cnt[clusterization[i]] += 1&lt;br /&gt;
&lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[j, k] /= c_new_cnt[j]&lt;br /&gt;
&lt;br /&gt;
    c = c_new&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На каждой итерации основного цикла алгоритма:&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; операций вычисления квадратов расстояний до центров кластеров: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; разностей, возведеий в квадрат и &amp;lt;math&amp;gt;NC(D-1)&amp;lt;/math&amp;gt; сумм&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
* Шаг 3 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; сложений&lt;br /&gt;
* Шаг 4 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; векторных умножений на скаляр, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; сложений: &amp;lt;math&amp;gt;ND+C&amp;lt;/math&amp;gt; сложений и &amp;lt;math&amp;gt;CD&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
Итого, одна итерация основного цикла стоит &amp;lt;math&amp;gt;O(3NCD)&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;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_k \}_{k=1}^N \subset \mathbb{R}^D&amp;lt;/math&amp;gt; — исходный набор точек признакового пространства.&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — количество кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;criteria params&amp;lt;/math&amp;gt; — параметры критерия останова.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;ND + const&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;M \in \mathbb{R}^{N \times C} &amp;lt;/math&amp;gt; — рядовая матрица&lt;br /&gt;
* &amp;lt;math&amp;gt;\{c_k\}_{k=1}^C&amp;lt;/math&amp;gt; — координаты кластерных центров&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;C(N+D)&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;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=21898</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=21898"/>
		<updated>2017-01-31T22:55:58Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Входные и выходные данные алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
Последовательная схема реализована в виде python-подобного псевдокода. Для оптимизации вычислений хранится структура, хранящая номер кластера для каждой точки. Это оптимизация с учётом разреженности матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
J_history = []&lt;br /&gt;
c = u[random.choice(N, C), :]&lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
clusterization = zeros(N) # sparse version of M&lt;br /&gt;
&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
    c_new_cnt = zeros(C)&lt;br /&gt;
    c_new = zeros(N, C)&lt;br /&gt;
&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, j_min] = 1&lt;br /&gt;
 &lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[clusterization[i], k] += u[i,k]&lt;br /&gt;
        c_new_cnt[clusterization[i]] += 1&lt;br /&gt;
&lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[j, k] /= c_new_cnt[j]&lt;br /&gt;
&lt;br /&gt;
    c = c_new&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На каждой итерации основного цикла алгоритма:&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; операций вычисления квадратов расстояний до центров кластеров: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; разностей, возведеий в квадрат и &amp;lt;math&amp;gt;NC(D-1)&amp;lt;/math&amp;gt; сумм&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
* Шаг 3 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; сложений&lt;br /&gt;
* Шаг 4 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; векторных умножений на скаляр, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; сложений: &amp;lt;math&amp;gt;ND+C&amp;lt;/math&amp;gt; сложений и &amp;lt;math&amp;gt;CD&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
Итого, одна итерация основного цикла стоит &amp;lt;math&amp;gt;O(3NCD)&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;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_k \}_{k=1}^N \subset \mathbb{R}^D&amp;lt;/math&amp;gt; — исходный набор точек признакового пространства.&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — количество кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;criteria params&amp;lt;/math&amp;gt; — параметры критерия останова.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;ND + const&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;M \in \mathbb{R}^{N \times 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;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=21897</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=21897"/>
		<updated>2017-01-31T22:55:23Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Входные и выходные данные алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
Последовательная схема реализована в виде python-подобного псевдокода. Для оптимизации вычислений хранится структура, хранящая номер кластера для каждой точки. Это оптимизация с учётом разреженности матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
J_history = []&lt;br /&gt;
c = u[random.choice(N, C), :]&lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
clusterization = zeros(N) # sparse version of M&lt;br /&gt;
&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
    c_new_cnt = zeros(C)&lt;br /&gt;
    c_new = zeros(N, C)&lt;br /&gt;
&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, j_min] = 1&lt;br /&gt;
 &lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[clusterization[i], k] += u[i,k]&lt;br /&gt;
        c_new_cnt[clusterization[i]] += 1&lt;br /&gt;
&lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[j, k] /= c_new_cnt[j]&lt;br /&gt;
&lt;br /&gt;
    c = c_new&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На каждой итерации основного цикла алгоритма:&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; операций вычисления квадратов расстояний до центров кластеров: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; разностей, возведеий в квадрат и &amp;lt;math&amp;gt;NC(D-1)&amp;lt;/math&amp;gt; сумм&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
* Шаг 3 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; сложений&lt;br /&gt;
* Шаг 4 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; векторных умножений на скаляр, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; сложений: &amp;lt;math&amp;gt;ND+C&amp;lt;/math&amp;gt; сложений и &amp;lt;math&amp;gt;CD&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
Итого, одна итерация основного цикла стоит &amp;lt;math&amp;gt;O(3NCD)&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;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;\{ u_k \}_{k=1}^N \subset \mathbb{R}^D&amp;lt;/math&amp;gt; — исходный набор точек признакового пространства.&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; — количество кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;criteria params&amp;lt;/math&amp;gt; — параметры критерия останова.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;ND + \const&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt;M \in \mathbb{R}^{N \cross 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;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=21895</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=21895"/>
		<updated>2017-01-31T22:49:43Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Последовательная сложность алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
Последовательная схема реализована в виде python-подобного псевдокода. Для оптимизации вычислений хранится структура, хранящая номер кластера для каждой точки. Это оптимизация с учётом разреженности матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
J_history = []&lt;br /&gt;
c = u[random.choice(N, C), :]&lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
clusterization = zeros(N) # sparse version of M&lt;br /&gt;
&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
    c_new_cnt = zeros(C)&lt;br /&gt;
    c_new = zeros(N, C)&lt;br /&gt;
&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, j_min] = 1&lt;br /&gt;
 &lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[clusterization[i], k] += u[i,k]&lt;br /&gt;
        c_new_cnt[clusterization[i]] += 1&lt;br /&gt;
&lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[j, k] /= c_new_cnt[j]&lt;br /&gt;
&lt;br /&gt;
    c = c_new&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На каждой итерации основного цикла алгоритма:&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; операций вычисления квадратов расстояний до центров кластеров: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; разностей, возведеий в квадрат и &amp;lt;math&amp;gt;NC(D-1)&amp;lt;/math&amp;gt; сумм&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
* Шаг 3 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; сложений&lt;br /&gt;
* Шаг 4 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; векторных умножений на скаляр, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; сложений: &amp;lt;math&amp;gt;ND+C&amp;lt;/math&amp;gt; сложений и &amp;lt;math&amp;gt;CD&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
Итого, одна итерация основного цикла стоит &amp;lt;math&amp;gt;O(3NCD)&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;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=21894</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=21894"/>
		<updated>2017-01-31T22:49:25Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Последовательная сложность алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
Последовательная схема реализована в виде python-подобного псевдокода. Для оптимизации вычислений хранится структура, хранящая номер кластера для каждой точки. Это оптимизация с учётом разреженности матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
J_history = []&lt;br /&gt;
c = u[random.choice(N, C), :]&lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
clusterization = zeros(N) # sparse version of M&lt;br /&gt;
&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
    c_new_cnt = zeros(C)&lt;br /&gt;
    c_new = zeros(N, C)&lt;br /&gt;
&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, j_min] = 1&lt;br /&gt;
 &lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[clusterization[i], k] += u[i,k]&lt;br /&gt;
        c_new_cnt[clusterization[i]] += 1&lt;br /&gt;
&lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[j, k] /= c_new_cnt[j]&lt;br /&gt;
&lt;br /&gt;
    c = c_new&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На каждой итерации основного цикла алгоритма:&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; операций вычисления квадратов расстояний до центров кластеров: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; разностей, возведеий в квадрат и &amp;lt;math&amp;gt;NC(D-1)&amp;lt;/math&amp;gt; сумм&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
* Шаг 3 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; сложений&lt;br /&gt;
* Шаг 4 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; векторных умножений на скаляр, &amp;lt;math&amp;gt;С&amp;lt;/math&amp;gt; сложений: &amp;lt;math&amp;gt;ND+C&amp;lt;/math&amp;gt; сложений и &amp;lt;math&amp;gt;СD&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
Итого, одна итерация основного цикла стоит &amp;lt;math&amp;gt;O(3NCD)&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;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=21893</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=21893"/>
		<updated>2017-01-31T22:48:35Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Последовательная сложность алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
Последовательная схема реализована в виде python-подобного псевдокода. Для оптимизации вычислений хранится структура, хранящая номер кластера для каждой точки. Это оптимизация с учётом разреженности матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
J_history = []&lt;br /&gt;
c = u[random.choice(N, C), :]&lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
clusterization = zeros(N) # sparse version of M&lt;br /&gt;
&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
    c_new_cnt = zeros(C)&lt;br /&gt;
    c_new = zeros(N, C)&lt;br /&gt;
&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, j_min] = 1&lt;br /&gt;
 &lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[clusterization[i], k] += u[i,k]&lt;br /&gt;
        c_new_cnt[clusterization[i]] += 1&lt;br /&gt;
&lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[j, k] /= c_new_cnt[j]&lt;br /&gt;
&lt;br /&gt;
    c = c_new&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На каждой итерации основного цикла алгоритма:&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; операций вычисления квадратов расстояний до центров кластеров: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; разностей, возведеий в квадрат и &amp;lt;math&amp;gt;NC(D-1)&amp;lt;/math&amp;gt; сумм&lt;br /&gt;
* Шаг 2 &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
* Шаг 3 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений: &amp;lt;math&amp;gt;NCD&amp;lt;/math&amp;gt; сложений&lt;br /&gt;
* Шаг 4 &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; векторных сложений, &amp;lt;math&amp;gt;С&amp;lt;/math&amp;gt; векторных умножений на скаляр, &amp;lt;math&amp;gt;С&amp;lt;/math&amp;gt; сложений: &amp;lt;math&amp;gt;ND+C&amp;lt;/math&amp;gt; сложений и &amp;lt;math&amp;gt;СD&amp;lt;/math&amp;gt; умножений.&lt;br /&gt;
&lt;br /&gt;
Итого, одна итерация основного цикла стоит &amp;lt;math&amp;gt;O(3NCD)&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;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=21889</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=21889"/>
		<updated>2017-01-31T22:06:05Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Схема реализации последовательного алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
Последовательная схема реализована в виде python-подобного псевдокода. Для оптимизации вычислений хранится структура, хранящая номер кластера для каждой точки. Это оптимизация с учётом разреженности матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
J_history = []&lt;br /&gt;
c = u[random.choice(N, C), :]&lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
clusterization = zeros(N) # sparse version of M&lt;br /&gt;
&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
    c_new_cnt = zeros(C)&lt;br /&gt;
    c_new = zeros(N, C)&lt;br /&gt;
&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, j_min] = 1&lt;br /&gt;
 &lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[clusterization[i], k] += u[i,k]&lt;br /&gt;
        c_new_cnt[clusterization[i]] += 1&lt;br /&gt;
&lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[j, k] /= c_new_cnt[j]&lt;br /&gt;
&lt;br /&gt;
    c = c_new&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=21888</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=21888"/>
		<updated>2017-01-31T22:02:49Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Схема реализации последовательного алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
J_history = []&lt;br /&gt;
c = u[random.choice(N, C), :]&lt;br /&gt;
M = zeros(N, C)&lt;br /&gt;
clusterization = zeros(N) # sparse version of M&lt;br /&gt;
&lt;br /&gt;
while not stop_criteria(J_history):&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
    c_new_cnt = zeros(C)&lt;br /&gt;
    c_new = zeros(N, C)&lt;br /&gt;
&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        M[i, clusterization[i]] = 0&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
            for k in range(D):&lt;br /&gt;
                d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
            if d_ij &amp;lt; d_min:&lt;br /&gt;
                d_min, j_min = d_ij, j&lt;br /&gt;
&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
        clusterization[i] = j_min&lt;br /&gt;
        M[i, j_min] = 1&lt;br /&gt;
 &lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[clusterization[i], k] += u[i,k]&lt;br /&gt;
        c_new_cnt[clusterization[i]] += 1&lt;br /&gt;
&lt;br /&gt;
    J_history.append(J_curr)&lt;br /&gt;
    &lt;br /&gt;
    for j in range(C):&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            c_new[j, k] /= c_new_cnt[j]&lt;br /&gt;
&lt;br /&gt;
    c = c_new&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=21887</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=21887"/>
		<updated>2017-01-31T21:50:40Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Макроструктура алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{k=1}^N d_{k, C(u_k)} &amp;lt;/math&amp;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;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
J = []&lt;br /&gt;
c = u[random.choice(N, C), :]&lt;br /&gt;
while not stop_criteria(J):&lt;br /&gt;
    M = zeros(N, C)&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
        if d_ij &amp;lt; d_min:&lt;br /&gt;
            d_min, j_min = d_ij, j&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
        M[i, j_min] = 1&lt;br /&gt;
    J.append(J_curr)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=21886</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=21886"/>
		<updated>2017-01-31T21:48:55Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Схема реализации последовательного алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{i=1}^C\sum\limits_{k=1}^N m_{ik} d_{ik}&amp;lt;/math&amp;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;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
J = []&lt;br /&gt;
c = u[random.choice(N, C), :]&lt;br /&gt;
while not stop_criteria(J):&lt;br /&gt;
    M = zeros(N, C)&lt;br /&gt;
    J_curr = 0&lt;br /&gt;
    for i in range(N):&lt;br /&gt;
        d_min, j_min = +inf, None&lt;br /&gt;
        for j in range(C):&lt;br /&gt;
            d_ij = 0&lt;br /&gt;
        for k in range(D):&lt;br /&gt;
            d_ij += (u[i,k] - c[j,k])**2&lt;br /&gt;
        if d_ij &amp;lt; d_min:&lt;br /&gt;
            d_min, j_min = d_ij, j&lt;br /&gt;
        J_curr += d_min&lt;br /&gt;
        M[i, j_min] = 1&lt;br /&gt;
    J.append(J_curr)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=21883</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=21883"/>
		<updated>2017-01-31T21:32:49Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Макроструктура алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{i=1}^C\sum\limits_{k=1}^N m_{ik} d_{ik}&amp;lt;/math&amp;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;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=21881</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=21881"/>
		<updated>2017-01-31T21:31:55Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Макроструктура алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Суммирование всех элементов матрицы с заранее определёнными индексами&lt;br /&gt;
&amp;lt;math&amp;gt; J = \sum\limits_{i=1}^C J_i = \sum\limits_{i=1}^C \left( \sum\limits_{k:\, u_k \in C_i} d_{ki} \right) = \sum\limits_{i=1}^C\sum\limits_{k=1}^N m_{ik} d_{ik}&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;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=21880</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=21880"/>
		<updated>2017-01-31T21:29:21Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Макроструктура алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;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} d_{ki} \right) = \sum\limits_{i=1}^C\sum\limits_{k=1}^N m_{ik} d_{ik} = \mathbf{e} M \odot D \mathbf{e}^T&lt;br /&gt;
.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=21879</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=21879"/>
		<updated>2017-01-31T21:29:08Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Макроструктура алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;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} d_{ki} \right) = \sum\limits_{i=1}^C\sum\limits_{k=1}^N m_{ik} d_{ik} = \mathbf{e} M \odot D \mathfb{e}^T&lt;br /&gt;
.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</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:Urandon/%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,_HCM)&amp;diff=21878</id>
		<title>Участник:Urandon/Строгий алгоритм С средних (Hard C-Means, HCM)</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:Urandon/%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,_HCM)&amp;diff=21878"/>
		<updated>2017-01-31T21:28:43Z</updated>

		<summary type="html">&lt;p&gt;Urandon: /* Макроструктура алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;Hard C-Means&#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;Jan Jantzen (1998). [http://faculty.petra.ac.id/resmana/private/fuzzy/nfmod.pdf 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;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
На вход алгоритм принимает точки &amp;lt;math&amp;gt;\{u_k\}_{k=1}^{N}&amp;lt;/math&amp;gt; признакового пространства &amp;lt;math&amp;gt;\mathbb{R}^D&amp;lt;/math&amp;gt; и количество кластеров &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На выходе алгоритм возвращает рядовую матрицу&amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, содержащую информацию о принадлежности элементов кластерам:&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
m_{ij} = \begin{cases}&lt;br /&gt;
1, &amp;amp; u_j \in C_i, \\&lt;br /&gt;
0, &amp;amp; \text{otherwise},&lt;br /&gt;
\end{cases}&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;-му кластеру, и а &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;
Алгоритм состоит из пяти шагов&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;
&#039;&#039;&#039;&#039;&#039;Шаг 1 – инициализация центров кластеров&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; c_i \sim Uniform \{u_1, \dots, u_N\} &amp;lt;/math&amp;gt; -- инициализация путём&lt;br /&gt;
случайного выбора центров кластеров из точек входного набора. Начальные центры кластером так же могут быть заданы пользователем явно. &amp;lt;math&amp;gt;test&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 2 – вычисление рядовой матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;M = \|m_{ik}\|&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;
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;
где &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — количество элементов во входном наборе данных.&lt;br /&gt;
&lt;br /&gt;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{M}&amp;lt;/math&amp;gt; при условии, что каждый объект попадает хотя бы в один кластер.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 3 – расчёт целевого функционала&#039;&#039;&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 4 – пересчёт кластерных центров&#039;&#039;&#039;&#039;&#039;&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;
Представляет собой шаг &amp;lt;math&amp;gt;J \to \min_{c_1, \dots, c_N}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Шаг 5 – зацикливание&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Переход по циклу к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для каждой пары &amp;lt;math&amp;gt;\{u_i, c_k\}, i \in \mathbb{N}_N, k \in \mathbb{N}_C&amp;lt;/math&amp;gt; согласно алгоритму необходимо вычислить расстояние &amp;lt;math&amp;gt;\|u_i - c_k\|^2&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt;-мерном пространстве. Такие расстояние вычисляются для &amp;lt;math&amp;gt;NC&amp;lt;/math&amp;gt; пар. Таким образом, происходит вычисление &amp;lt;math&amp;gt;O(NCD)&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;
&amp;lt;math&amp;gt;&lt;br /&gt;
d_{ik} = \|u_k - c_i\|^2&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нахождение аргминимума в векторе при фиксированном объекте &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt; i^* = \arg\!\min\limits_{i = 1 \dots C} d_{ik} &amp;lt;/math&amp;gt;.&lt;br /&gt;
После чего &amp;lt;math&amp;gt;m_{ik} := [i = i^*]&amp;lt;/math&amp;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} d_{ki} \right) = \sum\limits_{i=1}^C\sum\limits_{k=1}^N m_{ik} d_{ik} = \mathbb{e} M \odot D \mathbb{e}^T&lt;br /&gt;
.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Urandon</name></author>
	</entry>
</feed>