<?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=Demon+smd</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=Demon+smd"/>
	<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/Demon_smd"/>
	<updated>2026-10-22T16:45:49Z</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=21285</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=21285"/>
		<updated>2016-12-18T21:13:47Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Coctic}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Нечеткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(C^2*|X|*D*IterNumber)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(\log_{2}C^4*|X|^3) * IterNumber&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(C^2*|X|)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;|X|*p&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - размерность входных векторов&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;|X|*C &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: &lt;br /&gt;
[[Участник:Demon smd|Д.А.Гуськов]] &lt;br /&gt;
[[Участник:marina abramenkova|М.А.Абраменкова]].&lt;br /&gt;
Во все разделы вклад равноценный.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризуемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних заключается в следующем. Изначально для каждого вектора определяется случайным образом вероятность принадлежности вектора к каждому кластеру. Далее запускается итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) расчёт центров кластеров&lt;br /&gt;
&lt;br /&gt;
2) расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации: если разница этих значений меньше установленного значения, то алгоритм прекращает работу (решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности)&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{i = 1}^{|X|}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty , \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;|X|&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - количество кластеров, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные на каждой итерации ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^{(k)} - u_{i,j}^{(k-1)}|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&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;
В каждой итерации алгоритма происходит 3 основных действия описанных в п. 1.2.1:&lt;br /&gt;
*вычисление центров кластеров&lt;br /&gt;
*вычисление коэффициентов принадлежности&lt;br /&gt;
*вычисление решающей функции&lt;br /&gt;
Подробное описание макроструктур в виде кода приведено в пункте 1.5&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Схему реализации последовательного алгоритма можно описать на C++ следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FCM (X[], C, m, eps){&lt;br /&gt;
    float deside = 0;&lt;br /&gt;
    float newDeside = 0;&lt;br /&gt;
    generateMembershipDegree();            //заполняет uPrev[][] случайными нормрованными коэффициентами&lt;br /&gt;
    while (true){&lt;br /&gt;
        newDeside = deside;&lt;br /&gt;
&lt;br /&gt;
        //вычисление центров кластеров&lt;br /&gt;
        for (int j=0; j&amp;lt;C; j++){           //для каждого кластера&lt;br /&gt;
            float numerator = 0;&lt;br /&gt;
            float denumerator = 0;&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++){        //для каждого вектора&lt;br /&gt;
                numerator+=pow(u[i][j], m) * x[i];&lt;br /&gt;
                denumerator+=pow(u[i][j], m);&lt;br /&gt;
            }&lt;br /&gt;
            c[j] = numerator / denumerator;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //вычисление коэффициентов u[][]&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                sum = 0;&lt;br /&gt;
                for (int k=0; k&amp;lt;C; k++)&lt;br /&gt;
                    sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&lt;br /&gt;
                u[i][j] = 1/sum&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        //определения максимального различия между u[][] и uPrev[][]&lt;br /&gt;
        float max = 0;&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                if (abs(uPrev[i][j]-u[i][j])&amp;gt;max)&lt;br /&gt;
                    max = abs(uPrev[i][j]-u[i][j]);&lt;br /&gt;
&lt;br /&gt;
        if (eps &amp;lt;= max)&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
                for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                    uPrev[i][j]=u[i][j];&lt;br /&gt;
        else&lt;br /&gt;
            break;&lt;br /&gt;
             &lt;br /&gt;
    }&lt;br /&gt;
    return u;&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;
Под операцией будем понимать выражение в языке с++ из пункта 1.5, находящееся в теле цикла (например, выражения &amp;quot;sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&amp;quot; или &amp;quot;uPrev[i][j]=u[i][j];&amp;quot; считаются за одну операцию). Так как при больших входных объёмах данных сложность алгоритма в большей степени зависит от количества входных данных, и незначительно зависит от сложности операций,то при оценке сложности алгоритма сложность выражений можно считать равной единице. Так как в данном алгоритме количество итераций не является фиксированным и зависит от:&lt;br /&gt;
* параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
* набора входных векторов &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
* выбора начальных коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;&lt;br /&gt;
то в данном пункте будет приведена сложность одной итерации относительно количества входных векторов.&lt;br /&gt;
Для вычисления коэффициентов  u[][] на каждой итерации алгоритма требуется определить расстояние от векторов до центра кластера. Сложность данной операции зависит от размерности входных данных и определении нормы. В виду того, что для разных задач могут быть введены разные нормы, и сложность вычисления расстояний может варьироваться, то в данной статье будем считать, что сложность вычисления расстояния зависит линейно от размерности водных данных. В таком случае, для вычисления центров кластеров требуется &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, для определения коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;O(C^2*|X|*D)&amp;lt;/math&amp;gt; операций, а для вычисления решающей функции - &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, где &amp;lt;math&amp;gt;|X|&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;O(C^2*|X|*D)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Как видно из пункта 1.5, на каждом действии каждой итерации алгоритма все операции, выполняющиеся в цикле, не зависят друг от друга и могут быть распараллелены. Это показано на Рисунке 1.&lt;br /&gt;
&lt;br /&gt;
[[File:FCMIG.png|thumb|center|1200px|Рисунок 1. Информационный граф алгоритма. (1)-(7) - это наборы последовательных действий (например, (2) - последовательные операции деления, чтения элемента из памяти и присваивания).]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На каждом ярусе ярусно-параллельной формы алгоритма будет располагаться конечное число элементарных операций, например, чтение элемента из памяти, сложение или возведение в степень. Информационый граф из п.1.7 изображает свёрнутую ярусно-параллельную форму алгоритма. &lt;br /&gt;
&lt;br /&gt;
Сложность алгоритма будем рассчитывать в предположении, что число вычислительных ядер стремится к бесконечности. Как видно из информационного графа, параллельная сложность вычисления центров кластеров составляет &amp;lt;math&amp;gt;O(\log_{2}(C*|X|))&amp;lt;/math&amp;gt;, вычисления коэффициентов принадлежности - &amp;lt;math&amp;gt;O(\log_{2}(C^2*|X|))&amp;lt;/math&amp;gt;, а вычисления решающей функции - не больше чем &amp;lt;math&amp;gt;O(\log_{2} (C*|X|))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом параллельная сложность итерации алгоритма составляет &amp;lt;math&amp;gt;O(\log_{2} (C^4*|X|^3))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Так как задачи, решаемые в макроструктуре алгоритма могут быть сведены к задачам вычисления суммы элементов массива и максимального элемента массива, то на &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом ярусе графа будет находиться &amp;lt;math&amp;gt;{N}\over{2^i}&amp;lt;/math&amp;gt; операции, где N - количество элементов массива.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; - набор из &amp;lt;math&amp;gt;|X|&amp;lt;/math&amp;gt; входных векторов длины &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - количество кластеров&lt;br /&gt;
* &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
Объем входных данных: &amp;lt;math&amp;gt;|X|*p+3&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - матрица принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
Объем выходных данных: &amp;lt;math&amp;gt;|X|*C&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Увеличение скорости работы алгоритма при распараллеливании на бесконечном количестве процессоров составляет &amp;lt;math&amp;gt;O({{C^2*|X|}\over{\log_{2} (C^4*|X|^3)}})&amp;lt;/math&amp;gt;. Например, для разбиения 1000 элементов на 10 кластеров производительность параллельного алгоритма будет в 2315 раз больше, а на 20 кластеров - уже в 8477 раз.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
Как видно из предыдущих пунктов, масштабируется данный алгоритм хорошо. С увеличением количества процессоров время работы падает, а с увеличением количества входных данных и количества кластеров - растёт. &lt;br /&gt;
На рисунках показаны результаты запусков алгоритма на разном количестве входных данных и процессоров на массивно-параллельной вычислительной системе Blue Gene/P. Использовался компилятор mpixlcxx без указания специфических опций. Запуски производились в режиме SMP (на каждом ядре 1 MPI процесс из 4 SMP нитей, 2 Гб памяти). Характеристики вычислительного узла: 4 ядерный 32-битный процессор PowerPC 850 Мгц.&lt;br /&gt;
&lt;br /&gt;
Исходных код программы можно найти здесь: https://github.com/demonsmd/superPrak&lt;br /&gt;
[[File:FCMvectors_color2.png|thumb|center|1250px|Рисунок 2. Масштабируемость алгоритма. Зависимость времени работы алгоритма от количества процессоров и входных данных при фиксированном количестве кластеров.]]&lt;br /&gt;
[[File:FCMclusters_color.png|thumb|center|1250px|Рисунок 3. Масштабируемость алгоритма. Зависимость времени работы алгоритма от количества процессоров и кластеров при фиксированном количестве входных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Существует множество реализаций данного алгоритма. Рассмотрим некоторые из них:&lt;br /&gt;
&lt;br /&gt;
- Например, тут: https://habrahabr.ru/post/208496/&lt;br /&gt;
&amp;lt;ref&amp;gt;Нестер А. &amp;quot;Алгоритм нечёткой кластеризации fuzzy c-means на PHP&amp;quot;. [html](https://habrahabr.ru/post/208496/)&amp;lt;/ref&amp;gt;&lt;br /&gt;
приведено краткое описание алгоритма и приведена его реализация на php. В данной статье довольно подробно расписан каждый шаг алгоритма и приведён соответствующий ему фрагмент кода.&lt;br /&gt;
&lt;br /&gt;
- Тут: http://num-meth.srcc.msu.ru/zhurnal/tom_2012/v13r207.html&lt;br /&gt;
&amp;lt;ref&amp;gt;Миниахметов Р.М., Цымблер М.Л. &amp;quot;Интеграция алгоритма кластеризации Fuzzy c-Means в PostgreSQL&amp;quot;. [html](http://num-meth.srcc.msu.ru/zhurnal/tom_2012/v13r207.html)&amp;lt;/ref&amp;gt;&lt;br /&gt;
приводится реализация алгоритма для PostgreSQL, а также прилагается скрипт внедрения алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=21284</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=21284"/>
		<updated>2016-12-18T21:13:03Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Coctic}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Нечеткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(C^2*|X|*IterNumber)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(\log_{2}C^4*|X|^3) * IterNumber&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(C^2*|X|*D)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;|X|*p&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - размерность входных векторов&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;|X|*C &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: &lt;br /&gt;
[[Участник:Demon smd|Д.А.Гуськов]] &lt;br /&gt;
[[Участник:marina abramenkova|М.А.Абраменкова]].&lt;br /&gt;
Во все разделы вклад равноценный.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризуемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних заключается в следующем. Изначально для каждого вектора определяется случайным образом вероятность принадлежности вектора к каждому кластеру. Далее запускается итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) расчёт центров кластеров&lt;br /&gt;
&lt;br /&gt;
2) расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации: если разница этих значений меньше установленного значения, то алгоритм прекращает работу (решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности)&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{i = 1}^{|X|}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty , \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;|X|&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - количество кластеров, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные на каждой итерации ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^{(k)} - u_{i,j}^{(k-1)}|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&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;
В каждой итерации алгоритма происходит 3 основных действия описанных в п. 1.2.1:&lt;br /&gt;
*вычисление центров кластеров&lt;br /&gt;
*вычисление коэффициентов принадлежности&lt;br /&gt;
*вычисление решающей функции&lt;br /&gt;
Подробное описание макроструктур в виде кода приведено в пункте 1.5&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Схему реализации последовательного алгоритма можно описать на C++ следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FCM (X[], C, m, eps){&lt;br /&gt;
    float deside = 0;&lt;br /&gt;
    float newDeside = 0;&lt;br /&gt;
    generateMembershipDegree();            //заполняет uPrev[][] случайными нормрованными коэффициентами&lt;br /&gt;
    while (true){&lt;br /&gt;
        newDeside = deside;&lt;br /&gt;
&lt;br /&gt;
        //вычисление центров кластеров&lt;br /&gt;
        for (int j=0; j&amp;lt;C; j++){           //для каждого кластера&lt;br /&gt;
            float numerator = 0;&lt;br /&gt;
            float denumerator = 0;&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++){        //для каждого вектора&lt;br /&gt;
                numerator+=pow(u[i][j], m) * x[i];&lt;br /&gt;
                denumerator+=pow(u[i][j], m);&lt;br /&gt;
            }&lt;br /&gt;
            c[j] = numerator / denumerator;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //вычисление коэффициентов u[][]&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                sum = 0;&lt;br /&gt;
                for (int k=0; k&amp;lt;C; k++)&lt;br /&gt;
                    sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&lt;br /&gt;
                u[i][j] = 1/sum&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        //определения максимального различия между u[][] и uPrev[][]&lt;br /&gt;
        float max = 0;&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                if (abs(uPrev[i][j]-u[i][j])&amp;gt;max)&lt;br /&gt;
                    max = abs(uPrev[i][j]-u[i][j]);&lt;br /&gt;
&lt;br /&gt;
        if (eps &amp;lt;= max)&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
                for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                    uPrev[i][j]=u[i][j];&lt;br /&gt;
        else&lt;br /&gt;
            break;&lt;br /&gt;
             &lt;br /&gt;
    }&lt;br /&gt;
    return u;&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;
Под операцией будем понимать выражение в языке с++ из пункта 1.5, находящееся в теле цикла (например, выражения &amp;quot;sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&amp;quot; или &amp;quot;uPrev[i][j]=u[i][j];&amp;quot; считаются за одну операцию). Так как при больших входных объёмах данных сложность алгоритма в большей степени зависит от количества входных данных, и незначительно зависит от сложности операций,то при оценке сложности алгоритма сложность выражений можно считать равной единице. Так как в данном алгоритме количество итераций не является фиксированным и зависит от:&lt;br /&gt;
* параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
* набора входных векторов &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
* выбора начальных коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;&lt;br /&gt;
то в данном пункте будет приведена сложность одной итерации относительно количества входных векторов.&lt;br /&gt;
Для вычисления коэффициентов  u[][] на каждой итерации алгоритма требуется определить расстояние от векторов до центра кластера. Сложность данной операции зависит от размерности входных данных и определении нормы. В виду того, что для разных задач могут быть введены разные нормы, и сложность вычисления расстояний может варьироваться, то в данной статье будем считать, что сложность вычисления расстояния зависит линейно от размерности водных данных. В таком случае, для вычисления центров кластеров требуется &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, для определения коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;O(C^2*|X|*D)&amp;lt;/math&amp;gt; операций, а для вычисления решающей функции - &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, где &amp;lt;math&amp;gt;|X|&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;O(C^2*|X|*D)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Как видно из пункта 1.5, на каждом действии каждой итерации алгоритма все операции, выполняющиеся в цикле, не зависят друг от друга и могут быть распараллелены. Это показано на Рисунке 1.&lt;br /&gt;
&lt;br /&gt;
[[File:FCMIG.png|thumb|center|1200px|Рисунок 1. Информационный граф алгоритма. (1)-(7) - это наборы последовательных действий (например, (2) - последовательные операции деления, чтения элемента из памяти и присваивания).]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На каждом ярусе ярусно-параллельной формы алгоритма будет располагаться конечное число элементарных операций, например, чтение элемента из памяти, сложение или возведение в степень. Информационый граф из п.1.7 изображает свёрнутую ярусно-параллельную форму алгоритма. &lt;br /&gt;
&lt;br /&gt;
Сложность алгоритма будем рассчитывать в предположении, что число вычислительных ядер стремится к бесконечности. Как видно из информационного графа, параллельная сложность вычисления центров кластеров составляет &amp;lt;math&amp;gt;O(\log_{2}(C*|X|))&amp;lt;/math&amp;gt;, вычисления коэффициентов принадлежности - &amp;lt;math&amp;gt;O(\log_{2}(C^2*|X|))&amp;lt;/math&amp;gt;, а вычисления решающей функции - не больше чем &amp;lt;math&amp;gt;O(\log_{2} (C*|X|))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом параллельная сложность итерации алгоритма составляет &amp;lt;math&amp;gt;O(\log_{2} (C^4*|X|^3))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Так как задачи, решаемые в макроструктуре алгоритма могут быть сведены к задачам вычисления суммы элементов массива и максимального элемента массива, то на &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом ярусе графа будет находиться &amp;lt;math&amp;gt;{N}\over{2^i}&amp;lt;/math&amp;gt; операции, где N - количество элементов массива.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; - набор из &amp;lt;math&amp;gt;|X|&amp;lt;/math&amp;gt; входных векторов длины &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - количество кластеров&lt;br /&gt;
* &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
Объем входных данных: &amp;lt;math&amp;gt;|X|*p+3&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - матрица принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
Объем выходных данных: &amp;lt;math&amp;gt;|X|*C&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Увеличение скорости работы алгоритма при распараллеливании на бесконечном количестве процессоров составляет &amp;lt;math&amp;gt;O({{C^2*|X|}\over{\log_{2} (C^4*|X|^3)}})&amp;lt;/math&amp;gt;. Например, для разбиения 1000 элементов на 10 кластеров производительность параллельного алгоритма будет в 2315 раз больше, а на 20 кластеров - уже в 8477 раз.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
Как видно из предыдущих пунктов, масштабируется данный алгоритм хорошо. С увеличением количества процессоров время работы падает, а с увеличением количества входных данных и количества кластеров - растёт. &lt;br /&gt;
На рисунках показаны результаты запусков алгоритма на разном количестве входных данных и процессоров на массивно-параллельной вычислительной системе Blue Gene/P. Использовался компилятор mpixlcxx без указания специфических опций. Запуски производились в режиме SMP (на каждом ядре 1 MPI процесс из 4 SMP нитей, 2 Гб памяти). Характеристики вычислительного узла: 4 ядерный 32-битный процессор PowerPC 850 Мгц.&lt;br /&gt;
&lt;br /&gt;
Исходных код программы можно найти здесь: https://github.com/demonsmd/superPrak&lt;br /&gt;
[[File:FCMvectors_color2.png|thumb|center|1250px|Рисунок 2. Масштабируемость алгоритма. Зависимость времени работы алгоритма от количества процессоров и входных данных при фиксированном количестве кластеров.]]&lt;br /&gt;
[[File:FCMclusters_color.png|thumb|center|1250px|Рисунок 3. Масштабируемость алгоритма. Зависимость времени работы алгоритма от количества процессоров и кластеров при фиксированном количестве входных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Существует множество реализаций данного алгоритма. Рассмотрим некоторые из них:&lt;br /&gt;
&lt;br /&gt;
- Например, тут: https://habrahabr.ru/post/208496/&lt;br /&gt;
&amp;lt;ref&amp;gt;Нестер А. &amp;quot;Алгоритм нечёткой кластеризации fuzzy c-means на PHP&amp;quot;. [html](https://habrahabr.ru/post/208496/)&amp;lt;/ref&amp;gt;&lt;br /&gt;
приведено краткое описание алгоритма и приведена его реализация на php. В данной статье довольно подробно расписан каждый шаг алгоритма и приведён соответствующий ему фрагмент кода.&lt;br /&gt;
&lt;br /&gt;
- Тут: http://num-meth.srcc.msu.ru/zhurnal/tom_2012/v13r207.html&lt;br /&gt;
&amp;lt;ref&amp;gt;Миниахметов Р.М., Цымблер М.Л. &amp;quot;Интеграция алгоритма кластеризации Fuzzy c-Means в PostgreSQL&amp;quot;. [html](http://num-meth.srcc.msu.ru/zhurnal/tom_2012/v13r207.html)&amp;lt;/ref&amp;gt;&lt;br /&gt;
приводится реализация алгоритма для PostgreSQL, а также прилагается скрипт внедрения алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=21283</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=21283"/>
		<updated>2016-12-18T21:12:34Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: /* Последовательная сложность алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Coctic}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Нечеткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(C^2*|X|*IterNumber)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(\log_{2}C^4*|X|^3) * IterNumber&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(C^2*|X|)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;|X|*p&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - размерность входных векторов&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;|X|*C &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: &lt;br /&gt;
[[Участник:Demon smd|Д.А.Гуськов]] &lt;br /&gt;
[[Участник:marina abramenkova|М.А.Абраменкова]].&lt;br /&gt;
Во все разделы вклад равноценный.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризуемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних заключается в следующем. Изначально для каждого вектора определяется случайным образом вероятность принадлежности вектора к каждому кластеру. Далее запускается итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) расчёт центров кластеров&lt;br /&gt;
&lt;br /&gt;
2) расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации: если разница этих значений меньше установленного значения, то алгоритм прекращает работу (решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности)&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{i = 1}^{|X|}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty , \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;|X|&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - количество кластеров, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные на каждой итерации ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^{(k)} - u_{i,j}^{(k-1)}|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&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;
В каждой итерации алгоритма происходит 3 основных действия описанных в п. 1.2.1:&lt;br /&gt;
*вычисление центров кластеров&lt;br /&gt;
*вычисление коэффициентов принадлежности&lt;br /&gt;
*вычисление решающей функции&lt;br /&gt;
Подробное описание макроструктур в виде кода приведено в пункте 1.5&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Схему реализации последовательного алгоритма можно описать на C++ следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FCM (X[], C, m, eps){&lt;br /&gt;
    float deside = 0;&lt;br /&gt;
    float newDeside = 0;&lt;br /&gt;
    generateMembershipDegree();            //заполняет uPrev[][] случайными нормрованными коэффициентами&lt;br /&gt;
    while (true){&lt;br /&gt;
        newDeside = deside;&lt;br /&gt;
&lt;br /&gt;
        //вычисление центров кластеров&lt;br /&gt;
        for (int j=0; j&amp;lt;C; j++){           //для каждого кластера&lt;br /&gt;
            float numerator = 0;&lt;br /&gt;
            float denumerator = 0;&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++){        //для каждого вектора&lt;br /&gt;
                numerator+=pow(u[i][j], m) * x[i];&lt;br /&gt;
                denumerator+=pow(u[i][j], m);&lt;br /&gt;
            }&lt;br /&gt;
            c[j] = numerator / denumerator;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //вычисление коэффициентов u[][]&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                sum = 0;&lt;br /&gt;
                for (int k=0; k&amp;lt;C; k++)&lt;br /&gt;
                    sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&lt;br /&gt;
                u[i][j] = 1/sum&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        //определения максимального различия между u[][] и uPrev[][]&lt;br /&gt;
        float max = 0;&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                if (abs(uPrev[i][j]-u[i][j])&amp;gt;max)&lt;br /&gt;
                    max = abs(uPrev[i][j]-u[i][j]);&lt;br /&gt;
&lt;br /&gt;
        if (eps &amp;lt;= max)&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
                for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                    uPrev[i][j]=u[i][j];&lt;br /&gt;
        else&lt;br /&gt;
            break;&lt;br /&gt;
             &lt;br /&gt;
    }&lt;br /&gt;
    return u;&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;
Под операцией будем понимать выражение в языке с++ из пункта 1.5, находящееся в теле цикла (например, выражения &amp;quot;sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&amp;quot; или &amp;quot;uPrev[i][j]=u[i][j];&amp;quot; считаются за одну операцию). Так как при больших входных объёмах данных сложность алгоритма в большей степени зависит от количества входных данных, и незначительно зависит от сложности операций,то при оценке сложности алгоритма сложность выражений можно считать равной единице. Так как в данном алгоритме количество итераций не является фиксированным и зависит от:&lt;br /&gt;
* параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
* набора входных векторов &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
* выбора начальных коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;&lt;br /&gt;
то в данном пункте будет приведена сложность одной итерации относительно количества входных векторов.&lt;br /&gt;
Для вычисления коэффициентов  u[][] на каждой итерации алгоритма требуется определить расстояние от векторов до центра кластера. Сложность данной операции зависит от размерности входных данных и определении нормы. В виду того, что для разных задач могут быть введены разные нормы, и сложность вычисления расстояний может варьироваться, то в данной статье будем считать, что сложность вычисления расстояния зависит линейно от размерности водных данных. В таком случае, для вычисления центров кластеров требуется &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, для определения коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;O(C^2*|X|*D)&amp;lt;/math&amp;gt; операций, а для вычисления решающей функции - &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, где &amp;lt;math&amp;gt;|X|&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;O(C^2*|X|*D)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Как видно из пункта 1.5, на каждом действии каждой итерации алгоритма все операции, выполняющиеся в цикле, не зависят друг от друга и могут быть распараллелены. Это показано на Рисунке 1.&lt;br /&gt;
&lt;br /&gt;
[[File:FCMIG.png|thumb|center|1200px|Рисунок 1. Информационный граф алгоритма. (1)-(7) - это наборы последовательных действий (например, (2) - последовательные операции деления, чтения элемента из памяти и присваивания).]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На каждом ярусе ярусно-параллельной формы алгоритма будет располагаться конечное число элементарных операций, например, чтение элемента из памяти, сложение или возведение в степень. Информационый граф из п.1.7 изображает свёрнутую ярусно-параллельную форму алгоритма. &lt;br /&gt;
&lt;br /&gt;
Сложность алгоритма будем рассчитывать в предположении, что число вычислительных ядер стремится к бесконечности. Как видно из информационного графа, параллельная сложность вычисления центров кластеров составляет &amp;lt;math&amp;gt;O(\log_{2}(C*|X|))&amp;lt;/math&amp;gt;, вычисления коэффициентов принадлежности - &amp;lt;math&amp;gt;O(\log_{2}(C^2*|X|))&amp;lt;/math&amp;gt;, а вычисления решающей функции - не больше чем &amp;lt;math&amp;gt;O(\log_{2} (C*|X|))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом параллельная сложность итерации алгоритма составляет &amp;lt;math&amp;gt;O(\log_{2} (C^4*|X|^3))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Так как задачи, решаемые в макроструктуре алгоритма могут быть сведены к задачам вычисления суммы элементов массива и максимального элемента массива, то на &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом ярусе графа будет находиться &amp;lt;math&amp;gt;{N}\over{2^i}&amp;lt;/math&amp;gt; операции, где N - количество элементов массива.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; - набор из &amp;lt;math&amp;gt;|X|&amp;lt;/math&amp;gt; входных векторов длины &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - количество кластеров&lt;br /&gt;
* &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
Объем входных данных: &amp;lt;math&amp;gt;|X|*p+3&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - матрица принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
Объем выходных данных: &amp;lt;math&amp;gt;|X|*C&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Увеличение скорости работы алгоритма при распараллеливании на бесконечном количестве процессоров составляет &amp;lt;math&amp;gt;O({{C^2*|X|}\over{\log_{2} (C^4*|X|^3)}})&amp;lt;/math&amp;gt;. Например, для разбиения 1000 элементов на 10 кластеров производительность параллельного алгоритма будет в 2315 раз больше, а на 20 кластеров - уже в 8477 раз.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
Как видно из предыдущих пунктов, масштабируется данный алгоритм хорошо. С увеличением количества процессоров время работы падает, а с увеличением количества входных данных и количества кластеров - растёт. &lt;br /&gt;
На рисунках показаны результаты запусков алгоритма на разном количестве входных данных и процессоров на массивно-параллельной вычислительной системе Blue Gene/P. Использовался компилятор mpixlcxx без указания специфических опций. Запуски производились в режиме SMP (на каждом ядре 1 MPI процесс из 4 SMP нитей, 2 Гб памяти). Характеристики вычислительного узла: 4 ядерный 32-битный процессор PowerPC 850 Мгц.&lt;br /&gt;
&lt;br /&gt;
Исходных код программы можно найти здесь: https://github.com/demonsmd/superPrak&lt;br /&gt;
[[File:FCMvectors_color2.png|thumb|center|1250px|Рисунок 2. Масштабируемость алгоритма. Зависимость времени работы алгоритма от количества процессоров и входных данных при фиксированном количестве кластеров.]]&lt;br /&gt;
[[File:FCMclusters_color.png|thumb|center|1250px|Рисунок 3. Масштабируемость алгоритма. Зависимость времени работы алгоритма от количества процессоров и кластеров при фиксированном количестве входных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Существует множество реализаций данного алгоритма. Рассмотрим некоторые из них:&lt;br /&gt;
&lt;br /&gt;
- Например, тут: https://habrahabr.ru/post/208496/&lt;br /&gt;
&amp;lt;ref&amp;gt;Нестер А. &amp;quot;Алгоритм нечёткой кластеризации fuzzy c-means на PHP&amp;quot;. [html](https://habrahabr.ru/post/208496/)&amp;lt;/ref&amp;gt;&lt;br /&gt;
приведено краткое описание алгоритма и приведена его реализация на php. В данной статье довольно подробно расписан каждый шаг алгоритма и приведён соответствующий ему фрагмент кода.&lt;br /&gt;
&lt;br /&gt;
- Тут: http://num-meth.srcc.msu.ru/zhurnal/tom_2012/v13r207.html&lt;br /&gt;
&amp;lt;ref&amp;gt;Миниахметов Р.М., Цымблер М.Л. &amp;quot;Интеграция алгоритма кластеризации Fuzzy c-Means в PostgreSQL&amp;quot;. [html](http://num-meth.srcc.msu.ru/zhurnal/tom_2012/v13r207.html)&amp;lt;/ref&amp;gt;&lt;br /&gt;
приводится реализация алгоритма для PostgreSQL, а также прилагается скрипт внедрения алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=21228</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=21228"/>
		<updated>2016-12-18T17:37:28Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|{{REVISIONUSER}}}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Нечеткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(C^2*|X|*IterNumber)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(\log_{2}C^4*|X|^3) * IterNumber&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(C^2*|X|)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;|X|*p&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - размерность входных векторов&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;|X|*C &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: &lt;br /&gt;
[[Участник:Demon smd|Д.А.Гуськов]] &lt;br /&gt;
[[Участник:marina abramenkova|М.А.Абраменкова]].&lt;br /&gt;
Во все разделы вклад равноценный.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризуемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних заключается в следующем. Изначально для каждого вектора определяется случайным образом вероятность принадлежности вектора к каждому кластеру. Далее запускается итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) расчёт центров кластеров&lt;br /&gt;
&lt;br /&gt;
2) расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации: если разница этих значений меньше установленного значения, то алгоритм прекращает работу (решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности)&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{i = 1}^{|X|}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty , \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;|X|&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - количество кластеров, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные на каждой итерации ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^{(k)} - u_{i,j}^{(k-1)}|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&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;
В каждой итерации алгоритма происходит 3 основных действия описанных в п. 1.2.1:&lt;br /&gt;
*вычисление центров кластеров&lt;br /&gt;
*вычисление коэффициентов принадлежности&lt;br /&gt;
*вычисление решающей функции&lt;br /&gt;
Подробное описание макроструктур в виде кода приведено в пункте 1.5&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Схему реализации последовательного алгоритма можно описать на C++ следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FCM (X[], C, m, eps){&lt;br /&gt;
    float deside = 0;&lt;br /&gt;
    float newDeside = 0;&lt;br /&gt;
    generateMembershipDegree();            //заполняет uPrev[][] случайными нормрованными коэффициентами&lt;br /&gt;
    while (true){&lt;br /&gt;
        newDeside = deside;&lt;br /&gt;
&lt;br /&gt;
        //вычисление центров кластеров&lt;br /&gt;
        for (int j=0; j&amp;lt;C; j++){           //для каждого кластера&lt;br /&gt;
            float numerator = 0;&lt;br /&gt;
            float denumerator = 0;&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++){        //для каждого вектора&lt;br /&gt;
                numerator+=pow(u[i][j], m) * x[i];&lt;br /&gt;
                denumerator+=pow(u[i][j], m);&lt;br /&gt;
            }&lt;br /&gt;
            c[j] = numerator / denumerator;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //вычисление коэффициентов u[][]&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                sum = 0;&lt;br /&gt;
                for (int k=0; k&amp;lt;C; k++)&lt;br /&gt;
                    sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&lt;br /&gt;
                u[i][j] = 1/sum&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        //определения максимального различия между u[][] и uPrev[][]&lt;br /&gt;
        float max = 0;&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                if (abs(uPrev[i][j]-u[i][j])&amp;gt;max)&lt;br /&gt;
                    max = abs(uPrev[i][j]-u[i][j]);&lt;br /&gt;
&lt;br /&gt;
        if (eps &amp;lt;= max)&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
                for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                    uPrev[i][j]=u[i][j];&lt;br /&gt;
        else&lt;br /&gt;
            break;&lt;br /&gt;
             &lt;br /&gt;
    }&lt;br /&gt;
    return u;&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;
Под операцией будем понимать выражение в языке с++ из пункта 1.5, находящееся в теле цикла (например, выражения &amp;quot;sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&amp;quot; или &amp;quot;uPrev[i][j]=u[i][j];&amp;quot; считаются за одну операцию). Так как при больших входных объёмах данных сложность алгоритма в большей степени зависит от количества входных данных, и незначительно зависит от сложности операций,то при оценке сложности алгоритма сложность выражений можно считать равной единице. Так как в данном алгоритме количество итераций не является фиксированным и зависит от:&lt;br /&gt;
* параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
* набора входных векторов &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
* выбора начальных коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;&lt;br /&gt;
то в данном пункте будет приведена сложность одной итерации относительно количества входных векторов.&lt;br /&gt;
Для вычисления коэффициентов  u[][] на каждой итерации алгоритма требуется определить расстояние от векторов до центра кластера. Сложность данной операции зависит от размерности входных данных и определении нормы. В виду того, что для разных задач могут быть введены разные нормы, и сложность вычисления расстояний может варьироваться, то в данной статье сложность вычисления расстояния будет считаться равной единице. В таком случае, для вычисления центров кластеров требуется &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, для определения коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;O(C^2*|X|)&amp;lt;/math&amp;gt; операций, а для вычисления решающей функции - &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, где &amp;lt;math&amp;gt;|X|&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;O(C^2*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Как видно из пункта 1.5, на каждом действии каждой итерации алгоритма все операции, выполняющиеся в цикле, не зависят друг от друга и могут быть распараллелены. Это показано на Рисунке 1.&lt;br /&gt;
&lt;br /&gt;
[[File:FCMIG.png|thumb|center|1200px|Рисунок 1. Информационный граф алгоритма. (1)-(7) - это наборы последовательных действий (например, (2) - последовательные операции деления, чтения элемента из памяти и присваивания).]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На каждом ярусе ярусно-параллельной формы алгоритма будет располагаться конечное число элементарных операций, например, чтение элемента из памяти, сложение или возведение в степень. Информационый граф из п.1.7 изображает свёрнутую ярусно-параллельную форму алгоритма. &lt;br /&gt;
&lt;br /&gt;
Сложность алгоритма будем рассчитывать в предположении, что число вычислительных ядер стремится к бесконечности. Как видно из информационного графа, параллельная сложность вычисления центров кластеров составляет &amp;lt;math&amp;gt;O(\log_{2}(C*|X|))&amp;lt;/math&amp;gt;, вычисления коэффициентов принадлежности - &amp;lt;math&amp;gt;O(\log_{2}(C^2*|X|))&amp;lt;/math&amp;gt;, а вычисления решающей функции - не больше чем &amp;lt;math&amp;gt;O(\log_{2} (C*|X|))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом параллельная сложность итерации алгоритма составляет &amp;lt;math&amp;gt;O(\log_{2} (C^4*|X|^3))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Так как задачи, решаемые в макроструктуре алгоритма могут быть сведены к задачам вычисления суммы элементов массива и максимального элемента массива, то на &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом ярусе графа будет находиться &amp;lt;math&amp;gt;{N}\over{2^i}&amp;lt;/math&amp;gt; операции, где N - количество элементов массива.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; - набор из &amp;lt;math&amp;gt;|X|&amp;lt;/math&amp;gt; входных векторов длины &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - количество кластеров&lt;br /&gt;
* &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
Объем входных данных: &amp;lt;math&amp;gt;|X|*p+3&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - матрица принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
Объем выходных данных: &amp;lt;math&amp;gt;|X|*C&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Увеличение скорости работы алгоритма при распараллеливании на бесконечном количестве процессоров составляет &amp;lt;math&amp;gt;O({{C^2*|X|}\over{\log_{2} (C^4*|X|^3)}})&amp;lt;/math&amp;gt;. Например, для разбиения 1000 элементов на 10 кластеров производительность параллельного алгоритма будет в 2315 раз больше, а на 20 кластеров - уже в 8477 раз.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
Как видно из предыдущих пунктов, масштабируется данный алгоритм хорошо. С увеличением количества процессоров время работы падает, а с увеличением количества входных данных и количества кластеров - растёт. &lt;br /&gt;
На рисунках показаны результаты запусков алгоритма на разном количестве входных данных и процессоров на массивно-параллельной вычислительной системе Blue Gene/P. Использовался компилятор mpixlcxx без указания специфических опций. Запуски производились в режиме SMP (на каждом ядре 1 MPI процесс из 4 SMP нитей, 2 Гб памяти). Характеристики вычислительного узла: 4 ядерный 32-битный процессор PowerPC 850 Мгц.&lt;br /&gt;
&lt;br /&gt;
Исходных код программы можно найти здесь: https://github.com/demonsmd/superPrak&lt;br /&gt;
[[File:FCMvectors_color2.png|thumb|center|1250px|Рисунок 2. Масштабируемость алгоритма. Зависимость времени работы алгоритма от количества процессоров и входных данных при фиксированном количестве кластеров.]]&lt;br /&gt;
[[File:FCMclusters_color.png|thumb|center|1250px|Рисунок 3. Масштабируемость алгоритма. Зависимость времени работы алгоритма от количества процессоров и кластеров при фиксированном количестве входных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Существует множество реализаций данного алгоритма. Рассмотрим некоторые из них:&lt;br /&gt;
&lt;br /&gt;
- Например, тут: https://habrahabr.ru/post/208496/&lt;br /&gt;
&amp;lt;ref&amp;gt;Нестер А. &amp;quot;Алгоритм нечёткой кластеризации fuzzy c-means на PHP&amp;quot;. [html](https://habrahabr.ru/post/208496/)&amp;lt;/ref&amp;gt;&lt;br /&gt;
приведено краткое описание алгоритма и приведена его реализация на php. В данной статье довольно подробно расписан каждый шаг алгоритма и приведён соответствующий ему фрагмент кода.&lt;br /&gt;
&lt;br /&gt;
- Тут: http://num-meth.srcc.msu.ru/zhurnal/tom_2012/v13r207.html&lt;br /&gt;
&amp;lt;ref&amp;gt;Миниахметов Р.М., Цымблер М.Л. &amp;quot;Интеграция алгоритма кластеризации Fuzzy c-Means в PostgreSQL&amp;quot;. [html](http://num-meth.srcc.msu.ru/zhurnal/tom_2012/v13r207.html)&amp;lt;/ref&amp;gt;&lt;br /&gt;
приводится реализация алгоритма для PostgreSQL, а также прилагается скрипт внедрения алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=21224</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=21224"/>
		<updated>2016-12-18T17:10:15Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: /* Последовательная сложность алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|{{REVISIONUSER}}}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Нечеткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(C^2*|X|*D*IterNumber)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(\log_{2}C^4*|X|^3) * IterNumber&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(C^2*|X|)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;|X|*p&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - размерность входных векторов&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;|X|*C &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: &lt;br /&gt;
[[Участник:Demon smd|Д.А.Гуськов]] &lt;br /&gt;
[[Участник:marina abramenkova|М.А.Абраменкова]].&lt;br /&gt;
Во все разделы вклад равноценный.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризуемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних заключается в следующем. Изначально для каждого вектора определяется случайным образом вероятность принадлежности вектора к каждому кластеру. Далее запускается итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) расчёт центров кластеров&lt;br /&gt;
&lt;br /&gt;
2) расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации: если разница этих значений меньше установленного значения, то алгоритм прекращает работу (решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности)&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{i = 1}^{|X|}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty , \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;|X|&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - количество кластеров, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные на каждой итерации ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^{(k)} - u_{i,j}^{(k-1)}|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&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;
В каждой итерации алгоритма происходит 3 основных действия описанных в п. 1.2.1:&lt;br /&gt;
*вычисление центров кластеров&lt;br /&gt;
*вычисление коэффициентов принадлежности&lt;br /&gt;
*вычисление решающей функции&lt;br /&gt;
Подробное описание макроструктур в виде кода приведено в пункте 1.5&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Схему реализации последовательного алгоритма можно описать на C++ следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FCM (X[], C, m, eps){&lt;br /&gt;
    float deside = 0;&lt;br /&gt;
    float newDeside = 0;&lt;br /&gt;
    generateMembershipDegree();            //заполняет uPrev[][] случайными нормрованными коэффициентами&lt;br /&gt;
    while (true){&lt;br /&gt;
        newDeside = deside;&lt;br /&gt;
&lt;br /&gt;
        //вычисление центров кластеров&lt;br /&gt;
        for (int j=0; j&amp;lt;C; j++){           //для каждого кластера&lt;br /&gt;
            float numerator = 0;&lt;br /&gt;
            float denumerator = 0;&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++){        //для каждого вектора&lt;br /&gt;
                numerator+=pow(u[i][j], m) * x[i];&lt;br /&gt;
                denumerator+=pow(u[i][j], m);&lt;br /&gt;
            }&lt;br /&gt;
            c[j] = numerator / denumerator;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //вычисление коэффициентов u[][]&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                sum = 0;&lt;br /&gt;
                for (int k=0; k&amp;lt;C; k++)&lt;br /&gt;
                    sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&lt;br /&gt;
                u[i][j] = 1/sum&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        //определения максимального различия между u[][] и uPrev[][]&lt;br /&gt;
        float max = 0;&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                if (abs(uPrev[i][j]-u[i][j])&amp;gt;max)&lt;br /&gt;
                    max = abs(uPrev[i][j]-u[i][j]);&lt;br /&gt;
&lt;br /&gt;
        if (eps &amp;lt;= max)&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
                for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                    uPrev[i][j]=u[i][j];&lt;br /&gt;
        else&lt;br /&gt;
            break;&lt;br /&gt;
             &lt;br /&gt;
    }&lt;br /&gt;
    return u;&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;
Под операцией будем понимать выражение в языке с++ из пункта 1.5, находящееся в теле цикла (например, выражения &amp;quot;sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&amp;quot; или &amp;quot;uPrev[i][j]=u[i][j];&amp;quot; считаются за одну операцию). Так как при больших входных объёмах данных сложность алгоритма в большей степени зависит от количества входных данных, и незначительно зависит от сложности операций,то при оценке сложности алгоритма сложность выражений можно считать равной единице. Так как в данном алгоритме количество итераций не является фиксированным и зависит от:&lt;br /&gt;
* параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
* набора входных векторов &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
* выбора начальных коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;&lt;br /&gt;
то в данном пункте будет приведена сложность одной итерации относительно количества входных векторов.&lt;br /&gt;
Для вычисления коэффициентов  u[][] на каждой итерации алгоритма требуется определить расстояние от векторов до центра кластера. Сложность данной операции зависит от размерности входных данных и определении нормы. В виду того, что для разных задач могут быть введены разные нормы, и сложность вычисления расстояний может варьироваться, то в данной статье сложность вычисления расстояния будет считаться равной единице. В таком случае, для вычисления центров кластеров требуется &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, для определения коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;O(C^2*|X|)&amp;lt;/math&amp;gt; операций, а для вычисления решающей функции - &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, где &amp;lt;math&amp;gt;|X|&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;O(C^2*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Как видно из пункта 1.5, на каждом действии каждой итерации алгоритма все операции, выполняющиеся в цикле, не зависят друг от друга и могут быть распараллелены. Это показано на Рисунке 1.&lt;br /&gt;
&lt;br /&gt;
[[File:FCMIG.png|thumb|center|1200px|Рисунок 1. Информационный граф алгоритма. (1)-(7) - это наборы последовательных действий (например, (2) - последовательные операции деления, чтения элемента из памяти и присваивания).]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На каждом ярусе ярусно-параллельной формы алгоритма будет располагаться конечное число элементарных операций, например, чтение элемента из памяти, сложение или возведение в степень. Информационый граф из п.1.7 изображает свёрнутую ярусно-параллельную форму алгоритма. &lt;br /&gt;
&lt;br /&gt;
Сложность алгоритма будем рассчитывать в предположении, что число вычислительных ядер стремится к бесконечности. Как видно из информационного графа, параллельная сложность вычисления центров кластеров составляет &amp;lt;math&amp;gt;O(\log_{2}(C*|X|))&amp;lt;/math&amp;gt;, вычисления коэффициентов принадлежности - &amp;lt;math&amp;gt;O(\log_{2}(C^2*|X|))&amp;lt;/math&amp;gt;, а вычисления решающей функции - не больше чем &amp;lt;math&amp;gt;O(\log_{2} (C*|X|))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом параллельная сложность итерации алгоритма составляет &amp;lt;math&amp;gt;O(\log_{2} (C^4*|X|^3))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Так как задачи, решаемые в макроструктуре алгоритма могут быть сведены к задачам вычисления суммы элементов массива и максимального элемента массива, то на &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом ярусе графа будет находиться &amp;lt;math&amp;gt;{N}\over{2^i}&amp;lt;/math&amp;gt; операции, где N - количество элементов массива.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; - набор из &amp;lt;math&amp;gt;|X|&amp;lt;/math&amp;gt; входных векторов длины &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - количество кластеров&lt;br /&gt;
* &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
Объем входных данных: &amp;lt;math&amp;gt;|X|*p+3&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - матрица принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
Объем выходных данных: &amp;lt;math&amp;gt;|X|*C&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Увеличение скорости работы алгоритма при распараллеливании на бесконечном количестве процессоров составляет &amp;lt;math&amp;gt;O({{C^2*|X|}\over{\log_{2} (C^4*|X|^3)}})&amp;lt;/math&amp;gt;. Например, для разбиения 1000 элементов на 10 кластеров производительность параллельного алгоритма будет в 2315 раз больше, а на 20 кластеров - уже в 8477 раз.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
Как видно из предыдущих пунктов, масштабируется данный алгоритм хорошо. С увеличением количества процессоров время работы падает, а с увеличением количества входных данных и количества кластеров - растёт. &lt;br /&gt;
На рисунках показаны результаты запусков алгоритма на разном количестве входных данных и процессоров на массивно-параллельной вычислительной системе Blue Gene/P. Использовался компилятор mpixlcxx без указания специфических опций. Запуски производились в режиме SMP (на каждом ядре 1 MPI процесс из 4 SMP нитей, 2 Гб памяти). Характеристики вычислительного узла: 4 ядерный 32-битный процессор PowerPC 850 Мгц.&lt;br /&gt;
&lt;br /&gt;
Исходных код программы можно найти здесь: https://github.com/demonsmd/superPrak&lt;br /&gt;
[[File:FCMvectors_color2.png|thumb|center|1250px|Рисунок 2. Масштабируемость алгоритма. Зависимость времени работы алгоритма от количества процессоров и входных данных при фиксированном количестве кластеров.]]&lt;br /&gt;
[[File:FCMclusters_color.png|thumb|center|1250px|Рисунок 3. Масштабируемость алгоритма. Зависимость времени работы алгоритма от количества процессоров и кластеров при фиксированном количестве входных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Существует множество реализаций данного алгоритма. Рассмотрим некоторые из них:&lt;br /&gt;
&lt;br /&gt;
- Например, тут: https://habrahabr.ru/post/208496/&lt;br /&gt;
&amp;lt;ref&amp;gt;Нестер А. &amp;quot;Алгоритм нечёткой кластеризации fuzzy c-means на PHP&amp;quot;. [html](https://habrahabr.ru/post/208496/)&amp;lt;/ref&amp;gt;&lt;br /&gt;
приведено краткое описание алгоритма и приведена его реализация на php. В данной статье довольно подробно расписан каждый шаг алгоритма и приведён соответствующий ему фрагмент кода.&lt;br /&gt;
&lt;br /&gt;
- Тут: http://num-meth.srcc.msu.ru/zhurnal/tom_2012/v13r207.html&lt;br /&gt;
&amp;lt;ref&amp;gt;Миниахметов Р.М., Цымблер М.Л. &amp;quot;Интеграция алгоритма кластеризации Fuzzy c-Means в PostgreSQL&amp;quot;. [html](http://num-meth.srcc.msu.ru/zhurnal/tom_2012/v13r207.html)&amp;lt;/ref&amp;gt;&lt;br /&gt;
приводится реализация алгоритма для PostgreSQL, а также прилагается скрипт внедрения алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=21222</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=21222"/>
		<updated>2016-12-18T17:02:32Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: /* Ресурс параллелизма алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|{{REVISIONUSER}}}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Нечеткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(C^2*|X|*D*IterNumber)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(\log_{2}C^4*|X|^3) * IterNumber&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(C^2*|X|)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;|X|*p&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - размерность входных векторов&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;|X|*C &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: &lt;br /&gt;
[[Участник:Demon smd|Д.А.Гуськов]] &lt;br /&gt;
[[Участник:marina abramenkova|М.А.Абраменкова]].&lt;br /&gt;
Во все разделы вклад равноценный.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризуемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних заключается в следующем. Изначально для каждого вектора определяется случайным образом вероятность принадлежности вектора к каждому кластеру. Далее запускается итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) расчёт центров кластеров&lt;br /&gt;
&lt;br /&gt;
2) расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации: если разница этих значений меньше установленного значения, то алгоритм прекращает работу (решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности)&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{i = 1}^{|X|}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty , \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;|X|&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - количество кластеров, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные на каждой итерации ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^{(k)} - u_{i,j}^{(k-1)}|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&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;
В каждой итерации алгоритма происходит 3 основных действия описанных в п. 1.2.1:&lt;br /&gt;
*вычисление центров кластеров&lt;br /&gt;
*вычисление коэффициентов принадлежности&lt;br /&gt;
*вычисление решающей функции&lt;br /&gt;
Подробное описание макроструктур в виде кода приведено в пункте 1.5&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Схему реализации последовательного алгоритма можно описать на C++ следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FCM (X[], C, m, eps){&lt;br /&gt;
    float deside = 0;&lt;br /&gt;
    float newDeside = 0;&lt;br /&gt;
    generateMembershipDegree();            //заполняет uPrev[][] случайными нормрованными коэффициентами&lt;br /&gt;
    while (true){&lt;br /&gt;
        newDeside = deside;&lt;br /&gt;
&lt;br /&gt;
        //вычисление центров кластеров&lt;br /&gt;
        for (int j=0; j&amp;lt;C; j++){           //для каждого кластера&lt;br /&gt;
            float numerator = 0;&lt;br /&gt;
            float denumerator = 0;&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++){        //для каждого вектора&lt;br /&gt;
                numerator+=pow(u[i][j], m) * x[i];&lt;br /&gt;
                denumerator+=pow(u[i][j], m);&lt;br /&gt;
            }&lt;br /&gt;
            c[j] = numerator / denumerator;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //вычисление коэффициентов u[][]&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                sum = 0;&lt;br /&gt;
                for (int k=0; k&amp;lt;C; k++)&lt;br /&gt;
                    sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&lt;br /&gt;
                u[i][j] = 1/sum&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        //определения максимального различия между u[][] и uPrev[][]&lt;br /&gt;
        float max = 0;&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                if (abs(uPrev[i][j]-u[i][j])&amp;gt;max)&lt;br /&gt;
                    max = abs(uPrev[i][j]-u[i][j]);&lt;br /&gt;
&lt;br /&gt;
        if (eps &amp;lt;= max)&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
                for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                    uPrev[i][j]=u[i][j];&lt;br /&gt;
        else&lt;br /&gt;
            break;&lt;br /&gt;
             &lt;br /&gt;
    }&lt;br /&gt;
    return u;&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;
Под операцией будем понимать выражение в языке с++ из пункта 1.5, находящееся в теле цикла (например, выражения &amp;quot;sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&amp;quot; или &amp;quot;uPrev[i][j]=u[i][j];&amp;quot; считаются за одну операцию). Так как при больших входных объёмах данных сложность алгоритма в большей степени зависит от количества входных данных, и незначительно зависит от сложности операций,то при оценке сложности алгоритма сложность выражений можно считать равной единице. Так как в данном алгоритме количество итераций не является фиксированным и зависит от:&lt;br /&gt;
* параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
* набора входных векторов &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
* выбора начальных коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;&lt;br /&gt;
то в данном пункте будет приведена сложность одной итерации относительно количества входных векторов.&lt;br /&gt;
Как видно из предыдущего пункта, для вычисления центров кластеров требуется &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, для определения коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;O(C^2*|X|)&amp;lt;/math&amp;gt; операций, а для вычисления решающей функции - &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, где &amp;lt;math&amp;gt;|X|&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;O(C^2*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Как видно из пункта 1.5, на каждом действии каждой итерации алгоритма все операции, выполняющиеся в цикле, не зависят друг от друга и могут быть распараллелены. Это показано на Рисунке 1.&lt;br /&gt;
&lt;br /&gt;
[[File:FCMIG.png|thumb|center|1200px|Рисунок 1. Информационный граф алгоритма. (1)-(7) - это наборы последовательных действий (например, (2) - последовательные операции деления, чтения элемента из памяти и присваивания).]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На каждом ярусе ярусно-параллельной формы алгоритма будет располагаться конечное число элементарных операций, например, чтение элемента из памяти, сложение или возведение в степень. Информационый граф из п.1.7 изображает свёрнутую ярусно-параллельную форму алгоритма. &lt;br /&gt;
&lt;br /&gt;
Сложность алгоритма будем рассчитывать в предположении, что число вычислительных ядер стремится к бесконечности. Как видно из информационного графа, параллельная сложность вычисления центров кластеров составляет &amp;lt;math&amp;gt;O(\log_{2}(C*|X|))&amp;lt;/math&amp;gt;, вычисления коэффициентов принадлежности - &amp;lt;math&amp;gt;O(\log_{2}(C^2*|X|))&amp;lt;/math&amp;gt;, а вычисления решающей функции - не больше чем &amp;lt;math&amp;gt;O(\log_{2} (C*|X|))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом параллельная сложность итерации алгоритма составляет &amp;lt;math&amp;gt;O(\log_{2} (C^4*|X|^3))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Так как задачи, решаемые в макроструктуре алгоритма могут быть сведены к задачам вычисления суммы элементов массива и максимального элемента массива, то на &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом ярусе графа будет находиться &amp;lt;math&amp;gt;{N}\over{2^i}&amp;lt;/math&amp;gt; операции, где N - количество элементов массива.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; - набор из &amp;lt;math&amp;gt;|X|&amp;lt;/math&amp;gt; входных векторов длины &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - количество кластеров&lt;br /&gt;
* &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
Объем входных данных: &amp;lt;math&amp;gt;|X|*p+3&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - матрица принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
Объем выходных данных: &amp;lt;math&amp;gt;|X|*C&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Увеличение скорости работы алгоритма при распараллеливании на бесконечном количестве процессоров составляет &amp;lt;math&amp;gt;O({{C^2*|X|}\over{\log_{2} (C^4*|X|^3)}})&amp;lt;/math&amp;gt;. Например, для разбиения 1000 элементов на 10 кластеров производительность параллельного алгоритма будет в 2315 раз больше, а на 20 кластеров - уже в 8477 раз.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
Как видно из предыдущих пунктов, масштабируется данный алгоритм хорошо. С увеличением количества процессоров время работы падает, а с увеличением количества входных данных и количества кластеров - растёт. &lt;br /&gt;
На рисунках показаны результаты запусков алгоритма на разном количестве входных данных и процессоров на массивно-параллельной вычислительной системе Blue Gene/P. Использовался компилятор mpixlcxx без указания специфических опций. Запуски производились в режиме SMP (на каждом ядре 1 MPI процесс из 4 SMP нитей, 2 Гб памяти). Характеристики вычислительного узла: 4 ядерный 32-битный процессор PowerPC 850 Мгц.&lt;br /&gt;
&lt;br /&gt;
Исходных код программы можно найти здесь: https://github.com/demonsmd/superPrak&lt;br /&gt;
[[File:FCMvectors_color2.png|thumb|center|1250px|Рисунок 2. Масштабируемость алгоритма. Зависимость времени работы алгоритма от количества процессоров и входных данных при фиксированном количестве кластеров.]]&lt;br /&gt;
[[File:FCMclusters_color.png|thumb|center|1250px|Рисунок 3. Масштабируемость алгоритма. Зависимость времени работы алгоритма от количества процессоров и кластеров при фиксированном количестве входных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Существует множество реализаций данного алгоритма. Рассмотрим некоторые из них:&lt;br /&gt;
&lt;br /&gt;
- Например, тут: https://habrahabr.ru/post/208496/&lt;br /&gt;
&amp;lt;ref&amp;gt;Нестер А. &amp;quot;Алгоритм нечёткой кластеризации fuzzy c-means на PHP&amp;quot;. [html](https://habrahabr.ru/post/208496/)&amp;lt;/ref&amp;gt;&lt;br /&gt;
приведено краткое описание алгоритма и приведена его реализация на php. В данной статье довольно подробно расписан каждый шаг алгоритма и приведён соответствующий ему фрагмент кода.&lt;br /&gt;
&lt;br /&gt;
- Тут: http://num-meth.srcc.msu.ru/zhurnal/tom_2012/v13r207.html&lt;br /&gt;
&amp;lt;ref&amp;gt;Миниахметов Р.М., Цымблер М.Л. &amp;quot;Интеграция алгоритма кластеризации Fuzzy c-Means в PostgreSQL&amp;quot;. [html](http://num-meth.srcc.msu.ru/zhurnal/tom_2012/v13r207.html)&amp;lt;/ref&amp;gt;&lt;br /&gt;
приводится реализация алгоритма для PostgreSQL, а также прилагается скрипт внедрения алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Demon_smd&amp;diff=21221</id>
		<title>Обсуждение участника:Demon smd</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Demon_smd&amp;diff=21221"/>
		<updated>2016-12-18T17:01:39Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Статья [[Участник:Demon_smd/Нечеткий_алгоритм_С_средних]] =&lt;br /&gt;
&lt;br /&gt;
* У вас в сложности фигурирует количество итераций. В литературе есть какие-то оценки требуемого количества итераций исходя из входных параметров? Если есть, то хорошо бы указать. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 18:23, 18 декабря 2016 (MSK)&lt;br /&gt;
** Нет, в классической постановке задачи алгоритм работает пока есть улучшение результата (это описано в 1.1 пункт 4.) А количество итераций зависит от параметра эпсилон, входных данных и сгенерированного начального размещения.&lt;br /&gt;
* 1.8 — Из текста непонятно, откуда получен логарифм. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 23:11, 17 декабря 2016 (MSK)&lt;br /&gt;
** опечатка были пропущены скобки&lt;br /&gt;
* 1.8 — «взятие адреса» — имеется ввиду чтение элемента из памяти, да? [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 23:11, 17 декабря 2016 (MSK)&lt;br /&gt;
** Да, верно&lt;br /&gt;
*** Поправьте текст, пожалуйста. У «взятия адреса» есть определение и оно не соответствует тому, как вы это использовали. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 16:50, 18 декабря 2016 (MSK)&lt;br /&gt;
* 1.6 — в оценки сложности итерации не учтена размерность входных векторов. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 23:11, 17 декабря 2016 (MSK)&lt;br /&gt;
** единственное место, где это важно - вычисление нормы, определяющей расстояние, но тут сложность зависит не только от размерности входных данных, а ещё и от определения нормы.&lt;br /&gt;
* 1.4 — не описано условие останова алгоритма. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 23:11, 17 декабря 2016 (MSK)&lt;br /&gt;
** Условие останова описано в пункте 1.1 (четвертый подпункт) &lt;br /&gt;
* 1.2 — n и C не введены. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 23:11, 17 декабря 2016 (MSK)&lt;br /&gt;
** Исправлено&lt;br /&gt;
* 1.2 — в одном предложении написано, что xᵢ — вектор, а через запятую — что это i-тый компонент N-мерного вектора x. Если элементы вектора — это вектора, то, возможно, стоило написать что это матрица? (А матрица ли это?). [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 23:11, 17 декабря 2016 (MSK)&lt;br /&gt;
** Опечатка(тут X в uppercase): xᵢ — вектор, но в тоже время это i-тый компонент N-мерного вектора X (в общем случае X - это вектор из N элементов, которые кластеризуются. С практической точки зрения элементы это тоже вектора)&lt;br /&gt;
* 1.2 — Jₘ определён, но больше нигде не используется. &lt;br /&gt;
** Без обозначения величина выглядит странно. И нужна она только для математического описания.&lt;br /&gt;
***Ок, убрали.&lt;br /&gt;
* Пунктуация местами отсутствует в принципе. В том числе и в самом первом предложении. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 20:15, 17 декабря 2016 (MSK)&lt;br /&gt;
** В первом предложении поправили.&lt;br /&gt;
* Размерность входных векторов (p) не входит в сложность? Длина векторов (определена как |X| ниже) не входит в сложность? [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 20:15, 17 декабря 2016 (MSK)&lt;br /&gt;
** |X| входит (N - это тоже самое, исправили N на |X| для однообразия), во всех источниках длина кластеризуемых векторов (p) в сложности не фигурирует (в общем случае кластеризуются абстрактные объекты).&lt;br /&gt;
* Где определены N и D? Во входных данных их нет. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 20:15, 17 декабря 2016 (MSK)&lt;br /&gt;
** исправили N на |X|&lt;br /&gt;
* 1.6 — в терминах каких операций вычисляется сложность? [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 20:15, 17 декабря 2016 (MSK)&lt;br /&gt;
** указали&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
* не указан вклад каждого автора [[Участник:Coctic|Coctic]] ([[Обсуждение участника:Coctic|обсуждение]]) 12:58, 25 октября 2016 (MSK) - исправлено&lt;br /&gt;
:: Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 13:29, 31 октября 2016 (MSK)&lt;br /&gt;
* п. 1.9 не приведены оценки объема входных и выходных данных [[Участник:Coctic|Coctic]] ([[Обсуждение участника:Coctic|обсуждение]]) 12:58, 25 октября 2016 (MSK) - исправлено&lt;br /&gt;
:: Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 13:29, 31 октября 2016 (MSK)&lt;br /&gt;
* п. 2.4. Не приведена ссылка на текст исследуемой программы [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 18:28, 16 ноября 2016 (MSK)&lt;br /&gt;
** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:32, 28 ноября 2016 (MSK)&lt;br /&gt;
* п. 2.4. Не указана аппаратная платформа, на которой проводилось тестирование [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 18:28, 16 ноября 2016 (MSK)&lt;br /&gt;
** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:32, 28 ноября 2016 (MSK)&lt;br /&gt;
* п. 2.4. На рис. 2 и 3 подпись вертикальной оси накладывается на подписи шкалы  [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 18:28, 16 ноября 2016 (MSK)&lt;br /&gt;
** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:32, 28 ноября 2016 (MSK)&lt;br /&gt;
* п. 2.4. Не приведено никаких сведений о масштабируемости исследуемой программы. На рис. 2 и 3 приведены графики зависимости некоей &amp;quot;сложности&amp;quot; (какя сложность имеется в виду - не указано) от разных параметров. Как из этих графиков извлечь сведения о масштабируемости - не указано. [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 18:28, 16 ноября 2016 (MSK)&lt;br /&gt;
** Исправлено частично. В осях стало время в секундах, в подписях к рисункам по-прежнему непонятная &amp;quot;сложность&amp;quot;. Что в итоге на рисунках - неясно. [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:32, 28 ноября 2016 (MSK)&lt;br /&gt;
*** Указали в подписях к рисункам &amp;quot;зависимость времени работы&amp;quot;&lt;br /&gt;
**** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:31, 5 декабря 2016 (MSK)&lt;br /&gt;
* Графики на рис. 2 и 3 плохо читаются [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:32, 28 ноября 2016 (MSK)&lt;br /&gt;
** Добавили цветные поверхности&lt;br /&gt;
*** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:31, 5 декабря 2016 (MSK)&lt;br /&gt;
* Необходимо указать характеристики программно-аппаратной платформы (какой компилятор, с какими опциями использовался, какие версии библиотек, на каких узлах проводился запуск и т.д.) [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:32, 28 ноября 2016 (MSK)&lt;br /&gt;
**Указали компилятор и характеристики узлов на IBM Blue Gene/P&lt;br /&gt;
*** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:31, 5 декабря 2016 (MSK)&lt;/div&gt;</summary>
		<author><name>Demon smd</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Demon_smd&amp;diff=21219</id>
		<title>Обсуждение участника:Demon smd</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Demon_smd&amp;diff=21219"/>
		<updated>2016-12-18T16:45:56Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Статья [[Участник:Demon_smd/Нечеткий_алгоритм_С_средних]] =&lt;br /&gt;
&lt;br /&gt;
* У вас в сложности фигурирует количество итераций. В литературе есть какие-то оценки требуемого количества итераций исходя из входных параметров? Если есть, то хорошо бы указать. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 18:23, 18 декабря 2016 (MSK)&lt;br /&gt;
** Нет, в классической постановке задачи алгоритм работает пока есть улучшение результата (это описано в 1.1 пункт 4.) А количество итераций зависит от параметра эпсилон, входных данных и сгенерированного начального размещения.&lt;br /&gt;
* 1.8 — Из текста непонятно, откуда получен логарифм. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 23:11, 17 декабря 2016 (MSK)&lt;br /&gt;
** ---&lt;br /&gt;
* 1.8 — «взятие адреса» — имеется ввиду чтение элемента из памяти, да? [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 23:11, 17 декабря 2016 (MSK)&lt;br /&gt;
** Да, верно&lt;br /&gt;
*** Поправьте текст, пожалуйста. У «взятия адреса» есть определение и оно не соответствует тому, как вы это использовали. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 16:50, 18 декабря 2016 (MSK)&lt;br /&gt;
* 1.6 — в оценки сложности итерации не учтена размерность входных векторов. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 23:11, 17 декабря 2016 (MSK)&lt;br /&gt;
** --- &lt;br /&gt;
* 1.4 — не описано условие останова алгоритма. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 23:11, 17 декабря 2016 (MSK)&lt;br /&gt;
** Условие останова описано в пункте 1.1 (четвертый подпункт) &lt;br /&gt;
* 1.2 — n и C не введены. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 23:11, 17 декабря 2016 (MSK)&lt;br /&gt;
** Исправлено&lt;br /&gt;
* 1.2 — в одном предложении написано, что xᵢ — вектор, а через запятую — что это i-тый компонент N-мерного вектора x. Если элементы вектора — это вектора, то, возможно, стоило написать что это матрица? (А матрица ли это?). [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 23:11, 17 декабря 2016 (MSK)&lt;br /&gt;
** Опечатка(тут X в uppercase): xᵢ — вектор, но в тоже время это i-тый компонент N-мерного вектора X (в общем случае X - это вектор из N элементов, которые кластеризуются. С практической точки зрения элементы это тоже вектора)&lt;br /&gt;
* 1.2 — Jₘ определён, но больше нигде не используется. &lt;br /&gt;
** Без обозначения величина выглядит странно. И нужна она только для математического описания.&lt;br /&gt;
***Ок, убрали.&lt;br /&gt;
* Пунктуация местами отсутствует в принципе. В том числе и в самом первом предложении. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 20:15, 17 декабря 2016 (MSK)&lt;br /&gt;
** В первом предложении поправили.&lt;br /&gt;
* Размерность входных векторов (p) не входит в сложность? Длина векторов (определена как |X| ниже) не входит в сложность? [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 20:15, 17 декабря 2016 (MSK)&lt;br /&gt;
** |X| входит (N - это тоже самое, исправили N на |X| для однообразия), во всех источниках длина кластеризуемых векторов (p) в сложности не фигурирует (в общем случае кластеризуются абстрактные объекты).&lt;br /&gt;
* Где определены N и D? Во входных данных их нет. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 20:15, 17 декабря 2016 (MSK)&lt;br /&gt;
** исправили N на |X|&lt;br /&gt;
* 1.6 — в терминах каких операций вычисляется сложность? [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 20:15, 17 декабря 2016 (MSK)&lt;br /&gt;
** указали&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
* не указан вклад каждого автора [[Участник:Coctic|Coctic]] ([[Обсуждение участника:Coctic|обсуждение]]) 12:58, 25 октября 2016 (MSK) - исправлено&lt;br /&gt;
:: Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 13:29, 31 октября 2016 (MSK)&lt;br /&gt;
* п. 1.9 не приведены оценки объема входных и выходных данных [[Участник:Coctic|Coctic]] ([[Обсуждение участника:Coctic|обсуждение]]) 12:58, 25 октября 2016 (MSK) - исправлено&lt;br /&gt;
:: Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 13:29, 31 октября 2016 (MSK)&lt;br /&gt;
* п. 2.4. Не приведена ссылка на текст исследуемой программы [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 18:28, 16 ноября 2016 (MSK)&lt;br /&gt;
** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:32, 28 ноября 2016 (MSK)&lt;br /&gt;
* п. 2.4. Не указана аппаратная платформа, на которой проводилось тестирование [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 18:28, 16 ноября 2016 (MSK)&lt;br /&gt;
** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:32, 28 ноября 2016 (MSK)&lt;br /&gt;
* п. 2.4. На рис. 2 и 3 подпись вертикальной оси накладывается на подписи шкалы  [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 18:28, 16 ноября 2016 (MSK)&lt;br /&gt;
** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:32, 28 ноября 2016 (MSK)&lt;br /&gt;
* п. 2.4. Не приведено никаких сведений о масштабируемости исследуемой программы. На рис. 2 и 3 приведены графики зависимости некоей &amp;quot;сложности&amp;quot; (какя сложность имеется в виду - не указано) от разных параметров. Как из этих графиков извлечь сведения о масштабируемости - не указано. [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 18:28, 16 ноября 2016 (MSK)&lt;br /&gt;
** Исправлено частично. В осях стало время в секундах, в подписях к рисункам по-прежнему непонятная &amp;quot;сложность&amp;quot;. Что в итоге на рисунках - неясно. [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:32, 28 ноября 2016 (MSK)&lt;br /&gt;
*** Указали в подписях к рисункам &amp;quot;зависимость времени работы&amp;quot;&lt;br /&gt;
**** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:31, 5 декабря 2016 (MSK)&lt;br /&gt;
* Графики на рис. 2 и 3 плохо читаются [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:32, 28 ноября 2016 (MSK)&lt;br /&gt;
** Добавили цветные поверхности&lt;br /&gt;
*** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:31, 5 декабря 2016 (MSK)&lt;br /&gt;
* Необходимо указать характеристики программно-аппаратной платформы (какой компилятор, с какими опциями использовался, какие версии библиотек, на каких узлах проводился запуск и т.д.) [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:32, 28 ноября 2016 (MSK)&lt;br /&gt;
**Указали компилятор и характеристики узлов на IBM Blue Gene/P&lt;br /&gt;
*** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:31, 5 декабря 2016 (MSK)&lt;/div&gt;</summary>
		<author><name>Demon smd</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Demon_smd&amp;diff=21218</id>
		<title>Обсуждение участника:Demon smd</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Demon_smd&amp;diff=21218"/>
		<updated>2016-12-18T16:40:38Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Статья [[Участник:Demon_smd/Нечеткий_алгоритм_С_средних]] =&lt;br /&gt;
&lt;br /&gt;
* У вас в сложности фигурирует количество итераций. В литературе есть какие-то оценки требуемого количества итераций исходя из входных параметров? Если есть, то хорошо бы указать. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 18:23, 18 декабря 2016 (MSK)&lt;br /&gt;
** ---&lt;br /&gt;
* 1.8 — Из текста непонятно, откуда получен логарифм. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 23:11, 17 декабря 2016 (MSK)&lt;br /&gt;
** ---&lt;br /&gt;
* 1.8 — «взятие адреса» — имеется ввиду чтение элемента из памяти, да? [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 23:11, 17 декабря 2016 (MSK)&lt;br /&gt;
** Да, верно&lt;br /&gt;
*** Поправьте текст, пожалуйста. У «взятия адреса» есть определение и оно не соответствует тому, как вы это использовали. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 16:50, 18 декабря 2016 (MSK)&lt;br /&gt;
* 1.6 — в оценки сложности итерации не учтена размерность входных векторов. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 23:11, 17 декабря 2016 (MSK)&lt;br /&gt;
** --- &lt;br /&gt;
* 1.4 — не описано условие останова алгоритма. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 23:11, 17 декабря 2016 (MSK)&lt;br /&gt;
** Условие останова описано в пункте 1.1 (четвертый подпункт) &lt;br /&gt;
* 1.2 — n и C не введены. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 23:11, 17 декабря 2016 (MSK)&lt;br /&gt;
** Исправлено&lt;br /&gt;
* 1.2 — в одном предложении написано, что xᵢ — вектор, а через запятую — что это i-тый компонент N-мерного вектора x. Если элементы вектора — это вектора, то, возможно, стоило написать что это матрица? (А матрица ли это?). [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 23:11, 17 декабря 2016 (MSK)&lt;br /&gt;
** Опечатка(тут X в uppercase): xᵢ — вектор, но в тоже время это i-тый компонент N-мерного вектора X (в общем случае X - это вектор из N элементов, которые кластеризуются. С практической точки зрения элементы это тоже вектора)&lt;br /&gt;
* 1.2 — Jₘ определён, но больше нигде не используется. &lt;br /&gt;
** Без обозначения величина выглядит странно. И нужна она только для математического описания.&lt;br /&gt;
***Ок, убрали.&lt;br /&gt;
* Пунктуация местами отсутствует в принципе. В том числе и в самом первом предложении. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 20:15, 17 декабря 2016 (MSK)&lt;br /&gt;
** В первом предложении поправили.&lt;br /&gt;
* Размерность входных векторов (p) не входит в сложность? Длина векторов (определена как |X| ниже) не входит в сложность? [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 20:15, 17 декабря 2016 (MSK)&lt;br /&gt;
** |X| входит (N - это тоже самое, исправили N на |X| для однообразия), во всех источниках длина кластеризуемых векторов (p) в сложности не фигурирует (в общем случае кластеризуются абстрактные объекты).&lt;br /&gt;
* Где определены N и D? Во входных данных их нет. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 20:15, 17 декабря 2016 (MSK)&lt;br /&gt;
** исправили N на |X|&lt;br /&gt;
* 1.6 — в терминах каких операций вычисляется сложность? [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 20:15, 17 декабря 2016 (MSK)&lt;br /&gt;
** указали&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
* не указан вклад каждого автора [[Участник:Coctic|Coctic]] ([[Обсуждение участника:Coctic|обсуждение]]) 12:58, 25 октября 2016 (MSK) - исправлено&lt;br /&gt;
:: Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 13:29, 31 октября 2016 (MSK)&lt;br /&gt;
* п. 1.9 не приведены оценки объема входных и выходных данных [[Участник:Coctic|Coctic]] ([[Обсуждение участника:Coctic|обсуждение]]) 12:58, 25 октября 2016 (MSK) - исправлено&lt;br /&gt;
:: Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 13:29, 31 октября 2016 (MSK)&lt;br /&gt;
* п. 2.4. Не приведена ссылка на текст исследуемой программы [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 18:28, 16 ноября 2016 (MSK)&lt;br /&gt;
** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:32, 28 ноября 2016 (MSK)&lt;br /&gt;
* п. 2.4. Не указана аппаратная платформа, на которой проводилось тестирование [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 18:28, 16 ноября 2016 (MSK)&lt;br /&gt;
** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:32, 28 ноября 2016 (MSK)&lt;br /&gt;
* п. 2.4. На рис. 2 и 3 подпись вертикальной оси накладывается на подписи шкалы  [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 18:28, 16 ноября 2016 (MSK)&lt;br /&gt;
** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:32, 28 ноября 2016 (MSK)&lt;br /&gt;
* п. 2.4. Не приведено никаких сведений о масштабируемости исследуемой программы. На рис. 2 и 3 приведены графики зависимости некоей &amp;quot;сложности&amp;quot; (какя сложность имеется в виду - не указано) от разных параметров. Как из этих графиков извлечь сведения о масштабируемости - не указано. [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 18:28, 16 ноября 2016 (MSK)&lt;br /&gt;
** Исправлено частично. В осях стало время в секундах, в подписях к рисункам по-прежнему непонятная &amp;quot;сложность&amp;quot;. Что в итоге на рисунках - неясно. [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:32, 28 ноября 2016 (MSK)&lt;br /&gt;
*** Указали в подписях к рисункам &amp;quot;зависимость времени работы&amp;quot;&lt;br /&gt;
**** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:31, 5 декабря 2016 (MSK)&lt;br /&gt;
* Графики на рис. 2 и 3 плохо читаются [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:32, 28 ноября 2016 (MSK)&lt;br /&gt;
** Добавили цветные поверхности&lt;br /&gt;
*** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:31, 5 декабря 2016 (MSK)&lt;br /&gt;
* Необходимо указать характеристики программно-аппаратной платформы (какой компилятор, с какими опциями использовался, какие версии библиотек, на каких узлах проводился запуск и т.д.) [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:32, 28 ноября 2016 (MSK)&lt;br /&gt;
**Указали компилятор и характеристики узлов на IBM Blue Gene/P&lt;br /&gt;
*** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:31, 5 декабря 2016 (MSK)&lt;/div&gt;</summary>
		<author><name>Demon smd</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Demon_smd&amp;diff=21217</id>
		<title>Обсуждение участника:Demon smd</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Demon_smd&amp;diff=21217"/>
		<updated>2016-12-18T16:29:35Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Статья [[Участник:Demon_smd/Нечеткий_алгоритм_С_средних]] =&lt;br /&gt;
&lt;br /&gt;
* У вас в сложности фигурирует количество итераций. В литературе есть какие-то оценки требуемого количества итераций исходя из входных параметров? Если есть, то хорошо бы указать. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 18:23, 18 декабря 2016 (MSK)&lt;br /&gt;
* 1.8 — Из текста непонятно, откуда получен логарифм. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 23:11, 17 декабря 2016 (MSK)&lt;br /&gt;
* 1.8 — «взятие адреса» — имеется ввиду чтение элемента из памяти, да? [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 23:11, 17 декабря 2016 (MSK)&lt;br /&gt;
** Да, верно&lt;br /&gt;
*** Поправьте текст, пожалуйста. У «взятия адреса» есть определение и оно не соответствует тому, как вы это использовали. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 16:50, 18 декабря 2016 (MSK)&lt;br /&gt;
* 1.6 — в оценки сложности итерации не учтена размерность входных векторов. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 23:11, 17 декабря 2016 (MSK)&lt;br /&gt;
* 1.4 — не описано условие останова алгоритма. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 23:11, 17 декабря 2016 (MSK)&lt;br /&gt;
** Условие останова описано в пункте 1.1 (четвертый подпункт) &lt;br /&gt;
* 1.2 — n и C не введены. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 23:11, 17 декабря 2016 (MSK)&lt;br /&gt;
** Исправлено&lt;br /&gt;
* 1.2 — в одном предложении написано, что xᵢ — вектор, а через запятую — что это i-тый компонент N-мерного вектора x. Если элементы вектора — это вектора, то, возможно, стоило написать что это матрица? (А матрица ли это?). [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 23:11, 17 декабря 2016 (MSK)&lt;br /&gt;
** Опечатка(тут X в uppercase): xᵢ — вектор, но в тоже время это i-тый компонент N-мерного вектора X (в общем случае X - это вектор из N элементов, которые кластеризуются. С практической точки зрения элементы это тоже вектора)&lt;br /&gt;
* 1.2 — Jₘ определён, но больше нигде не используется. &lt;br /&gt;
** Без обозначения величина выглядит странно. И нужна она только для математического описания.&lt;br /&gt;
***Ок, убрали.&lt;br /&gt;
* Пунктуация местами отсутствует в принципе. В том числе и в самом первом предложении. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 20:15, 17 декабря 2016 (MSK)&lt;br /&gt;
** В первом предложении поправили.&lt;br /&gt;
* Размерность входных векторов (p) не входит в сложность? Длина векторов (определена как |X| ниже) не входит в сложность? [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 20:15, 17 декабря 2016 (MSK)&lt;br /&gt;
** |X| входит (N - это тоже самое, исправили N на |X| для однообразия), во всех источниках длина кластеризуемых векторов (p) в сложности не фигурирует (в общем случае кластеризуются абстрактные объекты).&lt;br /&gt;
* Где определены N и D? Во входных данных их нет. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 20:15, 17 декабря 2016 (MSK)&lt;br /&gt;
** исправили N на |X|&lt;br /&gt;
* 1.6 — в терминах каких операций вычисляется сложность? [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 20:15, 17 декабря 2016 (MSK)&lt;br /&gt;
** указали&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
* не указан вклад каждого автора [[Участник:Coctic|Coctic]] ([[Обсуждение участника:Coctic|обсуждение]]) 12:58, 25 октября 2016 (MSK) - исправлено&lt;br /&gt;
:: Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 13:29, 31 октября 2016 (MSK)&lt;br /&gt;
* п. 1.9 не приведены оценки объема входных и выходных данных [[Участник:Coctic|Coctic]] ([[Обсуждение участника:Coctic|обсуждение]]) 12:58, 25 октября 2016 (MSK) - исправлено&lt;br /&gt;
:: Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 13:29, 31 октября 2016 (MSK)&lt;br /&gt;
* п. 2.4. Не приведена ссылка на текст исследуемой программы [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 18:28, 16 ноября 2016 (MSK)&lt;br /&gt;
** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:32, 28 ноября 2016 (MSK)&lt;br /&gt;
* п. 2.4. Не указана аппаратная платформа, на которой проводилось тестирование [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 18:28, 16 ноября 2016 (MSK)&lt;br /&gt;
** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:32, 28 ноября 2016 (MSK)&lt;br /&gt;
* п. 2.4. На рис. 2 и 3 подпись вертикальной оси накладывается на подписи шкалы  [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 18:28, 16 ноября 2016 (MSK)&lt;br /&gt;
** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:32, 28 ноября 2016 (MSK)&lt;br /&gt;
* п. 2.4. Не приведено никаких сведений о масштабируемости исследуемой программы. На рис. 2 и 3 приведены графики зависимости некоей &amp;quot;сложности&amp;quot; (какя сложность имеется в виду - не указано) от разных параметров. Как из этих графиков извлечь сведения о масштабируемости - не указано. [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 18:28, 16 ноября 2016 (MSK)&lt;br /&gt;
** Исправлено частично. В осях стало время в секундах, в подписях к рисункам по-прежнему непонятная &amp;quot;сложность&amp;quot;. Что в итоге на рисунках - неясно. [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:32, 28 ноября 2016 (MSK)&lt;br /&gt;
*** Указали в подписях к рисункам &amp;quot;зависимость времени работы&amp;quot;&lt;br /&gt;
**** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:31, 5 декабря 2016 (MSK)&lt;br /&gt;
* Графики на рис. 2 и 3 плохо читаются [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:32, 28 ноября 2016 (MSK)&lt;br /&gt;
** Добавили цветные поверхности&lt;br /&gt;
*** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:31, 5 декабря 2016 (MSK)&lt;br /&gt;
* Необходимо указать характеристики программно-аппаратной платформы (какой компилятор, с какими опциями использовался, какие версии библиотек, на каких узлах проводился запуск и т.д.) [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:32, 28 ноября 2016 (MSK)&lt;br /&gt;
**Указали компилятор и характеристики узлов на IBM Blue Gene/P&lt;br /&gt;
*** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:31, 5 декабря 2016 (MSK)&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=21216</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=21216"/>
		<updated>2016-12-18T16:28:55Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|{{REVISIONUSER}}}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Нечеткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(C^2*|X|*D*IterNumber)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(\log_{2}C^4*|X|^3) * IterNumber&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(C^2*|X|)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;|X|*p&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - размерность входных векторов&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;|X|*C &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: &lt;br /&gt;
[[Участник:Demon smd|Д.А.Гуськов]] &lt;br /&gt;
[[Участник:marina abramenkova|М.А.Абраменкова]].&lt;br /&gt;
Во все разделы вклад равноценный.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризуемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних заключается в следующем. Изначально для каждого вектора определяется случайным образом вероятность принадлежности вектора к каждому кластеру. Далее запускается итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) расчёт центров кластеров&lt;br /&gt;
&lt;br /&gt;
2) расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации: если разница этих значений меньше установленного значения, то алгоритм прекращает работу (решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности)&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{i = 1}^{|X|}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty , \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;|X|&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - количество кластеров, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные на каждой итерации ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^{(k)} - u_{i,j}^{(k-1)}|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&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;
В каждой итерации алгоритма происходит 3 основных действия описанных в п. 1.2.1:&lt;br /&gt;
*вычисление центров кластеров&lt;br /&gt;
*вычисление коэффициентов принадлежности&lt;br /&gt;
*вычисление решающей функции&lt;br /&gt;
Подробное описание макроструктур в виде кода приведено в пункте 1.5&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Схему реализации последовательного алгоритма можно описать на C++ следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FCM (X[], C, m, eps){&lt;br /&gt;
    float deside = 0;&lt;br /&gt;
    float newDeside = 0;&lt;br /&gt;
    generateMembershipDegree();            //заполняет uPrev[][] случайными нормрованными коэффициентами&lt;br /&gt;
    while (true){&lt;br /&gt;
        newDeside = deside;&lt;br /&gt;
&lt;br /&gt;
        //вычисление центров кластеров&lt;br /&gt;
        for (int j=0; j&amp;lt;C; j++){           //для каждого кластера&lt;br /&gt;
            float numerator = 0;&lt;br /&gt;
            float denumerator = 0;&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++){        //для каждого вектора&lt;br /&gt;
                numerator+=pow(u[i][j], m) * x[i];&lt;br /&gt;
                denumerator+=pow(u[i][j], m);&lt;br /&gt;
            }&lt;br /&gt;
            c[j] = numerator / denumerator;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //вычисление коэффициентов u[][]&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                sum = 0;&lt;br /&gt;
                for (int k=0; k&amp;lt;C; k++)&lt;br /&gt;
                    sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&lt;br /&gt;
                u[i][j] = 1/sum&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        //определения максимального различия между u[][] и uPrev[][]&lt;br /&gt;
        float max = 0;&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                if (abs(uPrev[i][j]-u[i][j])&amp;gt;max)&lt;br /&gt;
                    max = abs(uPrev[i][j]-u[i][j]);&lt;br /&gt;
&lt;br /&gt;
        if (eps &amp;lt;= max)&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
                for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                    uPrev[i][j]=u[i][j];&lt;br /&gt;
        else&lt;br /&gt;
            break;&lt;br /&gt;
             &lt;br /&gt;
    }&lt;br /&gt;
    return u;&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;
Под операцией будем понимать выражение в языке с++ из пункта 1.5, находящееся в теле цикла (например, выражения &amp;quot;sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&amp;quot; или &amp;quot;uPrev[i][j]=u[i][j];&amp;quot; считаются за одну операцию). Так как при больших входных объёмах данных сложность алгоритма в большей степени зависит от количества входных данных, и незначительно зависит от сложности операций,то при оценке сложности алгоритма сложность выражений можно считать равной единице. Так как в данном алгоритме количество итераций не является фиксированным и зависит от:&lt;br /&gt;
* параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
* набора входных векторов &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
* выбора начальных коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;&lt;br /&gt;
то в данном пункте будет приведена сложность одной итерации относительно количества входных векторов.&lt;br /&gt;
Как видно из предыдущего пункта, для вычисления центров кластеров требуется &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, для определения коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;O(C^2*|X|)&amp;lt;/math&amp;gt; операций, а для вычисления решающей функции - &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, где &amp;lt;math&amp;gt;|X|&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;O(C^2*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Как видно из пункта 1.5, на каждом действии каждой итерации алгоритма все операции, выполняющиеся в цикле, не зависят друг от друга и могут быть распараллелены. Это показано на Рисунке 1.&lt;br /&gt;
&lt;br /&gt;
[[File:FCMIG.png|thumb|center|1200px|Рисунок 1. Информационный граф алгоритма. (1)-(7) - это наборы последовательных действий (например, (2) - последовательные операции деления, чтения элемента из памяти и присваивания).]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На каждом ярусе ярусно-параллельной формы алгоритма будет располагаться конечное число элементарных операций, например, чтение элемента из памяти, сложение или возведение в степень. Информационый граф из п.1.7 изображает свёрнутую ярусно-параллельную форму алгоритма. &lt;br /&gt;
&lt;br /&gt;
Сложность алгоритма будем рассчитывать в предположении, что число вычислительных ядер стремится к бесконечности. Как видно из информационного графа, параллельная сложность вычисления центров кластеров составляет &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;, вычисления коэффициентов принадлежности - &amp;lt;math&amp;gt;O(\log_{2} C^2*|X|)&amp;lt;/math&amp;gt;, а вычисления решающей функции - не больше чем &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом параллельная сложность итерации алгоритма составляет &amp;lt;math&amp;gt;O(\log_{2} C^4*|X|^3)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Так как задачи, решаемые в макроструктуре алгоритма могут быть сведены к задачам вычисления суммы элементов массива и максимального элемента массива, то на &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом ярусе графа будет находиться &amp;lt;math&amp;gt;{N}\over{2^i}&amp;lt;/math&amp;gt; операции, где N - количество элементов массива.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; - набор из &amp;lt;math&amp;gt;|X|&amp;lt;/math&amp;gt; входных векторов длины &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - количество кластеров&lt;br /&gt;
* &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
Объем входных данных: &amp;lt;math&amp;gt;|X|*p+3&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - матрица принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
Объем выходных данных: &amp;lt;math&amp;gt;|X|*C&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Увеличение скорости работы алгоритма при распараллеливании на бесконечном количестве процессоров составляет &amp;lt;math&amp;gt;O({{C^2*|X|}\over{\log_{2} (C^4*|X|^3)}})&amp;lt;/math&amp;gt;. Например, для разбиения 1000 элементов на 10 кластеров производительность параллельного алгоритма будет в 2315 раз больше, а на 20 кластеров - уже в 8477 раз.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
Как видно из предыдущих пунктов, масштабируется данный алгоритм хорошо. С увеличением количества процессоров время работы падает, а с увеличением количества входных данных и количества кластеров - растёт. &lt;br /&gt;
На рисунках показаны результаты запусков алгоритма на разном количестве входных данных и процессоров на массивно-параллельной вычислительной системе Blue Gene/P. Использовался компилятор mpixlcxx без указания специфических опций. Запуски производились в режиме SMP (на каждом ядре 1 MPI процесс из 4 SMP нитей, 2 Гб памяти). Характеристики вычислительного узла: 4 ядерный 32-битный процессор PowerPC 850 Мгц.&lt;br /&gt;
&lt;br /&gt;
Исходных код программы можно найти здесь: https://github.com/demonsmd/superPrak&lt;br /&gt;
[[File:FCMvectors_color2.png|thumb|center|1250px|Рисунок 2. Масштабируемость алгоритма. Зависимость времени работы алгоритма от количества процессоров и входных данных при фиксированном количестве кластеров.]]&lt;br /&gt;
[[File:FCMclusters_color.png|thumb|center|1250px|Рисунок 3. Масштабируемость алгоритма. Зависимость времени работы алгоритма от количества процессоров и кластеров при фиксированном количестве входных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Существует множество реализаций данного алгоритма. Рассмотрим некоторые из них:&lt;br /&gt;
&lt;br /&gt;
- Например, тут: https://habrahabr.ru/post/208496/&lt;br /&gt;
&amp;lt;ref&amp;gt;Нестер А. &amp;quot;Алгоритм нечёткой кластеризации fuzzy c-means на PHP&amp;quot;. [html](https://habrahabr.ru/post/208496/)&amp;lt;/ref&amp;gt;&lt;br /&gt;
приведено краткое описание алгоритма и приведена его реализация на php. В данной статье довольно подробно расписан каждый шаг алгоритма и приведён соответствующий ему фрагмент кода.&lt;br /&gt;
&lt;br /&gt;
- Тут: http://num-meth.srcc.msu.ru/zhurnal/tom_2012/v13r207.html&lt;br /&gt;
&amp;lt;ref&amp;gt;Миниахметов Р.М., Цымблер М.Л. &amp;quot;Интеграция алгоритма кластеризации Fuzzy c-Means в PostgreSQL&amp;quot;. [html](http://num-meth.srcc.msu.ru/zhurnal/tom_2012/v13r207.html)&amp;lt;/ref&amp;gt;&lt;br /&gt;
приводится реализация алгоритма для PostgreSQL, а также прилагается скрипт внедрения алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Demon_smd&amp;diff=21215</id>
		<title>Обсуждение участника:Demon smd</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Demon_smd&amp;diff=21215"/>
		<updated>2016-12-18T16:26:59Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Статья [[Участник:Demon_smd/Нечеткий_алгоритм_С_средних]] =&lt;br /&gt;
&lt;br /&gt;
* У вас в сложности фигурирует количество итераций. В литературе есть какие-то оценки требуемого количества итераций исходя из входных параметров? Если есть, то хорошо бы указать. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 18:23, 18 декабря 2016 (MSK)&lt;br /&gt;
* 1.8 — Из текста непонятно, откуда получен логарифм. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 23:11, 17 декабря 2016 (MSK)&lt;br /&gt;
* 1.8 — «взятие адреса» — имеется ввиду чтение элемента из памяти, да? [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 23:11, 17 декабря 2016 (MSK)&lt;br /&gt;
** Да, верно&lt;br /&gt;
*** Поправьте текст, пожалуйста. У «взятия адреса» есть определение и оно не соответствует тому, как вы это использовали. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 16:50, 18 декабря 2016 (MSK)&lt;br /&gt;
* 1.6 — в оценки сложности итерации не учтена размерность входных векторов. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 23:11, 17 декабря 2016 (MSK)&lt;br /&gt;
* 1.4 — не описано условие останова алгоритма. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 23:11, 17 декабря 2016 (MSK)&lt;br /&gt;
** Условие останова описано в пункте 1.1 (четвертый подпункт) &lt;br /&gt;
* 1.2 — n и C не введены. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 23:11, 17 декабря 2016 (MSK)&lt;br /&gt;
** Исправлено&lt;br /&gt;
* 1.2 — в одном предложении написано, что xᵢ — вектор, а через запятую — что это i-тый компонент N-мерного вектора x. Если элементы вектора — это вектора, то, возможно, стоило написать что это матрица? (А матрица ли это?). [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 23:11, 17 декабря 2016 (MSK)&lt;br /&gt;
** Опечатка(тут X в uppercase): xᵢ — вектор, но в тоже время это i-тый компонент N-мерного вектора X (в общем случае X - это вектор из N элементов, которые кластеризуются. С практической точки зрения элементы это тоже вектора)&lt;br /&gt;
* 1.2 — Jₘ определён, но больше нигде не используется. &lt;br /&gt;
** Без обозначения величина выглядит странно. И нужна она только для математического описания.&lt;br /&gt;
* Пунктуация местами отсутствует в принципе. В том числе и в самом первом предложении. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 20:15, 17 декабря 2016 (MSK)&lt;br /&gt;
** В первом предложении поправили.&lt;br /&gt;
* Размерность входных векторов (p) не входит в сложность? Длина векторов (определена как |X| ниже) не входит в сложность? [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 20:15, 17 декабря 2016 (MSK)&lt;br /&gt;
** |X| входит (N - это тоже самое, исправили N на |X| для однообразия), во всех источниках длина кластеризуемых векторов (p) в сложности не фигурирует (в общем случае кластеризуются абстрактные объекты).&lt;br /&gt;
* Где определены N и D? Во входных данных их нет. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 20:15, 17 декабря 2016 (MSK)&lt;br /&gt;
** исправили N на |X|&lt;br /&gt;
* 1.6 — в терминах каких операций вычисляется сложность? [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 20:15, 17 декабря 2016 (MSK)&lt;br /&gt;
** указали&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
* не указан вклад каждого автора [[Участник:Coctic|Coctic]] ([[Обсуждение участника:Coctic|обсуждение]]) 12:58, 25 октября 2016 (MSK) - исправлено&lt;br /&gt;
:: Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 13:29, 31 октября 2016 (MSK)&lt;br /&gt;
* п. 1.9 не приведены оценки объема входных и выходных данных [[Участник:Coctic|Coctic]] ([[Обсуждение участника:Coctic|обсуждение]]) 12:58, 25 октября 2016 (MSK) - исправлено&lt;br /&gt;
:: Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 13:29, 31 октября 2016 (MSK)&lt;br /&gt;
* п. 2.4. Не приведена ссылка на текст исследуемой программы [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 18:28, 16 ноября 2016 (MSK)&lt;br /&gt;
** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:32, 28 ноября 2016 (MSK)&lt;br /&gt;
* п. 2.4. Не указана аппаратная платформа, на которой проводилось тестирование [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 18:28, 16 ноября 2016 (MSK)&lt;br /&gt;
** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:32, 28 ноября 2016 (MSK)&lt;br /&gt;
* п. 2.4. На рис. 2 и 3 подпись вертикальной оси накладывается на подписи шкалы  [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 18:28, 16 ноября 2016 (MSK)&lt;br /&gt;
** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:32, 28 ноября 2016 (MSK)&lt;br /&gt;
* п. 2.4. Не приведено никаких сведений о масштабируемости исследуемой программы. На рис. 2 и 3 приведены графики зависимости некоей &amp;quot;сложности&amp;quot; (какя сложность имеется в виду - не указано) от разных параметров. Как из этих графиков извлечь сведения о масштабируемости - не указано. [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 18:28, 16 ноября 2016 (MSK)&lt;br /&gt;
** Исправлено частично. В осях стало время в секундах, в подписях к рисункам по-прежнему непонятная &amp;quot;сложность&amp;quot;. Что в итоге на рисунках - неясно. [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:32, 28 ноября 2016 (MSK)&lt;br /&gt;
*** Указали в подписях к рисункам &amp;quot;зависимость времени работы&amp;quot;&lt;br /&gt;
**** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:31, 5 декабря 2016 (MSK)&lt;br /&gt;
* Графики на рис. 2 и 3 плохо читаются [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:32, 28 ноября 2016 (MSK)&lt;br /&gt;
** Добавили цветные поверхности&lt;br /&gt;
*** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:31, 5 декабря 2016 (MSK)&lt;br /&gt;
* Необходимо указать характеристики программно-аппаратной платформы (какой компилятор, с какими опциями использовался, какие версии библиотек, на каких узлах проводился запуск и т.д.) [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:32, 28 ноября 2016 (MSK)&lt;br /&gt;
**Указали компилятор и характеристики узлов на IBM Blue Gene/P&lt;br /&gt;
*** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:31, 5 декабря 2016 (MSK)&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=21214</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=21214"/>
		<updated>2016-12-18T16:25:58Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: /* Последовательная сложность алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|{{REVISIONUSER}}}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Нечеткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(C^2*|X|*D*IterNumber)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(\log_{2}C^4*|X|^3) * IterNumber&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(C^2*|X|)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;|X|*p&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - размерность входных векторов&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;|X|*C &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: &lt;br /&gt;
[[Участник:Demon smd|Д.А.Гуськов]] &lt;br /&gt;
[[Участник:marina abramenkova|М.А.Абраменкова]].&lt;br /&gt;
Во все разделы вклад равноценный.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризуемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних заключается в следующем. Изначально для каждого вектора определяется случайным образом вероятность принадлежности вектора к каждому кластеру. Далее запускается итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) расчёт центров кластеров&lt;br /&gt;
&lt;br /&gt;
2) расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации: если разница этих значений меньше установленного значения, то алгоритм прекращает работу (решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности)&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
J_{m} = \sum_{i = 1}^{|X|}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty , \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;|X|&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - количество кластеров, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные на каждой итерации ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^{(k)} - u_{i,j}^{(k-1)}|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&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;
В каждой итерации алгоритма происходит 3 основных действия описанных в п. 1.2.1:&lt;br /&gt;
*вычисление центров кластеров&lt;br /&gt;
*вычисление коэффициентов принадлежности&lt;br /&gt;
*вычисление решающей функции&lt;br /&gt;
Подробное описание макроструктур в виде кода приведено в пункте 1.5&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Схему реализации последовательного алгоритма можно описать на C++ следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FCM (X[], C, m, eps){&lt;br /&gt;
    float deside = 0;&lt;br /&gt;
    float newDeside = 0;&lt;br /&gt;
    generateMembershipDegree();            //заполняет uPrev[][] случайными нормрованными коэффициентами&lt;br /&gt;
    while (true){&lt;br /&gt;
        newDeside = deside;&lt;br /&gt;
&lt;br /&gt;
        //вычисление центров кластеров&lt;br /&gt;
        for (int j=0; j&amp;lt;C; j++){           //для каждого кластера&lt;br /&gt;
            float numerator = 0;&lt;br /&gt;
            float denumerator = 0;&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++){        //для каждого вектора&lt;br /&gt;
                numerator+=pow(u[i][j], m) * x[i];&lt;br /&gt;
                denumerator+=pow(u[i][j], m);&lt;br /&gt;
            }&lt;br /&gt;
            c[j] = numerator / denumerator;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //вычисление коэффициентов u[][]&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                sum = 0;&lt;br /&gt;
                for (int k=0; k&amp;lt;C; k++)&lt;br /&gt;
                    sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&lt;br /&gt;
                u[i][j] = 1/sum&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        //определения максимального различия между u[][] и uPrev[][]&lt;br /&gt;
        float max = 0;&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                if (abs(uPrev[i][j]-u[i][j])&amp;gt;max)&lt;br /&gt;
                    max = abs(uPrev[i][j]-u[i][j]);&lt;br /&gt;
&lt;br /&gt;
        if (eps &amp;lt;= max)&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
                for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                    uPrev[i][j]=u[i][j];&lt;br /&gt;
        else&lt;br /&gt;
            break;&lt;br /&gt;
             &lt;br /&gt;
    }&lt;br /&gt;
    return u;&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;
Под операцией будем понимать выражение в языке с++ из пункта 1.5, находящееся в теле цикла (например, выражения &amp;quot;sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&amp;quot; или &amp;quot;uPrev[i][j]=u[i][j];&amp;quot; считаются за одну операцию). Так как при больших входных объёмах данных сложность алгоритма в большей степени зависит от количества входных данных, и незначительно зависит от сложности операций,то при оценке сложности алгоритма сложность выражений можно считать равной единице. Так как в данном алгоритме количество итераций не является фиксированным и зависит от:&lt;br /&gt;
* параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
* набора входных векторов &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
* выбора начальных коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;&lt;br /&gt;
то в данном пункте будет приведена сложность одной итерации относительно количества входных векторов.&lt;br /&gt;
Как видно из предыдущего пункта, для вычисления центров кластеров требуется &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, для определения коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;O(C^2*|X|)&amp;lt;/math&amp;gt; операций, а для вычисления решающей функции - &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, где &amp;lt;math&amp;gt;|X|&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;O(C^2*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Как видно из пункта 1.5, на каждом действии каждой итерации алгоритма все операции, выполняющиеся в цикле, не зависят друг от друга и могут быть распараллелены. Это показано на Рисунке 1.&lt;br /&gt;
&lt;br /&gt;
[[File:FCMIG.png|thumb|center|1200px|Рисунок 1. Информационный граф алгоритма. (1)-(7) - это наборы последовательных действий (например, (2) - последовательные операции деления, чтения элемента из памяти и присваивания).]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На каждом ярусе ярусно-параллельной формы алгоритма будет располагаться конечное число элементарных операций, например, чтение элемента из памяти, сложение или возведение в степень. Информационый граф из п.1.7 изображает свёрнутую ярусно-параллельную форму алгоритма. &lt;br /&gt;
&lt;br /&gt;
Сложность алгоритма будем рассчитывать в предположении, что число вычислительных ядер стремится к бесконечности. Как видно из информационного графа, параллельная сложность вычисления центров кластеров составляет &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;, вычисления коэффициентов принадлежности - &amp;lt;math&amp;gt;O(\log_{2} C^2*|X|)&amp;lt;/math&amp;gt;, а вычисления решающей функции - не больше чем &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом параллельная сложность итерации алгоритма составляет &amp;lt;math&amp;gt;O(\log_{2} C^4*|X|^3)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Так как задачи, решаемые в макроструктуре алгоритма могут быть сведены к задачам вычисления суммы элементов массива и максимального элемента массива, то на &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом ярусе графа будет находиться &amp;lt;math&amp;gt;{N}\over{2^i}&amp;lt;/math&amp;gt; операции, где N - количество элементов массива.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; - набор из &amp;lt;math&amp;gt;|X|&amp;lt;/math&amp;gt; входных векторов длины &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - количество кластеров&lt;br /&gt;
* &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
Объем входных данных: &amp;lt;math&amp;gt;|X|*p+3&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - матрица принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
Объем выходных данных: &amp;lt;math&amp;gt;|X|*C&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Увеличение скорости работы алгоритма при распараллеливании на бесконечном количестве процессоров составляет &amp;lt;math&amp;gt;O({{C^2*|X|}\over{\log_{2} (C^4*|X|^3)}})&amp;lt;/math&amp;gt;. Например, для разбиения 1000 элементов на 10 кластеров производительность параллельного алгоритма будет в 2315 раз больше, а на 20 кластеров - уже в 8477 раз.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
Как видно из предыдущих пунктов, масштабируется данный алгоритм хорошо. С увеличением количества процессоров время работы падает, а с увеличением количества входных данных и количества кластеров - растёт. &lt;br /&gt;
На рисунках показаны результаты запусков алгоритма на разном количестве входных данных и процессоров на массивно-параллельной вычислительной системе Blue Gene/P. Использовался компилятор mpixlcxx без указания специфических опций. Запуски производились в режиме SMP (на каждом ядре 1 MPI процесс из 4 SMP нитей, 2 Гб памяти). Характеристики вычислительного узла: 4 ядерный 32-битный процессор PowerPC 850 Мгц.&lt;br /&gt;
&lt;br /&gt;
Исходных код программы можно найти здесь: https://github.com/demonsmd/superPrak&lt;br /&gt;
[[File:FCMvectors_color2.png|thumb|center|1250px|Рисунок 2. Масштабируемость алгоритма. Зависимость времени работы алгоритма от количества процессоров и входных данных при фиксированном количестве кластеров.]]&lt;br /&gt;
[[File:FCMclusters_color.png|thumb|center|1250px|Рисунок 3. Масштабируемость алгоритма. Зависимость времени работы алгоритма от количества процессоров и кластеров при фиксированном количестве входных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Существует множество реализаций данного алгоритма. Рассмотрим некоторые из них:&lt;br /&gt;
&lt;br /&gt;
- Например, тут: https://habrahabr.ru/post/208496/&lt;br /&gt;
&amp;lt;ref&amp;gt;Нестер А. &amp;quot;Алгоритм нечёткой кластеризации fuzzy c-means на PHP&amp;quot;. [html](https://habrahabr.ru/post/208496/)&amp;lt;/ref&amp;gt;&lt;br /&gt;
приведено краткое описание алгоритма и приведена его реализация на php. В данной статье довольно подробно расписан каждый шаг алгоритма и приведён соответствующий ему фрагмент кода.&lt;br /&gt;
&lt;br /&gt;
- Тут: http://num-meth.srcc.msu.ru/zhurnal/tom_2012/v13r207.html&lt;br /&gt;
&amp;lt;ref&amp;gt;Миниахметов Р.М., Цымблер М.Л. &amp;quot;Интеграция алгоритма кластеризации Fuzzy c-Means в PostgreSQL&amp;quot;. [html](http://num-meth.srcc.msu.ru/zhurnal/tom_2012/v13r207.html)&amp;lt;/ref&amp;gt;&lt;br /&gt;
приводится реализация алгоритма для PostgreSQL, а также прилагается скрипт внедрения алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Demon_smd&amp;diff=19953</id>
		<title>Обсуждение участника:Demon smd</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Demon_smd&amp;diff=19953"/>
		<updated>2016-12-02T20:28:39Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: /* Статья Нечеткий алгоритм С средних */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Статья [[Нечеткий алгоритм С средних]] =&lt;br /&gt;
* не указан вклад каждого автора [[Участник:Coctic|Coctic]] ([[Обсуждение участника:Coctic|обсуждение]]) 12:58, 25 октября 2016 (MSK) - исправлено&lt;br /&gt;
:: Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 13:29, 31 октября 2016 (MSK)&lt;br /&gt;
* п. 1.9 не приведены оценки объема входных и выходных данных [[Участник:Coctic|Coctic]] ([[Обсуждение участника:Coctic|обсуждение]]) 12:58, 25 октября 2016 (MSK) - исправлено&lt;br /&gt;
:: Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 13:29, 31 октября 2016 (MSK)&lt;br /&gt;
* п. 2.4. Не приведена ссылка на текст исследуемой программы [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 18:28, 16 ноября 2016 (MSK)&lt;br /&gt;
** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:32, 28 ноября 2016 (MSK)&lt;br /&gt;
* п. 2.4. Не указана аппаратная платформа, на которой проводилось тестирование [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 18:28, 16 ноября 2016 (MSK)&lt;br /&gt;
** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:32, 28 ноября 2016 (MSK)&lt;br /&gt;
* п. 2.4. На рис. 2 и 3 подпись вертикальной оси накладывается на подписи шкалы  [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 18:28, 16 ноября 2016 (MSK)&lt;br /&gt;
** Исправлено [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:32, 28 ноября 2016 (MSK)&lt;br /&gt;
* п. 2.4. Не приведено никаких сведений о масштабируемости исследуемой программы. На рис. 2 и 3 приведены графики зависимости некоей &amp;quot;сложности&amp;quot; (какя сложность имеется в виду - не указано) от разных параметров. Как из этих графиков извлечь сведения о масштабируемости - не указано. [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 18:28, 16 ноября 2016 (MSK)&lt;br /&gt;
** Исправлено частично. В осях стало время в секундах, в подписях к рисункам по-прежнему непонятная &amp;quot;сложность&amp;quot;. Что в итоге на рисунках - неясно. [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:32, 28 ноября 2016 (MSK)&lt;br /&gt;
* Графики на рис. 2 и 3 плохо читаются [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:32, 28 ноября 2016 (MSK)&lt;br /&gt;
* Увы, так вышло, они с любого ракурса плохо читаемы&lt;br /&gt;
* Необходимо указать характеристики программно-аппаратной платформы (какой компилятор, с какими опциями использовался, какие версии библиотек, на каких узлах проводился запуск и т.д.) [[Участник:Coctic|К. Стефанов]] ([[Обсуждение участника:Coctic|обсуждение]]) 10:32, 28 ноября 2016 (MSK)&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=19226</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=19226"/>
		<updated>2016-11-26T14:21:04Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Нечеткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(C^2*N*D*IterNumber)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(\log_{2}C^4*|X|^3) * IterNumber&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(C^2*|X|)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;|X|*p&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - размерность входных векторов&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;|X|*C &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Assignment}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: &lt;br /&gt;
[[Участник:Demon smd|Д.А.Гуськов]] &lt;br /&gt;
[[Участник:marina abramenkova|М.А.Абраменкова]]&lt;br /&gt;
Во все разделы вклад равноценный.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризуемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних заключается в следующем. Изначально для каждого вектора определяется случайным образом вероятность принадлежности вектора к каждому кластеру. Далее запускается итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) расчёт центров кластеров&lt;br /&gt;
&lt;br /&gt;
2) расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации: если разница этих значений меньше установленного значения, то алгоритм прекращает работу (решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности)&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
J_{m} = \sum_{i = 1}^{N}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty , \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные на каждой итерации ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^{(k)} - u_{i,j}^{(k-1)}|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&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;
В каждой итерации алгоритма происходит 3 основных действия описанных в п. 1.2.1:&lt;br /&gt;
*вычисление центров кластеров&lt;br /&gt;
*вычисление коэффициентов принадлежности&lt;br /&gt;
*вычисление решающей функции&lt;br /&gt;
Подробное описание макроструктур в виде кода приведено в пункте 1.5&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Схему реализации последовательного алгоритма можно описать на C++ следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FCM (X[], C, m, eps){&lt;br /&gt;
    float deside = 0;&lt;br /&gt;
    float newDeside = 0;&lt;br /&gt;
    generateMembershipDegree();            //заполняет uPrev[][] случайными нормрованными коэффициентами&lt;br /&gt;
    while (true){&lt;br /&gt;
        newDeside = deside;&lt;br /&gt;
&lt;br /&gt;
        //вычисление центров кластеров&lt;br /&gt;
        for (int j=0; j&amp;lt;C; j++){           //для каждого кластера&lt;br /&gt;
            float numerator = 0;&lt;br /&gt;
            float denumerator = 0;&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++){        //для каждого вектора&lt;br /&gt;
                numerator+=pow(u[i][j], m) * x[i];&lt;br /&gt;
                denumerator+=pow(u[i][j], m);&lt;br /&gt;
            }&lt;br /&gt;
            c[j] = numerator / denumerator;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //вычисление коэффициентов u[][]&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                sum = 0;&lt;br /&gt;
                for (int k=0; k&amp;lt;C; k++)&lt;br /&gt;
                    sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&lt;br /&gt;
                u[i][j] = 1/sum&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        //определения максимального различия между u[][] и uPrev[][]&lt;br /&gt;
        float max = 0;&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                if (abs(uPrev[i][j]-u[i][j])&amp;gt;max)&lt;br /&gt;
                    max = abs(uPrev[i][j]-u[i][j]);&lt;br /&gt;
&lt;br /&gt;
        if (eps &amp;lt;= max)&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
                for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                    uPrev[i][j]=u[i][j];&lt;br /&gt;
        else&lt;br /&gt;
            break;&lt;br /&gt;
             &lt;br /&gt;
    }&lt;br /&gt;
    return u;&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;
* параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
* набора входных векторов &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
* выбора начальных коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;&lt;br /&gt;
то в данном пункте будет приведена сложность одной итерации относительно количества входных векторов.&lt;br /&gt;
Как видно из предыдущего пункта, для вычисления центров кластеров требуется &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, для определения коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;O(C^2*|X|)&amp;lt;/math&amp;gt; операций, а для вычисления решающей функции - &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, где &amp;lt;math&amp;gt;|X|&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;O(C^2*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Как видно из пункта 1.5, на каждом действии каждой итерации алгоритма все операции, выполняющиеся в цикле, не зависят друг от друга и могут быть распараллелены. Это показано на Рисунке 1.&lt;br /&gt;
&lt;br /&gt;
[[File:FCMIG.png|thumb|center|1200px|Рисунок 1. Информационный граф алгоритма. (1)-(7) - это наборы последовательных действий (например, (2) - последовательные операции деления, взятия адреса и присваивания).]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На каждом ярусе ярусно-параллельной формы алгоритма будет располагаться конечное число элементарных операций, например, взятие адреса, сложение или возведение в степень. Информационый граф из п.1.7 изображает свёрнутую ярусно-параллельную форму алгоритма. &lt;br /&gt;
&lt;br /&gt;
Сложность алгоритма будем рассчитывать в предположении, что число вычислительных ядер стремится к бесконечности. Как видно из информационного графа, параллельная сложность вычисления центров кластеров составляет &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;, вычисления коэффициентов принадлежности - &amp;lt;math&amp;gt;O(\log_{2} C^2*|X|)&amp;lt;/math&amp;gt;, а вычисления решающей функции - не больше чем &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом параллельная сложность итерации алгоритма составляет &amp;lt;math&amp;gt;O(\log_{2} C^4*|X|^3)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Так как задачи, решаемые в макроструктуре алгоритма могут быть сведены к задачам вычисления суммы элементов массива и максимального элемента массива, то на &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом ярусе графа будет находиться &amp;lt;math&amp;gt;{N}\over{2^i}&amp;lt;/math&amp;gt; операции, где N - количество элементов массива.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; - набор из &amp;lt;math&amp;gt;|X|&amp;lt;/math&amp;gt; входных векторов длины &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - количество кластеров&lt;br /&gt;
* &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
Объем входных данных: &amp;lt;math&amp;gt;|X|*p+3&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - матрица принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
Объем выходных данных: &amp;lt;math&amp;gt;|X|*C&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Увеличение скорости работы алгоритма при распараллеливании на бесконечном количестве процессоров составляет &amp;lt;math&amp;gt;O({{C^2*|X|}\over{\log_{2} (C^4*|X|^3)}})&amp;lt;/math&amp;gt;. Например, для разбиения 1000 элементов на 10 кластеров производительность параллельного алгоритма будет в 2315 раз больше, а на 20 кластеров - уже в 8477 раз.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
Как видно из предыдущих пунктов, масштабируется данный алгоритм хорошо. С увеличением количества процессоров время работы падает, а с увеличением количества входных данных и количества кластеров - растёт. На рисунках показаны результаты запусков алгоритма на разном количестве входных данных и процессоров на Blue Gene/P. Исходных код программы можно найти здесь: https://github.com/demonsmd/superPrak&lt;br /&gt;
[[File:FCMvectors.png|thumb|center|1500px|Рисунок 2. Масштабируемость алгоритма. Зависимость сложности алгоритма от количества процессоров и входных данных при фиксированном количестве кластеров.]]&lt;br /&gt;
[[File:FCMclusters.png|thumb|center|1500px|Рисунок 3. Масштабируемость алгоритма. Зависимость сложности алгоритма от количества процессоров и кластеров при фиксированном количестве входных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Существует множество реализаций данного алгоритма. Рассмотрим некоторые из них:&lt;br /&gt;
&lt;br /&gt;
- Например, тут: https://habrahabr.ru/post/208496/&lt;br /&gt;
&amp;lt;ref&amp;gt;Нестер А. &amp;quot;Алгоритм нечёткой кластеризации fuzzy c-means на PHP&amp;quot;. [html](https://habrahabr.ru/post/208496/)&amp;lt;/ref&amp;gt;&lt;br /&gt;
приведено краткое описание алгоритма и приведена его реализация на php. В данной статье довольно подробно расписан каждый шаг алгоритма и приведён соответствующий ему фрагмент кода.&lt;br /&gt;
&lt;br /&gt;
- Тут: http://num-meth.srcc.msu.ru/zhurnal/tom_2012/v13r207.html&lt;br /&gt;
&amp;lt;ref&amp;gt;Миниахметов Р.М., Цымблер М.Л. &amp;quot;Интеграция алгоритма кластеризации Fuzzy c-Means в PostgreSQL&amp;quot;. [html](http://num-meth.srcc.msu.ru/zhurnal/tom_2012/v13r207.html)&amp;lt;/ref&amp;gt;&lt;br /&gt;
приводится реализация алгоритма для PostgreSQL, а также прилагается скрипт внедрения алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=19225</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=19225"/>
		<updated>2016-11-26T14:08:44Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Нечеткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(C^2*N*D*IterNumber)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(\log_{2}C^4*|X|^3) * IterNumber&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(C^2*|X|)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;|X|*p&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - размерность входных векторов&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;|X|*C &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: &lt;br /&gt;
[[Участник:Demon smd|Д.А.Гуськов]] &lt;br /&gt;
[[Участник:marina abramenkova|М.А.Абраменкова]]&lt;br /&gt;
Во все разделы вклад равноценный.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризуемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних заключается в следующем. Изначально для каждого вектора определяется случайным образом вероятность принадлежности вектора к каждому кластеру. Далее запускается итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) расчёт центров кластеров&lt;br /&gt;
&lt;br /&gt;
2) расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации: если разница этих значений меньше установленного значения, то алгоритм прекращает работу (решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности)&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
J_{m} = \sum_{i = 1}^{N}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty , \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные на каждой итерации ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^{(k)} - u_{i,j}^{(k-1)}|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&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;
В каждой итерации алгоритма происходит 3 основных действия описанных в п. 1.2.1:&lt;br /&gt;
*вычисление центров кластеров&lt;br /&gt;
*вычисление коэффициентов принадлежности&lt;br /&gt;
*вычисление решающей функции&lt;br /&gt;
Подробное описание макроструктур в виде кода приведено в пункте 1.5&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Схему реализации последовательного алгоритма можно описать на C++ следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FCM (X[], C, m, eps){&lt;br /&gt;
    float deside = 0;&lt;br /&gt;
    float newDeside = 0;&lt;br /&gt;
    generateMembershipDegree();            //заполняет uPrev[][] случайными нормрованными коэффициентами&lt;br /&gt;
    while (true){&lt;br /&gt;
        newDeside = deside;&lt;br /&gt;
&lt;br /&gt;
        //вычисление центров кластеров&lt;br /&gt;
        for (int j=0; j&amp;lt;C; j++){           //для каждого кластера&lt;br /&gt;
            float numerator = 0;&lt;br /&gt;
            float denumerator = 0;&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++){        //для каждого вектора&lt;br /&gt;
                numerator+=pow(u[i][j], m) * x[i];&lt;br /&gt;
                denumerator+=pow(u[i][j], m);&lt;br /&gt;
            }&lt;br /&gt;
            c[j] = numerator / denumerator;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //вычисление коэффициентов u[][]&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                sum = 0;&lt;br /&gt;
                for (int k=0; k&amp;lt;C; k++)&lt;br /&gt;
                    sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&lt;br /&gt;
                u[i][j] = 1/sum&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        //определения максимального различия между u[][] и uPrev[][]&lt;br /&gt;
        float max = 0;&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                if (abs(uPrev[i][j]-u[i][j])&amp;gt;max)&lt;br /&gt;
                    max = abs(uPrev[i][j]-u[i][j]);&lt;br /&gt;
&lt;br /&gt;
        if (eps &amp;lt;= max)&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
                for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                    uPrev[i][j]=u[i][j];&lt;br /&gt;
        else&lt;br /&gt;
            break;&lt;br /&gt;
             &lt;br /&gt;
    }&lt;br /&gt;
    return u;&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;
* параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
* набора входных векторов &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
* выбора начальных коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;&lt;br /&gt;
то в данном пункте будет приведена сложность одной итерации относительно количества входных векторов.&lt;br /&gt;
Как видно из предыдущего пункта, для вычисления центров кластеров требуется &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, для определения коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;O(C^2*|X|)&amp;lt;/math&amp;gt; операций, а для вычисления решающей функции - &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, где &amp;lt;math&amp;gt;|X|&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;O(C^2*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Как видно из пункта 1.5, на каждом действии каждой итерации алгоритма все операции, выполняющиеся в цикле, не зависят друг от друга и могут быть распараллелены. Это показано на Рисунке 1.&lt;br /&gt;
&lt;br /&gt;
[[File:FCMIG.png|thumb|center|1200px|Рисунок 1. Информационный граф алгоритма. (1)-(7) - это наборы последовательных действий (например, (2) - последовательные операции деления, взятия адреса и присваивания).]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На каждом ярусе ярусно-параллельной формы алгоритма будет располагаться конечное число элементарных операций, например, взятие адреса, сложение или возведение в степень. Информационый граф из п.1.7 изображает свёрнутую ярусно-параллельную форму алгоритма. &lt;br /&gt;
&lt;br /&gt;
Сложность алгоритма будем рассчитывать в предположении, что число вычислительных ядер стремится к бесконечности. Как видно из информационного графа, параллельная сложность вычисления центров кластеров составляет &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;, вычисления коэффициентов принадлежности - &amp;lt;math&amp;gt;O(\log_{2} C^2*|X|)&amp;lt;/math&amp;gt;, а вычисления решающей функции - не больше чем &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом параллельная сложность итерации алгоритма составляет &amp;lt;math&amp;gt;O(\log_{2} C^4*|X|^3)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Так как задачи, решаемые в макроструктуре алгоритма могут быть сведены к задачам вычисления суммы элементов массива и максимального элемента массива, то на &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом ярусе графа будет находиться &amp;lt;math&amp;gt;{N}\over{2^i}&amp;lt;/math&amp;gt; операции, где N - количество элементов массива.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; - набор из &amp;lt;math&amp;gt;|X|&amp;lt;/math&amp;gt; входных векторов длины &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - количество кластеров&lt;br /&gt;
* &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
Объем входных данных: &amp;lt;math&amp;gt;|X|*p+3&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - матрица принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
Объем выходных данных: &amp;lt;math&amp;gt;|X|*C&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Увеличение скорости работы алгоритма при распараллеливании на бесконечном количестве процессоров составляет &amp;lt;math&amp;gt;O({{C^2*|X|}\over{\log_{2} (C^4*|X|^3)}})&amp;lt;/math&amp;gt;. Например, для разбиения 1000 элементов на 10 кластеров производительность параллельного алгоритма будет в 2315 раз больше, а на 20 кластеров - уже в 8477 раз.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
Как видно из предыдущих пунктов, масштабируется данный алгоритм хорошо. С увеличением количества процессоров время работы падает, а с увеличением количества входных данных и количества кластеров - растёт. На рисунках показаны результаты запусков алгоритма на разном количестве входных данных и процессоров на Blue Gene/P. Исходных код программы можно найти здесь: https://github.com/demonsmd/superPrak&lt;br /&gt;
[[File:FCMvectors.png|thumb|center|1500px|Рисунок 2. Масштабируемость алгоритма. Зависимость сложности алгоритма от количества процессоров и входных данных при фиксированном количестве кластеров.]]&lt;br /&gt;
[[File:FCMclusters.png|thumb|center|1500px|Рисунок 3. Масштабируемость алгоритма. Зависимость сложности алгоритма от количества процессоров и кластеров при фиксированном количестве входных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Существует множество реализаций данного алгоритма. Рассмотрим некоторые из них:&lt;br /&gt;
&lt;br /&gt;
- Например, тут: https://habrahabr.ru/post/208496/&lt;br /&gt;
&amp;lt;ref&amp;gt;Нестер А. &amp;quot;Алгоритм нечёткой кластеризации fuzzy c-means на PHP&amp;quot;. [html](https://habrahabr.ru/post/208496/)&amp;lt;/ref&amp;gt;&lt;br /&gt;
приведено краткое описание алгоритма и приведена его реализация на php. В данной статье довольно подробно расписан каждый шаг алгоритма и приведён соответствующий ему фрагмент кода.&lt;br /&gt;
&lt;br /&gt;
- Тут: http://num-meth.srcc.msu.ru/zhurnal/tom_2012/v13r207.html&lt;br /&gt;
&amp;lt;ref&amp;gt;Миниахметов Р.М., Цымблер М.Л. &amp;quot;Интеграция алгоритма кластеризации Fuzzy c-Means в PostgreSQL&amp;quot;. [html](http://num-meth.srcc.msu.ru/zhurnal/tom_2012/v13r207.html)&amp;lt;/ref&amp;gt;&lt;br /&gt;
приводится реализация алгоритма для PostgreSQL, а также прилагается скрипт внедрения алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=19224</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=19224"/>
		<updated>2016-11-26T12:48:37Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Нечеткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(C^2*N*D*IterNumber)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(\log_{2}C^4*|X|^3) * IterNumber&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(C^2*|X|)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;|X|*p&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - размерность входных векторов&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;|X|*C &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: &lt;br /&gt;
[[Участник:Demon smd|Д.А.Гуськов]] &lt;br /&gt;
[[Участник:marina abramenkova|М.А.Абраменкова]]&lt;br /&gt;
Во все разделы вклад равноценный.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризуемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних заключается в следующем. Изначально для каждого вектора определяется случайным образом вероятность принадлежности вектора к каждому кластеру. Далее запускается итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) расчёт центров кластеров&lt;br /&gt;
&lt;br /&gt;
2) расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации: если разница этих значений меньше установленного значения, то алгоритм прекращает работу (решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности)&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
J_{m} = \sum_{i = 1}^{N}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty , \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные на каждой итерации ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^{(k)} - u_{i,j}^{(k-1)}|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&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;
В каждой итерации алгоритма происходит 3 основных действия описанных в п. 1.2.1:&lt;br /&gt;
*вычисление центров кластеров&lt;br /&gt;
*вычисление коэффициентов принадлежности&lt;br /&gt;
*вычисление решающей функции&lt;br /&gt;
Подробное описание макроструктур в виде кода приведено в пункте 1.5&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Схему реализации последовательного алгоритма можно описать на C++ следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FCM (X[], C, m, eps){&lt;br /&gt;
    float deside = 0;&lt;br /&gt;
    float newDeside = 0;&lt;br /&gt;
    generateMembershipDegree();            //заполняет uPrev[][] случайными нормрованными коэффициентами&lt;br /&gt;
    while (true){&lt;br /&gt;
        newDeside = deside;&lt;br /&gt;
&lt;br /&gt;
        //вычисление центров кластеров&lt;br /&gt;
        for (int j=0; j&amp;lt;C; j++){           //для каждого кластера&lt;br /&gt;
            float numerator = 0;&lt;br /&gt;
            float denumerator = 0;&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++){        //для каждого вектора&lt;br /&gt;
                numerator+=pow(u[i][j], m) * x[i];&lt;br /&gt;
                denumerator+=pow(u[i][j], m);&lt;br /&gt;
            }&lt;br /&gt;
            c[j] = numerator / denumerator;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //вычисление коэффициентов u[][]&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                sum = 0;&lt;br /&gt;
                for (int k=0; k&amp;lt;C; k++)&lt;br /&gt;
                    sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&lt;br /&gt;
                u[i][j] = 1/sum&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        //определения максимального различия между u[][] и uPrev[][]&lt;br /&gt;
        float max = 0;&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                if (abs(uPrev[i][j]-u[i][j])&amp;gt;max)&lt;br /&gt;
                    max = abs(uPrev[i][j]-u[i][j]);&lt;br /&gt;
&lt;br /&gt;
        if (eps &amp;lt;= max)&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
                for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                    uPrev[i][j]=u[i][j];&lt;br /&gt;
        else&lt;br /&gt;
            break;&lt;br /&gt;
             &lt;br /&gt;
    }&lt;br /&gt;
    return u;&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;
* параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
* набора входных векторов &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
* выбора начальных коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;&lt;br /&gt;
то в данном пункте будет приведена сложность одной итерации относительно количества входных векторов.&lt;br /&gt;
Как видно из предыдущего пункта, для вычисления центров кластеров требуется &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, для определения коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;O(C^2*|X|)&amp;lt;/math&amp;gt; операций, а для вычисления решающей функции - &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, где &amp;lt;math&amp;gt;|X|&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;O(C^2*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Как видно из пункта 1.5, на каждом действии каждой итерации алгоритма все операции, выполняющиеся в цикле, не зависят друг от друга и могут быть распараллелены. Это показано на Рисунке 1.&lt;br /&gt;
&lt;br /&gt;
[[File:FCMIG.png|thumb|center|1200px|Рисунок 1. Информационный граф алгоритма. (1)-(7) - это наборы последовательных действий (например, (2) - последовательные операции деления, взятия адреса и присваивания).]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На каждом ярусе ярусно-параллельной формы алгоритма будет располагаться конечное число элементарных операций, например, взятие адреса, сложение или возведение в степень. Информационый граф из п.1.7 изображает свёрнутую ярусно-параллельную форму алгоритма. &lt;br /&gt;
&lt;br /&gt;
Сложность алгоритма будем рассчитывать в предположении, что число вычислительных ядер стремится к бесконечности. Как видно из информационного графа, параллельная сложность вычисления центров кластеров составляет &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;, вычисления коэффициентов принадлежности - &amp;lt;math&amp;gt;O(\log_{2} C^2*|X|)&amp;lt;/math&amp;gt;, а вычисления решающей функции - не больше чем &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом параллельная сложность итерации алгоритма составляет &amp;lt;math&amp;gt;O(\log_{2} C^4*|X|^3)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Так как задачи, решаемые в макроструктуре алгоритма могут быть сведены к задачам вычисления суммы элементов массива и максимального элемента массива, то на &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом ярусе графа будет находиться &amp;lt;math&amp;gt;{N}\over{2^i}&amp;lt;/math&amp;gt; операции, где N - количество элементов массива.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; - набор из &amp;lt;math&amp;gt;|X|&amp;lt;/math&amp;gt; входных векторов длины &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - количество кластеров&lt;br /&gt;
* &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
Объем входных данных: &amp;lt;math&amp;gt;|X|*p+3&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - матрица принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
Объем выходных данных: &amp;lt;math&amp;gt;|X|*C&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Увеличение скорости работы алгоритма при распараллеливании на бесконечном количестве процессоров составляет &amp;lt;math&amp;gt;O({{C^2*|X|}\over{\log_{2} (C^4*|X|^3)}})&amp;lt;/math&amp;gt;. Например, для разбиения 1000 элементов на 10 кластеров производительность параллельного алгоритма будет в 2315 раз больше, а на 20 кластеров - уже в 8477 раз.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
Как видно из предыдущих пунктов, масштабируется данный алгоритм хорошо. С увеличением количества процессоров время работы падает, а с увеличением количества входных данных и количества кластеров - растёт. На рисунках показаны результаты запусков алгоритма на разном количестве входных данных и процессоров на Blue Gene/P. Исходных код программы можно найти здесь: https://github.com/demonsmd/superPrak&lt;br /&gt;
[[File:FCMCOMP1.jpg|thumb|center|1500px|Рисунок 2. Масштабируемость алгоритма. Зависимость сложности алгоритма от количества процессоров и входных данных при фиксированном количестве кластеров.]]&lt;br /&gt;
[[File:FCMCOMP2.jpg|thumb|center|1500px|Рисунок 3. Масштабируемость алгоритма. Зависимость сложности алгоритма от количества процессоров и кластеров при фиксированном количестве входных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Существует множество реализаций данного алгоритма. Рассмотрим некоторые из них:&lt;br /&gt;
&lt;br /&gt;
- Например, тут: https://habrahabr.ru/post/208496/&lt;br /&gt;
&amp;lt;ref&amp;gt;Нестер А. &amp;quot;Алгоритм нечёткой кластеризации fuzzy c-means на PHP&amp;quot;. [html](https://habrahabr.ru/post/208496/)&amp;lt;/ref&amp;gt;&lt;br /&gt;
приведено краткое описание алгоритма и приведена его реализация на php. В данной статье довольно подробно расписан каждый шаг алгоритма и приведён соответствующий ему фрагмент кода.&lt;br /&gt;
&lt;br /&gt;
- Тут: http://num-meth.srcc.msu.ru/zhurnal/tom_2012/v13r207.html&lt;br /&gt;
&amp;lt;ref&amp;gt;Миниахметов Р.М., Цымблер М.Л. &amp;quot;Интеграция алгоритма кластеризации Fuzzy c-Means в PostgreSQL&amp;quot;. [html](http://num-meth.srcc.msu.ru/zhurnal/tom_2012/v13r207.html)&amp;lt;/ref&amp;gt;&lt;br /&gt;
приводится реализация алгоритма для PostgreSQL, а также прилагается скрипт внедрения алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=19223</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=19223"/>
		<updated>2016-11-26T12:47:39Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Нечеткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(C^2*N*D*IterNumber)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(\log_{2}C^4*|X|^3) * IterNumber&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(C^2*|X|)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;|X|*p&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - размерность входных векторов&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;|X|*C &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: &lt;br /&gt;
[[Участник:Demon smd|Д.А.Гуськов]] &lt;br /&gt;
[[Участник:marina abramenkova|М.А.Абраменкова]]&lt;br /&gt;
Во все разделы вклад равноценный.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризуемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних заключается в следующем. Изначально для каждого вектора определяется случайным образом вероятность принадлежности вектора к каждому кластеру. Далее запускается итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) расчёт центров кластеров&lt;br /&gt;
&lt;br /&gt;
2) расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации: если разница этих значений меньше установленного значения, то алгоритм прекращает работу (решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности)&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
J_{m} = \sum_{i = 1}^{N}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty , \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные на каждой итерации ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^{(k)} - u_{i,j}^{(k-1)}|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&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;
В каждой итерации алгоритма происходит 3 основных действия описанных в п. 1.2.1:&lt;br /&gt;
*вычисление центров кластеров&lt;br /&gt;
*вычисление коэффициентов принадлежности&lt;br /&gt;
*вычисление решающей функции&lt;br /&gt;
Подробное описание макроструктур в виде кода приведено в пункте 1.5&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Схему реализации последовательного алгоритма можно описать на C++ следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FCM (X[], C, m, eps){&lt;br /&gt;
    float deside = 0;&lt;br /&gt;
    float newDeside = 0;&lt;br /&gt;
    generateMembershipDegree();            //заполняет uPrev[][] случайными нормрованными коэффициентами&lt;br /&gt;
    while (true){&lt;br /&gt;
        newDeside = deside;&lt;br /&gt;
&lt;br /&gt;
        //вычисление центров кластеров&lt;br /&gt;
        for (int j=0; j&amp;lt;C; j++){           //для каждого кластера&lt;br /&gt;
            float numerator = 0;&lt;br /&gt;
            float denumerator = 0;&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++){        //для каждого вектора&lt;br /&gt;
                numerator+=pow(u[i][j], m) * x[i];&lt;br /&gt;
                denumerator+=pow(u[i][j], m);&lt;br /&gt;
            }&lt;br /&gt;
            c[j] = numerator / denumerator;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //вычисление коэффициентов u[][]&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                sum = 0;&lt;br /&gt;
                for (int k=0; k&amp;lt;C; k++)&lt;br /&gt;
                    sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&lt;br /&gt;
                u[i][j] = 1/sum&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        //определения максимального различия между u[][] и uPrev[][]&lt;br /&gt;
        float max = 0;&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                if (abs(uPrev[i][j]-u[i][j])&amp;gt;max)&lt;br /&gt;
                    max = abs(uPrev[i][j]-u[i][j]);&lt;br /&gt;
&lt;br /&gt;
        if (eps &amp;lt;= max)&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
                for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                    uPrev[i][j]=u[i][j];&lt;br /&gt;
        else&lt;br /&gt;
            break;&lt;br /&gt;
             &lt;br /&gt;
    }&lt;br /&gt;
    return u;&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;
* параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
* набора входных векторов &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
* выбора начальных коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;&lt;br /&gt;
то в данном пункте будет приведена сложность одной итерации относительно количества входных векторов.&lt;br /&gt;
Как видно из предыдущего пункта, для вычисления центров кластеров требуется &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, для определения коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;O(C^2*|X|)&amp;lt;/math&amp;gt; операций, а для вычисления решающей функции - &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, где &amp;lt;math&amp;gt;|X|&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;O(C^2*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Как видно из пункта 1.5, на каждом действии каждой итерации алгоритма все операции, выполняющиеся в цикле, не зависят друг от друга и могут быть распараллелены. Это показано на Рисунке 1.&lt;br /&gt;
&lt;br /&gt;
[[File:FCMIG.png|thumb|center|1200px|Рисунок 1. Информационный граф алгоритма. (1)-(7) - это наборы последовательных действий (например, (2) - последовательные операции деления, взятия адреса и присваивания).]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На каждом ярусе ярусно-параллельной формы алгоритма будет располагаться конечное число элементарных операций, например, взятие адреса, сложение или возведение в степень. Информационый граф из п.1.7 изображает свёрнутую ярусно-параллельную форму алгоритма. &lt;br /&gt;
&lt;br /&gt;
Сложность алгоритма будем рассчитывать в предположении, что число вычислительных ядер стремится к бесконечности. Как видно из информационного графа, параллельная сложность вычисления центров кластеров составляет &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;, вычисления коэффициентов принадлежности - &amp;lt;math&amp;gt;O(\log_{2} C^2*|X|)&amp;lt;/math&amp;gt;, а вычисления решающей функции - не больше чем &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом параллельная сложность итерации алгоритма составляет &amp;lt;math&amp;gt;O(\log_{2} C^4*|X|^3)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Так как задачи, решаемые в макроструктуре алгоритма могут быть сведены к задачам вычисления суммы элементов массива и максимального элемента массива, то на &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом ярусе графа будет находиться &amp;lt;math&amp;gt;{N}\over{2^i}&amp;lt;/math&amp;gt; операции, где N - количество элементов массива.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; - набор из &amp;lt;math&amp;gt;|X|&amp;lt;/math&amp;gt; входных векторов длины &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - количество кластеров&lt;br /&gt;
* &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
Объем входных данных: &amp;lt;math&amp;gt;|X|*p+3&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - матрица принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
Объем выходных данных: &amp;lt;math&amp;gt;|X|*C&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Увеличение скорости работы алгоритма при распараллеливании на бесконечном количестве процессоров составляет &amp;lt;math&amp;gt;O({{C^2*|X|}\over{\log_{2} (C^4*|X|^3)}})&amp;lt;/math&amp;gt;. Например, для разбиения 1000 элементов на 10 кластеров производительность параллельного алгоритма будет в 2315 раз больше, а на 20 кластеров - уже в 8477 раз.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
Как видно из предыдущих пунктов, масштабируется данный алгоритм хорошо. С увеличением количества процессоров время работы падает, а с увеличением количества входных данных и количества кластеров - растёт. На рисунках показаны результаты запусков алгоритма на разном количестве входных данных и процессоров. Исходных код программы можно найти здесь: https://github.com/demonsmd/superPrak&lt;br /&gt;
[[File:FCMCOMP1.jpg|thumb|center|1500px|Рисунок 2. Масштабируемость алгоритма. Зависимость сложности алгоритма от количества процессоров и входных данных при фиксированном количестве кластеров.]]&lt;br /&gt;
[[File:FCMCOMP2.jpg|thumb|center|1500px|Рисунок 3. Масштабируемость алгоритма. Зависимость сложности алгоритма от количества процессоров и кластеров при фиксированном количестве входных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Существует множество реализаций данного алгоритма. Рассмотрим некоторые из них:&lt;br /&gt;
&lt;br /&gt;
- Например, тут: https://habrahabr.ru/post/208496/&lt;br /&gt;
&amp;lt;ref&amp;gt;Нестер А. &amp;quot;Алгоритм нечёткой кластеризации fuzzy c-means на PHP&amp;quot;. [html](https://habrahabr.ru/post/208496/)&amp;lt;/ref&amp;gt;&lt;br /&gt;
приведено краткое описание алгоритма и приведена его реализация на php. В данной статье довольно подробно расписан каждый шаг алгоритма и приведён соответствующий ему фрагмент кода.&lt;br /&gt;
&lt;br /&gt;
- Тут: http://num-meth.srcc.msu.ru/zhurnal/tom_2012/v13r207.html&lt;br /&gt;
&amp;lt;ref&amp;gt;Миниахметов Р.М., Цымблер М.Л. &amp;quot;Интеграция алгоритма кластеризации Fuzzy c-Means в PostgreSQL&amp;quot;. [html](http://num-meth.srcc.msu.ru/zhurnal/tom_2012/v13r207.html)&amp;lt;/ref&amp;gt;&lt;br /&gt;
приводится реализация алгоритма для PostgreSQL, а также прилагается скрипт внедрения алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=14659</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=14659"/>
		<updated>2016-10-29T09:23:32Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Нечеткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(C^2*N*D*IterNumber)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(\log_{2}C^4*|X|^3) * IterNumber&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(C^2*|X|)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;|X|*p&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - размерность входных векторов&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;|X|*C &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: &lt;br /&gt;
[[Участник:Demon smd|Д.А.Гуськов]] &lt;br /&gt;
[[Участник:marina abramenkova|М.А.Абраменкова]]&lt;br /&gt;
Во все разделы вклад равноценный.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризуемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних заключается в следующем. Изначально для каждого вектора определяется случайным образом вероятность принадлежности вектора к каждому кластеру. Далее запускается итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) расчёт центров кластеров&lt;br /&gt;
&lt;br /&gt;
2) расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации: если разница этих значений меньше установленного значения, то алгоритм прекращает работу (решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности)&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
J_{m} = \sum_{i = 1}^{N}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty , \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные на каждой итерации ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^{(k)} - u_{i,j}^{(k-1)}|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&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;
В каждой итерации алгоритма происходит 3 основных действия описанных в п. 1.2.1:&lt;br /&gt;
*вычисление центров кластеров&lt;br /&gt;
*вычисление коэффициентов принадлежности&lt;br /&gt;
*вычисление решающей функции&lt;br /&gt;
Подробное описание макроструктур в виде кода приведено в пункте 1.5&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Схему реализации последовательного алгоритма можно описать на C++ следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FCM (X[], C, m, eps){&lt;br /&gt;
    float deside = 0;&lt;br /&gt;
    float newDeside = 0;&lt;br /&gt;
    generateMembershipDegree();            //заполняет uPrev[][] случайными нормрованными коэффициентами&lt;br /&gt;
    while (true){&lt;br /&gt;
        newDeside = deside;&lt;br /&gt;
&lt;br /&gt;
        //вычисление центров кластеров&lt;br /&gt;
        for (int j=0; j&amp;lt;C; j++){           //для каждого кластера&lt;br /&gt;
            float numerator = 0;&lt;br /&gt;
            float denumerator = 0;&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++){        //для каждого вектора&lt;br /&gt;
                numerator+=pow(u[i][j], m) * x[i];&lt;br /&gt;
                denumerator+=pow(u[i][j], m);&lt;br /&gt;
            }&lt;br /&gt;
            c[j] = numerator / denumerator;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //вычисление коэффициентов u[][]&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                sum = 0;&lt;br /&gt;
                for (int k=0; k&amp;lt;C; k++)&lt;br /&gt;
                    sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&lt;br /&gt;
                u[i][j] = 1/sum&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        //определения максимального различия между u[][] и uPrev[][]&lt;br /&gt;
        float max = 0;&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                if (abs(uPrev[i][j]-u[i][j])&amp;gt;max)&lt;br /&gt;
                    max = abs(uPrev[i][j]-u[i][j]);&lt;br /&gt;
&lt;br /&gt;
        if (eps &amp;lt;= max)&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
                for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                    uPrev[i][j]=u[i][j];&lt;br /&gt;
        else&lt;br /&gt;
            break;&lt;br /&gt;
             &lt;br /&gt;
    }&lt;br /&gt;
    return u;&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;
* параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
* набора входных векторов &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
* выбора начальных коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;&lt;br /&gt;
то в данном пункте будет приведена сложность одной итерации относительно количества входных векторов.&lt;br /&gt;
Как видно из предыдущего пункта, для вычисления центров кластеров требуется &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, для определения коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;O(C^2*|X|)&amp;lt;/math&amp;gt; операций, а для вычисления решающей функции - &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, где &amp;lt;math&amp;gt;|X|&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;O(C^2*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Как видно из пункта 1.5, на каждом действии каждой итерации алгоритма все операции, выполняющиеся в цикле, не зависят друг от друга и могут быть распаралелены. Это показано на Рисунке 1.&lt;br /&gt;
&lt;br /&gt;
[[File:FCMIG.png|thumb|center|1200px|Рисунок 1. Информационный граф алгоритма. (1)-(7) - это наборы последовательных действий (например, (2) - последовательные операции деления, взятия адреса и присваивания).]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На каждом ярусе ярусно-параллельной формы алгоритма будет располагаться конечное число элементарных операций, например, взятие адреса, сложение или возведение в степень. Информационый граф из п.1.7 изображает свёрнутую ярусно-параллельную форму алгоритма. &lt;br /&gt;
&lt;br /&gt;
Сложность алгоритма будем рассчитывать в предположении, что число вычислительных ядер стремится к бесконечности. Как видно из информационного графа, параллельная сложность вычисления центров кластеров составляет &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;, вычисления коэффициентов принадлежности - &amp;lt;math&amp;gt;O(\log_{2} C^2*|X|)&amp;lt;/math&amp;gt;, а вычисления решающей функции - не больше чем &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом параллельная сложность итерации алгоритма составляет &amp;lt;math&amp;gt;O(\log_{2} C^4*|X|^3)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Так как задачи, решаемые в макроструктуре алгоритма могут быть сведены к задачам вычисления суммы элементов массива и максимального элемента массива, то на &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом ярусе графа будет находиться &amp;lt;math&amp;gt;{N}\over{2^i}&amp;lt;/math&amp;gt; операции, где N - количество элементов массива.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; - набор из &amp;lt;math&amp;gt;|X|&amp;lt;/math&amp;gt; входных векторов длины &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - количество кластеров&lt;br /&gt;
* &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
Объем входных данных: &amp;lt;math&amp;gt;kp&amp;lt;/math&amp;gt; (не считая трех коэффициентов)&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - матрица принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
Объем выходных данных: &amp;lt;math&amp;gt;kC&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Увеличение скорости работы алгоритма при распараллеливании на бесконечном количестве процессоров составляет &amp;lt;math&amp;gt;O({{C^2*|X|}\over{\log_{2} (C^4*|X|^3)}})&amp;lt;/math&amp;gt;. Например, для разбиения 1000 элементов на 10 кластеров производительность параллельного алгоритма будет в 2315 раз больше, а на 20 кластеров - уже в 8477 раз.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
Как видно из предыдущих пунктов, масштабируется данный алгоритм хорошо. С увеличением количества процессоров время работы падает, а с увеличением количества входных данных и количества кластеров - растёт. На рисунках показана масштабируемость алгоритма.&lt;br /&gt;
[[File:FCMCOMP1.jpg|thumb|center|1500px|Рисунок 2. Масштабируемость алгоритма. Зависимость сложности алгоритма от количества процессоров и входных данных при фиксированном количестве кластеров.]]&lt;br /&gt;
[[File:FCMCOMP2.jpg|thumb|center|1500px|Рисунок 3. Масштабируемость алгоритма. Зависимость сложности алгоритма от количества процессоров и кластеров при фиксированном количестве входных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Существует множество реализаций данного алгоритма. Рассмотрим некоторые из них:&lt;br /&gt;
&lt;br /&gt;
- Например, тут: https://habrahabr.ru/post/208496/&lt;br /&gt;
&amp;lt;ref&amp;gt;Нестер А. &amp;quot;Алгоритм нечёткой кластеризации fuzzy c-means на PHP&amp;quot;. [html](https://habrahabr.ru/post/208496/)&amp;lt;/ref&amp;gt;&lt;br /&gt;
приведено краткое описание алгоритма и приведена его реализация на php. В данной статье довольно подробно расписан каждый шаг алгоритма и приведён соответствующий ему фрагмент кода.&lt;br /&gt;
&lt;br /&gt;
- Тут: http://num-meth.srcc.msu.ru/zhurnal/tom_2012/v13r207.html&lt;br /&gt;
&amp;lt;ref&amp;gt;Миниахметов Р.М., Цымблер М.Л. &amp;quot;Интеграция алгоритма кластеризации Fuzzy c-Means в PostgreSQL&amp;quot;. [html](http://num-meth.srcc.msu.ru/zhurnal/tom_2012/v13r207.html)&amp;lt;/ref&amp;gt;&lt;br /&gt;
приводится реализация алгоритма для PostgreSQL, а также прилагается скрипт внедрения алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=14656</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=14656"/>
		<updated>2016-10-29T09:19:45Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: /* Входные и выходные данные алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Нечеткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(C^2*N*D*IterNumber)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(\log_{2}C^4*|X|^3) * IterNumber&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(C^2*|X|)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;|X|*C &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;|X|*C &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: &lt;br /&gt;
[[Участник:Demon smd|Д.А.Гуськов]](Информационный граф) &lt;br /&gt;
[[Участник:marina abramenkova|М.А.Абраменкова]](Схема реализации последовательного алгоритма) &lt;br /&gt;
В остальные разделы вклад равноценный.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризуемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних заключается в следующем. Изначально для каждого вектора определяется случайным образом вероятность принадлежности вектора к каждому кластеру. Далее запускается итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) расчёт центров кластеров&lt;br /&gt;
&lt;br /&gt;
2) расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации: если разница этих значений меньше установленного значения, то алгоритм прекращает работу (решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности)&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
J_{m} = \sum_{i = 1}^{N}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty , \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные на каждой итерации ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^{(k)} - u_{i,j}^{(k-1)}|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&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;
В каждой итерации алгоритма происходит 3 основных действия описанных в п. 1.2.1:&lt;br /&gt;
*вычисление центров кластеров&lt;br /&gt;
*вычисление коэффициентов принадлежности&lt;br /&gt;
*вычисление решающей функции&lt;br /&gt;
Подробное описание макроструктур в виде кода приведено в пункте 1.5&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Схему реализации последовательного алгоритма можно описать на C++ следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FCM (X[], C, m, eps){&lt;br /&gt;
    float deside = 0;&lt;br /&gt;
    float newDeside = 0;&lt;br /&gt;
    generateMembershipDegree();            //заполняет uPrev[][] случайными нормрованными коэффициентами&lt;br /&gt;
    while (true){&lt;br /&gt;
        newDeside = deside;&lt;br /&gt;
&lt;br /&gt;
        //вычисление центров кластеров&lt;br /&gt;
        for (int j=0; j&amp;lt;C; j++){           //для каждого кластера&lt;br /&gt;
            float numerator = 0;&lt;br /&gt;
            float denumerator = 0;&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++){        //для каждого вектора&lt;br /&gt;
                numerator+=pow(u[i][j], m) * x[i];&lt;br /&gt;
                denumerator+=pow(u[i][j], m);&lt;br /&gt;
            }&lt;br /&gt;
            c[j] = numerator / denumerator;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //вычисление коэффициентов u[][]&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                sum = 0;&lt;br /&gt;
                for (int k=0; k&amp;lt;C; k++)&lt;br /&gt;
                    sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&lt;br /&gt;
                u[i][j] = 1/sum&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        //определения максимального различия между u[][] и uPrev[][]&lt;br /&gt;
        float max = 0;&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                if (abs(uPrev[i][j]-u[i][j])&amp;gt;max)&lt;br /&gt;
                    max = abs(uPrev[i][j]-u[i][j]);&lt;br /&gt;
&lt;br /&gt;
        if (eps &amp;lt;= max)&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
                for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                    uPrev[i][j]=u[i][j];&lt;br /&gt;
        else&lt;br /&gt;
            break;&lt;br /&gt;
             &lt;br /&gt;
    }&lt;br /&gt;
    return u;&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;
* параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
* набора входных векторов &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
* выбора начальных коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;&lt;br /&gt;
то в данном пункте будет приведена сложность одной итерации относительно количества входных векторов.&lt;br /&gt;
Как видно из предыдущего пункта, для вычисления центров кластеров требуется &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, для определения коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;O(C^2*|X|)&amp;lt;/math&amp;gt; операций, а для вычисления решающей функции - &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, где &amp;lt;math&amp;gt;|X|&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;O(C^2*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Как видно из пункта 1.5, на каждом действии каждой итерации алгоритма все операции, выполняющиеся в цикле, не зависят друг от друга и могут быть распаралелены. Это показано на Рисунке 1.&lt;br /&gt;
&lt;br /&gt;
[[File:FCMIG.png|thumb|center|1200px|Рисунок 1. Информационный граф алгоритма. (1)-(7) - это наборы последовательных действий (например, (2) - последовательные операции деления, взятия адреса и присваивания).]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На каждом ярусе ярусно-параллельной формы алгоритма будет располагаться конечное число элементарных операций, например, взятие адреса, сложение или возведение в степень. Информационый граф из п.1.7 изображает свёрнутую ярусно-параллельную форму алгоритма. &lt;br /&gt;
&lt;br /&gt;
Сложность алгоритма будем рассчитывать в предположении, что число вычислительных ядер стремится к бесконечности. Как видно из информационного графа, параллельная сложность вычисления центров кластеров составляет &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;, вычисления коэффициентов принадлежности - &amp;lt;math&amp;gt;O(\log_{2} C^2*|X|)&amp;lt;/math&amp;gt;, а вычисления решающей функции - не больше чем &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом параллельная сложность итерации алгоритма составляет &amp;lt;math&amp;gt;O(\log_{2} C^4*|X|^3)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Так как задачи, решаемые в макроструктуре алгоритма могут быть сведены к задачам вычисления суммы элементов массива и максимального элемента массива, то на &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом ярусе графа будет находиться &amp;lt;math&amp;gt;{N}\over{2^i}&amp;lt;/math&amp;gt; операции, где N - количество элементов массива.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; - набор из &amp;lt;math&amp;gt;|X|&amp;lt;/math&amp;gt; входных векторов длины &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - количество кластеров&lt;br /&gt;
* &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
Объем входных данных: &amp;lt;math&amp;gt;kp&amp;lt;/math&amp;gt; (не считая трех коэффициентов)&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - матрица принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
Объем выходных данных: &amp;lt;math&amp;gt;kC&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Увеличение скорости работы алгоритма при распараллеливании на бесконечном количестве процессоров составляет &amp;lt;math&amp;gt;O({{C^2*|X|}\over{\log_{2} (C^4*|X|^3)}})&amp;lt;/math&amp;gt;. Например, для разбиения 1000 элементов на 10 кластеров производительность параллельного алгоритма будет в 2315 раз больше, а на 20 кластеров - уже в 8477 раз.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
Как видно из предыдущих пунктов, масштабируется данный алгоритм хорошо. С увеличением количества процессоров время работы падает, а с увеличением количества входных данных и количества кластеров - растёт. На рисунках показана масштабируемость алгоритма.&lt;br /&gt;
[[File:FCMCOMP1.jpg|thumb|center|1500px|Рисунок 2. Масштабируемость алгоритма. Зависимость сложности алгоритма от количества процессоров и входных данных при фиксированном количестве кластеров.]]&lt;br /&gt;
[[File:FCMCOMP2.jpg|thumb|center|1500px|Рисунок 3. Масштабируемость алгоритма. Зависимость сложности алгоритма от количества процессоров и кластеров при фиксированном количестве входных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Существует множество реализаций данного алгоритма. Рассмотрим некоторые из них:&lt;br /&gt;
&lt;br /&gt;
- Например, тут: https://habrahabr.ru/post/208496/&lt;br /&gt;
&amp;lt;ref&amp;gt;Нестер А. &amp;quot;Алгоритм нечёткой кластеризации fuzzy c-means на PHP&amp;quot;. [html](https://habrahabr.ru/post/208496/)&amp;lt;/ref&amp;gt;&lt;br /&gt;
приведено краткое описание алгоритма и приведена его реализация на php. В данной статье довольно подробно расписан каждый шаг алгоритма и приведён соответствующий ему фрагмент кода.&lt;br /&gt;
&lt;br /&gt;
- Тут: http://num-meth.srcc.msu.ru/zhurnal/tom_2012/v13r207.html&lt;br /&gt;
&amp;lt;ref&amp;gt;Миниахметов Р.М., Цымблер М.Л. &amp;quot;Интеграция алгоритма кластеризации Fuzzy c-Means в PostgreSQL&amp;quot;. [html](http://num-meth.srcc.msu.ru/zhurnal/tom_2012/v13r207.html)&amp;lt;/ref&amp;gt;&lt;br /&gt;
приводится реализация алгоритма для PostgreSQL, а также прилагается скрипт внедрения алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=6323</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=6323"/>
		<updated>2016-10-13T09:45:48Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Нечеткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(C^2*N*D*IterNumber)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(\log_{2}C^4*|X|^3) * IterNumber&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(C^2*|X|)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;|X|*C &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;|X|*C &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: [[Участник:Demon smd|Д.А.Гуськов]] [[Участник:marina abramenkova|М.А.Абраменкова]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means Данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризируемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних для каждого вектора определяет случайным образом значения принадлежности вектора к каждому кластеру и запускает итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) Расчёт центров кластеров.&lt;br /&gt;
&lt;br /&gt;
2) Расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) Расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) Расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации.Если их разница меньше установленного значения, то алгоритм прекращает работу. Решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
J_{m} = \sum_{i = 1}^{N}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty &amp;amp; ; \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные на каждой итерации ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^{(k)} - u_{i,j}^{(k-1)}|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&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;
В каждой итерации алгоритма происходит 3 основных действия описанных в п. 1.2.1:&lt;br /&gt;
*вычисление центров кластеров&lt;br /&gt;
*вычисление коэффициентов принадлежности&lt;br /&gt;
*вычисление решающей функции&lt;br /&gt;
Подробное описание макроструктур в виде кода приведено в пункте 1.5&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Схему реализации последовательного алгоритма можно описать на C++ следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FCM (X[], C, m, eps){&lt;br /&gt;
    float deside = 0;&lt;br /&gt;
    float newDeside = 0;&lt;br /&gt;
    generateMembershipDegree();            //заполняет uPrev[][] случайными нормрованными коэффициентами&lt;br /&gt;
    while (true){&lt;br /&gt;
        newDeside = deside;&lt;br /&gt;
&lt;br /&gt;
        //вычисление центров кластеров&lt;br /&gt;
        for (int j=0; j&amp;lt;C; j++){           //для каждого кластера&lt;br /&gt;
            float numerator = 0;&lt;br /&gt;
            float denumerator = 0;&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++){        //для каждого вектора&lt;br /&gt;
                numerator+=pow(u[i][j], m) * x[i];&lt;br /&gt;
                denumerator+=pow(u[i][j], m);&lt;br /&gt;
            }&lt;br /&gt;
            c[j] = numerator / denumerator;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //вычисление коэффициентов u[][]&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                sum = 0;&lt;br /&gt;
                for (int k=0; k&amp;lt;C; k++)&lt;br /&gt;
                    sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&lt;br /&gt;
                u[i][j] = 1/sum&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        //определения максимального различия между u[][] и uPrev[][]&lt;br /&gt;
        float max = 0;&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                if (abs(uPrev[i][j]-u[i][j])&amp;gt;max)&lt;br /&gt;
                    max = abs(uPrev[i][j]-u[i][j]);&lt;br /&gt;
&lt;br /&gt;
        if (eps &amp;lt;= max)&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
                for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                    uPrev[i][j]=u[i][j];&lt;br /&gt;
        else&lt;br /&gt;
            break;&lt;br /&gt;
             &lt;br /&gt;
    }&lt;br /&gt;
    return u;&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;
* параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
* набора входных векторов &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
* выбора начальных коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;&lt;br /&gt;
то в данном пункте будет приведена сложность одной итерации относительно количества входных векторов.&lt;br /&gt;
Как видно из предыдущего пункта, для вычисления центров кластеров требуется &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, для определения коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;O(C^2*|X|)&amp;lt;/math&amp;gt; операций, а для вычисления решающей функции - &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, где &amp;lt;math&amp;gt;|X|&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;O(C^2*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Как видно из пункта 1.5, на каждом действии каждой итерации алгоритма все операции, выполняющиеся в цикле, не зависят друг от друга и могут быть распаралелены. Это показано на Рисунке 1.&lt;br /&gt;
&lt;br /&gt;
[[File:FCMIG.png|thumb|center|1200px|Рисунок 1. Информационный граф алгоритма. (1)-(7) - это наборы последовательных действий (например, (2) - последовательные операции деления, взятия адреса и присваивания).]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На каждом ярусе ярусно-параллельной формы алгоритма будет располагаться конечное число элементарных операций, например, взятие адреса, сложение или возведение в степень. Информационый граф из п.1.7 изображает свёрнутую ярусно-параллельную форму алгоритма. Как видно из информационного графа, Параллельная сложность вычисления центров кластеров составляет &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;, вычисления коэффициентов принадлежности - &amp;lt;math&amp;gt;O(\log_{2} C^2*|X|)&amp;lt;/math&amp;gt;, а вычисления решающей функции - не больше чем &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом Параллельная сложность итерации алгоритма составляет &amp;lt;math&amp;gt;O(\log_{2} C^4*|X|^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Так как задачи, решаемые в макроструктурах алгоритма могут быть сведены к задачам вычисления суммы элементов массива и максимального элемента массива, то на &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом ярусе графа будет находиться &amp;lt;math&amp;gt;{N}\over{2^i}&amp;lt;/math&amp;gt; операции, где N - количество элементов массива.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - набор входных векторов&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - количество кластеров&lt;br /&gt;
* &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - матрица принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Увеличение скорости работы алгоритма при распараллеливании на бесконечном количестве процессоров составляет &amp;lt;math&amp;gt;O({{C^2*|X|}\over{\log_{2} (C^4*|X|^3)}})&amp;lt;/math&amp;gt;. Например, для разбиения 1000 элементов на 10 кластеров производительность параллельного алгоритма будет в 2315 раз больше, а на 20 кластеров - уже в 8477 раз.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
Как видно из предыдущих пунктов, масштабируется данный алгоритм хорошо. С увеличением количества процессоров время работы падает, а с увеличением количества входных данных и количества кластеров - растёт. На рисунках приведена масштабируемость алгоритма.&lt;br /&gt;
[[File:FCMCOMP1.jpg|thumb|center|1500px|Рисунок 2. Масштабируемость алгоритма. Зависимость сложности алгоритма от количества процессоров и входных данных при фиксированном количестве кластеров.]]&lt;br /&gt;
[[File:FCMCOMP2.jpg|thumb|center|1500px|Рисунок 3. Масштабируемость алгоритма. Зависимость сложности алгоритма от количества процессоров и кластеров при фиксированном количестве входных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Существует множество реализаций данного алгоритма. Рассмотрим некоторые из них:&lt;br /&gt;
&lt;br /&gt;
- Например, тут: https://habrahabr.ru/post/208496/&lt;br /&gt;
&amp;lt;ref&amp;gt;Нестер А. &amp;quot;Алгоритм нечёткой кластеризации fuzzy c-means на PHP&amp;quot;. [html](https://habrahabr.ru/post/208496/)&amp;lt;/ref&amp;gt;&lt;br /&gt;
приведено краткое описание алгоритма и приведена его реализация на php. В данной статье довольно подробно расписан каждый шаг алгоритма и приведён соответствующий ему фрагмент кода.&lt;br /&gt;
&lt;br /&gt;
- Тут: http://num-meth.srcc.msu.ru/zhurnal/tom_2012/v13r207.html&lt;br /&gt;
&amp;lt;ref&amp;gt;Миниахметов Р.М., Цымблер М.Л. &amp;quot;Интеграция алгоритма кластеризации Fuzzy c-Means в PostgreSQL&amp;quot;. [html](http://num-meth.srcc.msu.ru/zhurnal/tom_2012/v13r207.html)&amp;lt;/ref&amp;gt;&lt;br /&gt;
приводится реализация алгоритма для PostgreSQL, а также прилагается скрипт внедрения алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=6322</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=6322"/>
		<updated>2016-10-13T09:45:10Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Нечеткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(C^2*N*D*IterNumber)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(\log_{2}C^4*|X|^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(C^2*|X|)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;|X|*C &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;|X|*C &amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: [[Участник:Demon smd|Д.А.Гуськов]] [[Участник:marina abramenkova|М.А.Абраменкова]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means Данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризируемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних для каждого вектора определяет случайным образом значения принадлежности вектора к каждому кластеру и запускает итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) Расчёт центров кластеров.&lt;br /&gt;
&lt;br /&gt;
2) Расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) Расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) Расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации.Если их разница меньше установленного значения, то алгоритм прекращает работу. Решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
J_{m} = \sum_{i = 1}^{N}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty &amp;amp; ; \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные на каждой итерации ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^{(k)} - u_{i,j}^{(k-1)}|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&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;
В каждой итерации алгоритма происходит 3 основных действия описанных в п. 1.2.1:&lt;br /&gt;
*вычисление центров кластеров&lt;br /&gt;
*вычисление коэффициентов принадлежности&lt;br /&gt;
*вычисление решающей функции&lt;br /&gt;
Подробное описание макроструктур в виде кода приведено в пункте 1.5&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Схему реализации последовательного алгоритма можно описать на C++ следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FCM (X[], C, m, eps){&lt;br /&gt;
    float deside = 0;&lt;br /&gt;
    float newDeside = 0;&lt;br /&gt;
    generateMembershipDegree();            //заполняет uPrev[][] случайными нормрованными коэффициентами&lt;br /&gt;
    while (true){&lt;br /&gt;
        newDeside = deside;&lt;br /&gt;
&lt;br /&gt;
        //вычисление центров кластеров&lt;br /&gt;
        for (int j=0; j&amp;lt;C; j++){           //для каждого кластера&lt;br /&gt;
            float numerator = 0;&lt;br /&gt;
            float denumerator = 0;&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++){        //для каждого вектора&lt;br /&gt;
                numerator+=pow(u[i][j], m) * x[i];&lt;br /&gt;
                denumerator+=pow(u[i][j], m);&lt;br /&gt;
            }&lt;br /&gt;
            c[j] = numerator / denumerator;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //вычисление коэффициентов u[][]&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                sum = 0;&lt;br /&gt;
                for (int k=0; k&amp;lt;C; k++)&lt;br /&gt;
                    sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&lt;br /&gt;
                u[i][j] = 1/sum&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        //определения максимального различия между u[][] и uPrev[][]&lt;br /&gt;
        float max = 0;&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                if (abs(uPrev[i][j]-u[i][j])&amp;gt;max)&lt;br /&gt;
                    max = abs(uPrev[i][j]-u[i][j]);&lt;br /&gt;
&lt;br /&gt;
        if (eps &amp;lt;= max)&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
                for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                    uPrev[i][j]=u[i][j];&lt;br /&gt;
        else&lt;br /&gt;
            break;&lt;br /&gt;
             &lt;br /&gt;
    }&lt;br /&gt;
    return u;&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;
* параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
* набора входных векторов &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
* выбора начальных коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;&lt;br /&gt;
то в данном пункте будет приведена сложность одной итерации относительно количества входных векторов.&lt;br /&gt;
Как видно из предыдущего пункта, для вычисления центров кластеров требуется &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, для определения коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;O(C^2*|X|)&amp;lt;/math&amp;gt; операций, а для вычисления решающей функции - &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, где &amp;lt;math&amp;gt;|X|&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;O(C^2*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Как видно из пункта 1.5, на каждом действии каждой итерации алгоритма все операции, выполняющиеся в цикле, не зависят друг от друга и могут быть распаралелены. Это показано на Рисунке 1.&lt;br /&gt;
&lt;br /&gt;
[[File:FCMIG.png|thumb|center|1200px|Рисунок 1. Информационный граф алгоритма. (1)-(7) - это наборы последовательных действий (например, (2) - последовательные операции деления, взятия адреса и присваивания).]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На каждом ярусе ярусно-параллельной формы алгоритма будет располагаться конечное число элементарных операций, например, взятие адреса, сложение или возведение в степень. Информационый граф из п.1.7 изображает свёрнутую ярусно-параллельную форму алгоритма. Как видно из информационного графа, Параллельная сложность вычисления центров кластеров составляет &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;, вычисления коэффициентов принадлежности - &amp;lt;math&amp;gt;O(\log_{2} C^2*|X|)&amp;lt;/math&amp;gt;, а вычисления решающей функции - не больше чем &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом Параллельная сложность итерации алгоритма составляет &amp;lt;math&amp;gt;O(\log_{2} C^4*|X|^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Так как задачи, решаемые в макроструктурах алгоритма могут быть сведены к задачам вычисления суммы элементов массива и максимального элемента массива, то на &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом ярусе графа будет находиться &amp;lt;math&amp;gt;{N}\over{2^i}&amp;lt;/math&amp;gt; операции, где N - количество элементов массива.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - набор входных векторов&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - количество кластеров&lt;br /&gt;
* &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - матрица принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Увеличение скорости работы алгоритма при распараллеливании на бесконечном количестве процессоров составляет &amp;lt;math&amp;gt;O({{C^2*|X|}\over{\log_{2} (C^4*|X|^3)}})&amp;lt;/math&amp;gt;. Например, для разбиения 1000 элементов на 10 кластеров производительность параллельного алгоритма будет в 2315 раз больше, а на 20 кластеров - уже в 8477 раз.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
Как видно из предыдущих пунктов, масштабируется данный алгоритм хорошо. С увеличением количества процессоров время работы падает, а с увеличением количества входных данных и количества кластеров - растёт. На рисунках приведена масштабируемость алгоритма.&lt;br /&gt;
[[File:FCMCOMP1.jpg|thumb|center|1500px|Рисунок 2. Масштабируемость алгоритма. Зависимость сложности алгоритма от количества процессоров и входных данных при фиксированном количестве кластеров.]]&lt;br /&gt;
[[File:FCMCOMP2.jpg|thumb|center|1500px|Рисунок 3. Масштабируемость алгоритма. Зависимость сложности алгоритма от количества процессоров и кластеров при фиксированном количестве входных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Существует множество реализаций данного алгоритма. Рассмотрим некоторые из них:&lt;br /&gt;
&lt;br /&gt;
- Например, тут: https://habrahabr.ru/post/208496/&lt;br /&gt;
&amp;lt;ref&amp;gt;Нестер А. &amp;quot;Алгоритм нечёткой кластеризации fuzzy c-means на PHP&amp;quot;. [html](https://habrahabr.ru/post/208496/)&amp;lt;/ref&amp;gt;&lt;br /&gt;
приведено краткое описание алгоритма и приведена его реализация на php. В данной статье довольно подробно расписан каждый шаг алгоритма и приведён соответствующий ему фрагмент кода.&lt;br /&gt;
&lt;br /&gt;
- Тут: http://num-meth.srcc.msu.ru/zhurnal/tom_2012/v13r207.html&lt;br /&gt;
&amp;lt;ref&amp;gt;Миниахметов Р.М., Цымблер М.Л. &amp;quot;Интеграция алгоритма кластеризации Fuzzy c-Means в PostgreSQL&amp;quot;. [html](http://num-meth.srcc.msu.ru/zhurnal/tom_2012/v13r207.html)&amp;lt;/ref&amp;gt;&lt;br /&gt;
приводится реализация алгоритма для PostgreSQL, а также прилагается скрипт внедрения алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=6318</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=6318"/>
		<updated>2016-10-13T09:44:10Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Нечеткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(C^2*N*D*IterNumber)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(\log_{2} C^4*|X|^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(C^2*|X|)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;|X|*С&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;|X|*C&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: [[Участник:Demon smd|Д.А.Гуськов]] [[Участник:marina abramenkova|М.А.Абраменкова]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means Данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризируемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних для каждого вектора определяет случайным образом значения принадлежности вектора к каждому кластеру и запускает итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) Расчёт центров кластеров.&lt;br /&gt;
&lt;br /&gt;
2) Расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) Расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) Расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации.Если их разница меньше установленного значения, то алгоритм прекращает работу. Решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
J_{m} = \sum_{i = 1}^{N}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty &amp;amp; ; \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные на каждой итерации ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^{(k)} - u_{i,j}^{(k-1)}|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&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;
В каждой итерации алгоритма происходит 3 основных действия описанных в п. 1.2.1:&lt;br /&gt;
*вычисление центров кластеров&lt;br /&gt;
*вычисление коэффициентов принадлежности&lt;br /&gt;
*вычисление решающей функции&lt;br /&gt;
Подробное описание макроструктур в виде кода приведено в пункте 1.5&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Схему реализации последовательного алгоритма можно описать на C++ следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FCM (X[], C, m, eps){&lt;br /&gt;
    float deside = 0;&lt;br /&gt;
    float newDeside = 0;&lt;br /&gt;
    generateMembershipDegree();            //заполняет uPrev[][] случайными нормрованными коэффициентами&lt;br /&gt;
    while (true){&lt;br /&gt;
        newDeside = deside;&lt;br /&gt;
&lt;br /&gt;
        //вычисление центров кластеров&lt;br /&gt;
        for (int j=0; j&amp;lt;C; j++){           //для каждого кластера&lt;br /&gt;
            float numerator = 0;&lt;br /&gt;
            float denumerator = 0;&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++){        //для каждого вектора&lt;br /&gt;
                numerator+=pow(u[i][j], m) * x[i];&lt;br /&gt;
                denumerator+=pow(u[i][j], m);&lt;br /&gt;
            }&lt;br /&gt;
            c[j] = numerator / denumerator;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //вычисление коэффициентов u[][]&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                sum = 0;&lt;br /&gt;
                for (int k=0; k&amp;lt;C; k++)&lt;br /&gt;
                    sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&lt;br /&gt;
                u[i][j] = 1/sum&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        //определения максимального различия между u[][] и uPrev[][]&lt;br /&gt;
        float max = 0;&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                if (abs(uPrev[i][j]-u[i][j])&amp;gt;max)&lt;br /&gt;
                    max = abs(uPrev[i][j]-u[i][j]);&lt;br /&gt;
&lt;br /&gt;
        if (eps &amp;lt;= max)&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
                for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                    uPrev[i][j]=u[i][j];&lt;br /&gt;
        else&lt;br /&gt;
            break;&lt;br /&gt;
             &lt;br /&gt;
    }&lt;br /&gt;
    return u;&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;
* параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
* набора входных векторов &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
* выбора начальных коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;&lt;br /&gt;
то в данном пункте будет приведена сложность одной итерации относительно количества входных векторов.&lt;br /&gt;
Как видно из предыдущего пункта, для вычисления центров кластеров требуется &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, для определения коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;O(C^2*|X|)&amp;lt;/math&amp;gt; операций, а для вычисления решающей функции - &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, где &amp;lt;math&amp;gt;|X|&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;O(C^2*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Как видно из пункта 1.5, на каждом действии каждой итерации алгоритма все операции, выполняющиеся в цикле, не зависят друг от друга и могут быть распаралелены. Это показано на Рисунке 1.&lt;br /&gt;
&lt;br /&gt;
[[File:FCMIG.png|thumb|center|1200px|Рисунок 1. Информационный граф алгоритма. (1)-(7) - это наборы последовательных действий (например, (2) - последовательные операции деления, взятия адреса и присваивания).]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На каждом ярусе ярусно-параллельной формы алгоритма будет располагаться конечное число элементарных операций, например, взятие адреса, сложение или возведение в степень. Информационый граф из п.1.7 изображает свёрнутую ярусно-параллельную форму алгоритма. Как видно из информационного графа, Параллельная сложность вычисления центров кластеров составляет &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;, вычисления коэффициентов принадлежности - &amp;lt;math&amp;gt;O(\log_{2} C^2*|X|)&amp;lt;/math&amp;gt;, а вычисления решающей функции - не больше чем &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом Параллельная сложность итерации алгоритма составляет &amp;lt;math&amp;gt;O(\log_{2} C^4*|X|^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Так как задачи, решаемые в макроструктурах алгоритма могут быть сведены к задачам вычисления суммы элементов массива и максимального элемента массива, то на &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом ярусе графа будет находиться &amp;lt;math&amp;gt;{N}\over{2^i}&amp;lt;/math&amp;gt; операции, где N - количество элементов массива.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - набор входных векторов&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - количество кластеров&lt;br /&gt;
* &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - матрица принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Увеличение скорости работы алгоритма при распараллеливании на бесконечном количестве процессоров составляет &amp;lt;math&amp;gt;O({{C^2*|X|}\over{\log_{2} (C^4*|X|^3)}})&amp;lt;/math&amp;gt;. Например, для разбиения 1000 элементов на 10 кластеров производительность параллельного алгоритма будет в 2315 раз больше, а на 20 кластеров - уже в 8477 раз.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
Как видно из предыдущих пунктов, масштабируется данный алгоритм хорошо. С увеличением количества процессоров время работы падает, а с увеличением количества входных данных и количества кластеров - растёт. На рисунках приведена масштабируемость алгоритма.&lt;br /&gt;
[[File:FCMCOMP1.jpg|thumb|center|1500px|Рисунок 2. Масштабируемость алгоритма. Зависимость сложности алгоритма от количества процессоров и входных данных при фиксированном количестве кластеров.]]&lt;br /&gt;
[[File:FCMCOMP2.jpg|thumb|center|1500px|Рисунок 3. Масштабируемость алгоритма. Зависимость сложности алгоритма от количества процессоров и кластеров при фиксированном количестве входных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Существует множество реализаций данного алгоритма. Рассмотрим некоторые из них:&lt;br /&gt;
&lt;br /&gt;
- Например, тут: https://habrahabr.ru/post/208496/&lt;br /&gt;
&amp;lt;ref&amp;gt;Нестер А. &amp;quot;Алгоритм нечёткой кластеризации fuzzy c-means на PHP&amp;quot;. [html](https://habrahabr.ru/post/208496/)&amp;lt;/ref&amp;gt;&lt;br /&gt;
приведено краткое описание алгоритма и приведена его реализация на php. В данной статье довольно подробно расписан каждый шаг алгоритма и приведён соответствующий ему фрагмент кода.&lt;br /&gt;
&lt;br /&gt;
- Тут: http://num-meth.srcc.msu.ru/zhurnal/tom_2012/v13r207.html&lt;br /&gt;
&amp;lt;ref&amp;gt;Миниахметов Р.М., Цымблер М.Л. &amp;quot;Интеграция алгоритма кластеризации Fuzzy c-Means в PostgreSQL&amp;quot;. [html](http://num-meth.srcc.msu.ru/zhurnal/tom_2012/v13r207.html)&amp;lt;/ref&amp;gt;&lt;br /&gt;
приводится реализация алгоритма для PostgreSQL, а также прилагается скрипт внедрения алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=6310</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=6310"/>
		<updated>2016-10-13T09:32:13Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Нечеткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(C^2*N*D*IterNumber)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: [[Участник:Demon smd|Д.А.Гуськов]] [[Участник:marina abramenkova|М.А.Абраменкова]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means Данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризируемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних для каждого вектора определяет случайным образом значения принадлежности вектора к каждому кластеру и запускает итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) Расчёт центров кластеров.&lt;br /&gt;
&lt;br /&gt;
2) Расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) Расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) Расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации.Если их разница меньше установленного значения, то алгоритм прекращает работу. Решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
J_{m} = \sum_{i = 1}^{N}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty &amp;amp; ; \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные на каждой итерации ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^{(k)} - u_{i,j}^{(k-1)}|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&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;
В каждой итерации алгоритма происходит 3 основных действия описанных в п. 1.2.1:&lt;br /&gt;
*вычисление центров кластеров&lt;br /&gt;
*вычисление коэффициентов принадлежности&lt;br /&gt;
*вычисление решающей функции&lt;br /&gt;
Подробное описание макроструктур в виде кода приведено в пункте 1.5&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Схему реализации последовательного алгоритма можно описать на C++ следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FCM (X[], C, m, eps){&lt;br /&gt;
    float deside = 0;&lt;br /&gt;
    float newDeside = 0;&lt;br /&gt;
    generateMembershipDegree();            //заполняет uPrev[][] случайными нормрованными коэффициентами&lt;br /&gt;
    while (true){&lt;br /&gt;
        newDeside = deside;&lt;br /&gt;
&lt;br /&gt;
        //вычисление центров кластеров&lt;br /&gt;
        for (int j=0; j&amp;lt;C; j++){           //для каждого кластера&lt;br /&gt;
            float numerator = 0;&lt;br /&gt;
            float denumerator = 0;&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++){        //для каждого вектора&lt;br /&gt;
                numerator+=pow(u[i][j], m) * x[i];&lt;br /&gt;
                denumerator+=pow(u[i][j], m);&lt;br /&gt;
            }&lt;br /&gt;
            c[j] = numerator / denumerator;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //вычисление коэффициентов u[][]&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                sum = 0;&lt;br /&gt;
                for (int k=0; k&amp;lt;C; k++)&lt;br /&gt;
                    sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&lt;br /&gt;
                u[i][j] = 1/sum&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        //определения максимального различия между u[][] и uPrev[][]&lt;br /&gt;
        float max = 0;&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                if (abs(uPrev[i][j]-u[i][j])&amp;gt;max)&lt;br /&gt;
                    max = abs(uPrev[i][j]-u[i][j]);&lt;br /&gt;
&lt;br /&gt;
        if (eps &amp;lt;= max)&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
                for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                    uPrev[i][j]=u[i][j];&lt;br /&gt;
        else&lt;br /&gt;
            break;&lt;br /&gt;
             &lt;br /&gt;
    }&lt;br /&gt;
    return u;&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;
* параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
* набора входных векторов &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
* выбора начальных коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;&lt;br /&gt;
то в данном пункте будет приведена сложность одной итерации относительно количества входных векторов.&lt;br /&gt;
Как видно из предыдущего пункта, для вычисления центров кластеров требуется &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, для определения коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;O(C^2*|X|)&amp;lt;/math&amp;gt; операций, а для вычисления решающей функции - &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, где &amp;lt;math&amp;gt;|X|&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;O(C^2*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Как видно из пункта 1.5, на каждом действии каждой итерации алгоритма все операции, выполняющиеся в цикле, не зависят друг от друга и могут быть распаралелены. Это показано на Рисунке 1.&lt;br /&gt;
&lt;br /&gt;
[[File:FCMIG.png|thumb|center|1200px|Рисунок 1. Информационный граф алгоритма. (1)-(7) - это наборы последовательных действий (например, (2) - последовательные операции деления, взятия адреса и присваивания).]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На каждом ярусе ярусно-параллельной формы алгоритма будет располагаться конечное число элементарных операций, например, взятие адреса, сложение или возведение в степень. Информационый граф из п.1.7 изображает свёрнутую ярусно-параллельную форму алгоритма. Как видно из информационного графа, Параллельная сложность вычисления центров кластеров составляет &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;, вычисления коэффициентов принадлежности - &amp;lt;math&amp;gt;O(\log_{2} C^2*|X|)&amp;lt;/math&amp;gt;, а вычисления решающей функции - не больше чем &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом Параллельная сложность итерации алгоритма составляет &amp;lt;math&amp;gt;O(\log_{2} C^4*|X|^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Так как задачи, решаемые в макроструктурах алгоритма могут быть сведены к задачам вычисления суммы элементов массива и максимального элемента массива, то на &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом ярусе графа будет находиться &amp;lt;math&amp;gt;{N}\over{2^i}&amp;lt;/math&amp;gt; операции, где N - количество элементов массива.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - набор входных векторов&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - количество кластеров&lt;br /&gt;
* &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - матрица принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Увеличение скорости работы алгоритма при распараллеливании на бесконечном количестве процессоров составляет &amp;lt;math&amp;gt;O({{C^2*|X|}\over{\log_{2} (C^4*|X|^3)}})&amp;lt;/math&amp;gt;. Например, для разбиения 1000 элементов на 10 кластеров производительность параллельного алгоритма будет в 2315 раз больше, а на 20 кластеров - уже в 8477 раз.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
Как видно из предыдущих пунктов, масштабируется данный алгоритм хорошо. С увеличением количества процессоров время работы падает, а с увеличением количества входных данных и количества кластеров - растёт. На рисунках приведена масштабируемость алгоритма.&lt;br /&gt;
[[File:FCMCOMP1.jpg|thumb|center|1500px|Рисунок 2. Масштабируемость алгоритма. Зависимость сложности алгоритма от количества процессоров и входных данных при фиксированном количестве кластеров.]]&lt;br /&gt;
[[File:FCMCOMP2.jpg|thumb|center|1500px|Рисунок 3. Масштабируемость алгоритма. Зависимость сложности алгоритма от количества процессоров и кластеров при фиксированном количестве входных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Существует множество реализаций данного алгоритма. Рассмотрим некоторые из них:&lt;br /&gt;
&lt;br /&gt;
- Например, тут: https://habrahabr.ru/post/208496/&lt;br /&gt;
&amp;lt;ref&amp;gt;Нестер А. &amp;quot;Алгоритм нечёткой кластеризации fuzzy c-means на PHP&amp;quot;. [html](https://habrahabr.ru/post/208496/)&amp;lt;/ref&amp;gt;&lt;br /&gt;
приведено краткое описание алгоритма и приведена его реализация на php. В данной статье довольно подробно расписан каждый шаг алгоритма и приведён соответствующий ему фрагмент кода.&lt;br /&gt;
&lt;br /&gt;
- Тут: http://num-meth.srcc.msu.ru/zhurnal/tom_2012/v13r207.html&lt;br /&gt;
&amp;lt;ref&amp;gt;Миниахметов Р.М., Цымблер М.Л. &amp;quot;Интеграция алгоритма кластеризации Fuzzy c-Means в PostgreSQL&amp;quot;. [html](http://num-meth.srcc.msu.ru/zhurnal/tom_2012/v13r207.html)&amp;lt;/ref&amp;gt;&lt;br /&gt;
приводится реализация алгоритма для PostgreSQL, а также прилагается скрипт внедрения алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=6309</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=6309"/>
		<updated>2016-10-13T09:29:24Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Нечеткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(C^2*N*D*IterNumber)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: [[Участник:Demon smd|Д.А.Гуськов]] [[Участник:marina abramenkova|М.А.Абраменкова]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means Данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризируемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних для каждого вектора определяет случайным образом значения принадлежности вектора к каждому кластеру и запускает итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) Расчёт центров кластеров.&lt;br /&gt;
&lt;br /&gt;
2) Расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) Расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) Расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации.Если их разница меньше установленного значения, то алгоритм прекращает работу. Решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
J_{m} = \sum_{i = 1}^{N}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty &amp;amp; ; \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные на каждой итерации ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^{(k)} - u_{i,j}^{(k-1)}|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&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;
В каждой итерации алгоритма происходит 3 основных действия описанных в п. 1.2.1:&lt;br /&gt;
*вычисление центров кластеров&lt;br /&gt;
*вычисление коэффициентов принадлежности&lt;br /&gt;
*вычисление решающей функции&lt;br /&gt;
Подробное описание макроструктур в виде кода приведено в пункте 1.5&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Схему реализации последовательного алгоритма можно описать на C++ следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FCM (X[], C, m, eps){&lt;br /&gt;
    float deside = 0;&lt;br /&gt;
    float newDeside = 0;&lt;br /&gt;
    generateMembershipDegree();            //заполняет uPrev[][] случайными нормрованными коэффициентами&lt;br /&gt;
    while (true){&lt;br /&gt;
        newDeside = deside;&lt;br /&gt;
&lt;br /&gt;
        //вычисление центров кластеров&lt;br /&gt;
        for (int j=0; j&amp;lt;C; j++){           //для каждого кластера&lt;br /&gt;
            float numerator = 0;&lt;br /&gt;
            float denumerator = 0;&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++){        //для каждого вектора&lt;br /&gt;
                numerator+=pow(u[i][j], m) * x[i];&lt;br /&gt;
                denumerator+=pow(u[i][j], m);&lt;br /&gt;
            }&lt;br /&gt;
            c[j] = numerator / denumerator;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //вычисление коэффициентов u[][]&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                sum = 0;&lt;br /&gt;
                for (int k=0; k&amp;lt;C; k++)&lt;br /&gt;
                    sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&lt;br /&gt;
                u[i][j] = 1/sum&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        //определения максимального различия между u[][] и uPrev[][]&lt;br /&gt;
        float max = 0;&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                if (abs(uPrev[i][j]-u[i][j])&amp;gt;max)&lt;br /&gt;
                    max = abs(uPrev[i][j]-u[i][j]);&lt;br /&gt;
&lt;br /&gt;
        if (eps &amp;lt;= max)&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
                for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                    uPrev[i][j]=u[i][j];&lt;br /&gt;
        else&lt;br /&gt;
            break;&lt;br /&gt;
             &lt;br /&gt;
    }&lt;br /&gt;
    return u;&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;
* параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
* набора входных векторов &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
* выбора начальных коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;&lt;br /&gt;
то в данном пункте будет приведена сложность одной итерации относительно количества входных векторов.&lt;br /&gt;
Как видно из предыдущего пункта, для вычисления центров кластеров требуется &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, для определения коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;O(C^2*|X|)&amp;lt;/math&amp;gt; операций, а для вычисления решающей функции - &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, где &amp;lt;math&amp;gt;|X|&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;O(C^2*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Как видно из пункта 1.5, на каждом действии каждой итерации алгоритма все операции, выполняющиеся в цикле, не зависят друг от друга и могут быть распаралелены. Это показано на Рисунке 1.&lt;br /&gt;
&lt;br /&gt;
[[File:FCMIG.png|thumb|center|1200px|Рисунок 1. Информационный граф алгоритма. (1)-(7) - это наборы последовательных действий (например, (2) - последовательные операции деления, взятия адреса и присваивания).]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На каждом ярусе ярусно-параллельной формы алгоритма будет располагаться конечное число элементарных операций, например, взятие адреса, сложение или возведение в степень. Информационый граф из п.1.7 изображает свёрнутую ярусно-параллельную форму алгоритма. Как видно из информационного графа, Параллельная сложность вычисления центров кластеров составляет &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;, вычисления коэффициентов принадлежности - &amp;lt;math&amp;gt;O(\log_{2} C^2*|X|)&amp;lt;/math&amp;gt;, а вычисления решающей функции - не больше чем &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом Параллельная сложность итерации алгоритма составляет &amp;lt;math&amp;gt;O(\log_{2} C^4*|X|^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Так как задачи, решаемые в макроструктурах алгоритма могут быть сведены к задачам вычисления суммы элементов массива и максимального элемента массива, то на &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом ярусе графа будет находиться &amp;lt;math&amp;gt;{N}\over{2^i}&amp;lt;/math&amp;gt; операции, где N - количество элементов массива.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - набор входных векторов&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - количество кластеров&lt;br /&gt;
* &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - матрица принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Увеличение скорости работы алгоритма при распараллеливании на бесконечном количестве процессоров составляет &amp;lt;math&amp;gt;O({{C^2*|X|}\over{\log_{2} (C^4*|X|^3)}})&amp;lt;/math&amp;gt;. Например, для разбиения 1000 элементов на 10 кластеров производительность параллельного алгоритма будет в 2315 раз больше, а на 20 кластеров - уже в 8477 раз.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
Как видно из предыдущих пунктов, масштабируется данный алгоритм хорошо. С увеличением количества процессоров время работы падает, а с увеличением количества входных данных и количества кластеров - растёт. На рисунках приведена масштабируемость алгоритма.&lt;br /&gt;
[[File:FCMCOMP1.jpg|thumb|center|1200px|Рисунок 2. Масштабируемость алгоритма. Зависимость сложности алгоритма от количества процессоров и входных данных при фиксированном количестве кластеров.]]&lt;br /&gt;
[[File:FCMCOMP2.jpg|thumb|center|1200px|Рисунок 3. Масштабируемость алгоритма. Зависимость сложности алгоритма от количества процессоров и кластеров при фиксированном количестве входных данных.]]&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Существует множество реализаций данного алгоритма. Рассмотрим некоторые из них:&lt;br /&gt;
&lt;br /&gt;
- Например, тут: https://habrahabr.ru/post/208496/&lt;br /&gt;
&amp;lt;ref&amp;gt;Нестер А. &amp;quot;Алгоритм нечёткой кластеризации fuzzy c-means на PHP&amp;quot;. [html](https://habrahabr.ru/post/208496/)&amp;lt;/ref&amp;gt;&lt;br /&gt;
приведено краткое описание алгоритма и приведена его реализация на php. В данной статье довольно подробно расписан каждый шаг алгоритма и приведён соответствующий ему фрагмент кода.&lt;br /&gt;
&lt;br /&gt;
- Тут: http://num-meth.srcc.msu.ru/zhurnal/tom_2012/v13r207.html&lt;br /&gt;
&amp;lt;ref&amp;gt;Миниахметов Р.М., Цымблер М.Л. &amp;quot;Интеграция алгоритма кластеризации Fuzzy c-Means в PostgreSQL&amp;quot;. [html](http://num-meth.srcc.msu.ru/zhurnal/tom_2012/v13r207.html)&amp;lt;/ref&amp;gt;&lt;br /&gt;
приводится реализация алгоритма для PostgreSQL, а также прилагается скрипт внедрения алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=6296</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=6296"/>
		<updated>2016-10-13T08:37:17Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: /* Существующие реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Нечеткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(C^2*N*D*IterNumber)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: [[Участник:Demon smd|Д.А.Гуськов]] [[Участник:marina abramenkova|М.А.Абраменкова]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means Данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризируемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних для каждого вектора определяет случайным образом значения принадлежности вектора к каждому кластеру и запускает итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) Расчёт центров кластеров.&lt;br /&gt;
&lt;br /&gt;
2) Расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) Расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) Расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации.Если их разница меньше установленного значения, то алгоритм прекращает работу. Решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
J_{m} = \sum_{i = 1}^{N}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty &amp;amp; ; \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные на каждой итерации ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^{(k)} - u_{i,j}^{(k-1)}|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&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;
В каждой итерации алгоритма происходит 3 основных действия описанных в п. 1.2.1:&lt;br /&gt;
*вычисление центров кластеров&lt;br /&gt;
*вычисление коэффициентов принадлежности&lt;br /&gt;
*вычисление решающей функции&lt;br /&gt;
Подробное описание макроструктур в виде кода приведено в пункте 1.5&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Схему реализации последовательного алгоритма можно описать на C++ следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FCM (X[], C, m, eps){&lt;br /&gt;
    float deside = 0;&lt;br /&gt;
    float newDeside = 0;&lt;br /&gt;
    generateMembershipDegree();            //заполняет uPrev[][] случайными нормрованными коэффициентами&lt;br /&gt;
    while (true){&lt;br /&gt;
        newDeside = deside;&lt;br /&gt;
&lt;br /&gt;
        //вычисление центров кластеров&lt;br /&gt;
        for (int j=0; j&amp;lt;C; j++){           //для каждого кластера&lt;br /&gt;
            float numerator = 0;&lt;br /&gt;
            float denumerator = 0;&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++){        //для каждого вектора&lt;br /&gt;
                numerator+=pow(u[i][j], m) * x[i];&lt;br /&gt;
                denumerator+=pow(u[i][j], m);&lt;br /&gt;
            }&lt;br /&gt;
            c[j] = numerator / denumerator;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //вычисление коэффициентов u[][]&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                sum = 0;&lt;br /&gt;
                for (int k=0; k&amp;lt;C; k++)&lt;br /&gt;
                    sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&lt;br /&gt;
                u[i][j] = 1/sum&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        //определения максимального различия между u[][] и uPrev[][]&lt;br /&gt;
        float max = 0;&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                if (abs(uPrev[i][j]-u[i][j])&amp;gt;max)&lt;br /&gt;
                    max = abs(uPrev[i][j]-u[i][j]);&lt;br /&gt;
&lt;br /&gt;
        if (eps &amp;lt;= max)&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
                for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                    uPrev[i][j]=u[i][j];&lt;br /&gt;
        else&lt;br /&gt;
            break;&lt;br /&gt;
             &lt;br /&gt;
    }&lt;br /&gt;
    return u;&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;
* параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
* набора входных векторов &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
* выбора начальных коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;&lt;br /&gt;
то в данном пункте будет приведена сложность одной итерации относительно количества входных векторов.&lt;br /&gt;
Как видно из предыдущего пункта, для вычисления центров кластеров требуется &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, для определения коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;O(C^2*|X|)&amp;lt;/math&amp;gt; операций, а для вычисления решающей функции - &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, где &amp;lt;math&amp;gt;|X|&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;O(C^2*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Как видно из пункта 1.5, на каждом действии каждой итерации алгоритма все операции, выполняющиеся в цикле, не зависят друг от друга и могут быть распаралелены. Это показано на Рисунке 1.&lt;br /&gt;
&lt;br /&gt;
[[File:FCMIG.png|thumb|center|1200px|Рисунок 1. Информационный граф алгоритма. (1)-(7) - это наборы последовательных действий (например, (2) - последовательные операции деления, взятия адреса и присваивания).]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На каждом ярусе ярусно-параллельной формы алгоритма будет располагаться конечное число элементарных операций, например, взятие адреса, сложение или возведение в степень. Информационый граф из п.1.7 изображает свёрнутую ярусно-параллельную форму алгоритма. Как видно из информационного графа, Параллельная сложность вычисления центров кластеров составляет &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;, вычисления коэффициентов принадлежности - &amp;lt;math&amp;gt;O(\log_{2} C^2*|X|)&amp;lt;/math&amp;gt;, а вычисления решающей функции - не больше чем &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом Параллельная сложность итерации алгоритма составляет &amp;lt;math&amp;gt;O(\log_{2} C^4*|X|^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Так как задачи, решаемые в макроструктурах алгоритма могут быть сведены к задачам вычисления суммы элементов массива и максимального элемента массива, то на &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом ярусе графа будет находиться &amp;lt;math&amp;gt;{N}\over{2^i}&amp;lt;/math&amp;gt; операции, где N - количество элементов массива.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - набор входных векторов&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - количество кластеров&lt;br /&gt;
* &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - матрица принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Увеличение скорости работы алгоритма при распараллеливании на бесконечном количестве процессоров составляет &amp;lt;math&amp;gt;O({{C^2*|X|}\over{\log_{2} (C^4*|X|^3)}})&amp;lt;/math&amp;gt;. Например, для разбиения 1000 элементов на 10 кластеров производительность параллельного алгоритма будет в 2315 раз больше, а на 20 кластеров - уже в 8477 раз.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Существует множество реализаций данного алгоритма. Рассмотрим некоторые из них:&lt;br /&gt;
&lt;br /&gt;
- Например, тут: https://habrahabr.ru/post/208496/&lt;br /&gt;
&amp;lt;ref&amp;gt;Нестер А. &amp;quot;Алгоритм нечёткой кластеризации fuzzy c-means на PHP&amp;quot;. [html](https://habrahabr.ru/post/208496/)&amp;lt;/ref&amp;gt;&lt;br /&gt;
приведено краткое описание алгоритма и приведена его реализация на php. В данной статье довольно подробно расписан каждый шаг алгоритма и приведён соответствующий ему фрагмент кода.&lt;br /&gt;
&lt;br /&gt;
- Тут: http://num-meth.srcc.msu.ru/zhurnal/tom_2012/v13r207.html&lt;br /&gt;
&amp;lt;ref&amp;gt;Миниахметов Р.М., Цымблер М.Л. &amp;quot;Интеграция алгоритма кластеризации Fuzzy c-Means в PostgreSQL&amp;quot;. [html](http://num-meth.srcc.msu.ru/zhurnal/tom_2012/v13r207.html)&amp;lt;/ref&amp;gt;&lt;br /&gt;
приводится реализация алгоритма для PostgreSQL, а также прилагается скрипт внедрения алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=6292</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=6292"/>
		<updated>2016-10-13T08:27:24Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Нечеткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(C^2*N*D*IterNumber)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: [[Участник:Demon smd|Д.А.Гуськов]] [[Участник:marina abramenkova|М.А.Абраменкова]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means Данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризируемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних для каждого вектора определяет случайным образом значения принадлежности вектора к каждому кластеру и запускает итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) Расчёт центров кластеров.&lt;br /&gt;
&lt;br /&gt;
2) Расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) Расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) Расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации.Если их разница меньше установленного значения, то алгоритм прекращает работу. Решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
J_{m} = \sum_{i = 1}^{N}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty &amp;amp; ; \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные на каждой итерации ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^{(k)} - u_{i,j}^{(k-1)}|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&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;
В каждой итерации алгоритма происходит 3 основных действия описанных в п. 1.2.1:&lt;br /&gt;
*вычисление центров кластеров&lt;br /&gt;
*вычисление коэффициентов принадлежности&lt;br /&gt;
*вычисление решающей функции&lt;br /&gt;
Подробное описание макроструктур в виде кода приведено в пункте 1.5&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Схему реализации последовательного алгоритма можно описать на C++ следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FCM (X[], C, m, eps){&lt;br /&gt;
    float deside = 0;&lt;br /&gt;
    float newDeside = 0;&lt;br /&gt;
    generateMembershipDegree();            //заполняет uPrev[][] случайными нормрованными коэффициентами&lt;br /&gt;
    while (true){&lt;br /&gt;
        newDeside = deside;&lt;br /&gt;
&lt;br /&gt;
        //вычисление центров кластеров&lt;br /&gt;
        for (int j=0; j&amp;lt;C; j++){           //для каждого кластера&lt;br /&gt;
            float numerator = 0;&lt;br /&gt;
            float denumerator = 0;&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++){        //для каждого вектора&lt;br /&gt;
                numerator+=pow(u[i][j], m) * x[i];&lt;br /&gt;
                denumerator+=pow(u[i][j], m);&lt;br /&gt;
            }&lt;br /&gt;
            c[j] = numerator / denumerator;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //вычисление коэффициентов u[][]&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                sum = 0;&lt;br /&gt;
                for (int k=0; k&amp;lt;C; k++)&lt;br /&gt;
                    sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&lt;br /&gt;
                u[i][j] = 1/sum&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        //определения максимального различия между u[][] и uPrev[][]&lt;br /&gt;
        float max = 0;&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                if (abs(uPrev[i][j]-u[i][j])&amp;gt;max)&lt;br /&gt;
                    max = abs(uPrev[i][j]-u[i][j]);&lt;br /&gt;
&lt;br /&gt;
        if (eps &amp;lt;= max)&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
                for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                    uPrev[i][j]=u[i][j];&lt;br /&gt;
        else&lt;br /&gt;
            break;&lt;br /&gt;
             &lt;br /&gt;
    }&lt;br /&gt;
    return u;&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;
* параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
* набора входных векторов &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
* выбора начальных коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;&lt;br /&gt;
то в данном пункте будет приведена сложность одной итерации относительно количества входных векторов.&lt;br /&gt;
Как видно из предыдущего пункта, для вычисления центров кластеров требуется &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, для определения коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;O(C^2*|X|)&amp;lt;/math&amp;gt; операций, а для вычисления решающей функции - &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, где &amp;lt;math&amp;gt;|X|&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;O(C^2*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Как видно из пункта 1.5, на каждом действии каждой итерации алгоритма все операции, выполняющиеся в цикле, не зависят друг от друга и могут быть распаралелены. Это показано на Рисунке 1.&lt;br /&gt;
&lt;br /&gt;
[[File:FCMIG.png|thumb|center|1200px|Рисунок 1. Информационный граф алгоритма. (1)-(7) - это наборы последовательных действий (например, (2) - последовательные операции деления, взятия адреса и присваивания).]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На каждом ярусе ярусно-параллельной формы алгоритма будет располагаться конечное число элементарных операций, например, взятие адреса, сложение или возведение в степень. Информационый граф из п.1.7 изображает свёрнутую ярусно-параллельную форму алгоритма. Как видно из информационного графа, Параллельная сложность вычисления центров кластеров составляет &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;, вычисления коэффициентов принадлежности - &amp;lt;math&amp;gt;O(\log_{2} C^2*|X|)&amp;lt;/math&amp;gt;, а вычисления решающей функции - не больше чем &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом Параллельная сложность итерации алгоритма составляет &amp;lt;math&amp;gt;O(\log_{2} C^4*|X|^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Так как задачи, решаемые в макроструктурах алгоритма могут быть сведены к задачам вычисления суммы элементов массива и максимального элемента массива, то на &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом ярусе графа будет находиться &amp;lt;math&amp;gt;{N}\over{2^i}&amp;lt;/math&amp;gt; операции, где N - количество элементов массива.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - набор входных векторов&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - количество кластеров&lt;br /&gt;
* &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - матрица принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Увеличение скорости работы алгоритма при распараллеливании на бесконечном количестве процессоров составляет &amp;lt;math&amp;gt;O({{C^2*|X|}\over{\log_{2} (C^4*|X|^3)}})&amp;lt;/math&amp;gt;. Например, для разбиения 1000 элементов на 10 кластеров производительность параллельного алгоритма будет в 2315 раз больше, а на 20 кластеров - уже в 8477 раз.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&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;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4524</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4524"/>
		<updated>2016-10-04T15:56:07Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: /* Свойства алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Нечеткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(C^2*N*D*IterNumber)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: [[Участник:Demon smd|Д.А.Гуськов]] [[Участник:marina abramenkova|М.А.Абраменкова]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means Данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризируемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних для каждого вектора определяет случайным образом значения принадлежности вектора к каждому кластеру и запускает итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) Расчёт центров кластеров.&lt;br /&gt;
&lt;br /&gt;
2) Расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) Расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) Расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации.Если их разница меньше установленного значения, то алгоритм прекращает работу. Решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
J_{m} = \sum_{i = 1}^{N}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty &amp;amp; ; \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные на каждой итерации ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^{(k)} - u_{i,j}^{(k-1)}|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&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;
В каждой итерации алгоритма происходит 3 основных действия описанных в п. 1.2.1:&lt;br /&gt;
*вычисление центров кластеров&lt;br /&gt;
*вычисление коэффициентов принадлежности&lt;br /&gt;
*вычисление решающей функции&lt;br /&gt;
Подробное описание макроструктур в виде кода приведено в пункте 1.5&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Схему реализации последовательного алгоритма можно описать на C++ следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FCM (X[], C, m, eps){&lt;br /&gt;
    float deside = 0;&lt;br /&gt;
    float newDeside = 0;&lt;br /&gt;
    generateMembershipDegree();            //заполняет uPrev[][] случайными нормрованными коэффициентами&lt;br /&gt;
    while (true){&lt;br /&gt;
        newDeside = deside;&lt;br /&gt;
&lt;br /&gt;
        //вычисление центров кластеров&lt;br /&gt;
        for (int j=0; j&amp;lt;C; j++){           //для каждого кластера&lt;br /&gt;
            float numerator = 0;&lt;br /&gt;
            float denumerator = 0;&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++){        //для каждого вектора&lt;br /&gt;
                numerator+=pow(u[i][j], m) * x[i];&lt;br /&gt;
                denumerator+=pow(u[i][j], m);&lt;br /&gt;
            }&lt;br /&gt;
            c[j] = numerator / denumerator;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //вычисление коэффициентов u[][]&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                sum = 0;&lt;br /&gt;
                for (int k=0; k&amp;lt;C; k++)&lt;br /&gt;
                    sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&lt;br /&gt;
                u[i][j] = 1/sum&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        //определения максимального различия между u[][] и uPrev[][]&lt;br /&gt;
        float max = 0;&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                if (abs(uPrev[i][j]-u[i][j])&amp;gt;max)&lt;br /&gt;
                    max = abs(uPrev[i][j]-u[i][j]);&lt;br /&gt;
&lt;br /&gt;
        if (eps &amp;lt;= max)&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
                for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                    uPrev[i][j]=u[i][j];&lt;br /&gt;
        else&lt;br /&gt;
            break;&lt;br /&gt;
             &lt;br /&gt;
    }&lt;br /&gt;
    return u;&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;
* параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
* набора входных векторов &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
* выбора начальных коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;&lt;br /&gt;
то в данном пункте будет приведена сложность одной итерации относительно количества входных векторов.&lt;br /&gt;
Как видно из предыдущего пункта, для вычисления центров кластеров требуется &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, для определения коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;O(C^2*|X|)&amp;lt;/math&amp;gt; операций, а для вычисления решающей функции - &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, где &amp;lt;math&amp;gt;|X|&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;O(C^2*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Как видно из пункта 1.5, на каждом действии каждой итерации алгоритма все операции, выполняющиеся в цикле, не зависят друг от друга и могут быть распаралелены. Это показано на Рисунке 1.&lt;br /&gt;
&lt;br /&gt;
[[File:FCMIG.png|thumb|center|1200px|Рисунок 1. Информационный граф алгоритма. (1)-(7) - это наборы последовательных действий (например, (2) - последовательные операции деления, взятия адреса и присваивания).]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На каждом ярусе ярусно-параллельной формы алгоритма будет располагаться конечное число элементарных операций, например, взятие адреса, сложение или возведение в степень. Информационый граф из п.1.7 изображает свёрнутую ярусно-параллельную форму алгоритма. Как видно из информационного графа, Параллельная сложность вычисления центров кластеров составляет &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;, вычисления коэффициентов принадлежности - &amp;lt;math&amp;gt;O(\log_{2} C^2*|X|)&amp;lt;/math&amp;gt;, а вычисления решающей функции - не больше чем &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом Параллельная сложность итерации алгоритма составляет &amp;lt;math&amp;gt;O(\log_{2} C^4*|X|^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Так как задачи, решаемые в макроструктурах алгоритма могут быть сведены к задачам вычисления суммы элементов массива и максимального элемента массива, то на &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом ярусе графа будет находиться &amp;lt;math&amp;gt;{N}\over{2^i}&amp;lt;/math&amp;gt; операции, где N - количество элементов массива.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - набор входных векторов&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - количество кластеров&lt;br /&gt;
* &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - матрица принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Увеличение скорости работы алгоритма при распараллеливании на бесконечном количестве процессоров составляет &amp;lt;math&amp;gt;O({{C^2*|X|}\over{\log_{2} (C^4*|X|^3)}})&amp;lt;/math&amp;gt;. Например, для разбиения 1000 элементов на 10 кластеров производительность параллельного алгоритма будет в 2315 раз больше, а на 20 кластеров - уже в 8477 раз.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4523</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4523"/>
		<updated>2016-10-04T15:55:34Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: /* Свойства алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Нечеткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(C^2*N*D*IterNumber)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: [[Участник:Demon smd|Д.А.Гуськов]] [[Участник:marina abramenkova|М.А.Абраменкова]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means Данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризируемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних для каждого вектора определяет случайным образом значения принадлежности вектора к каждому кластеру и запускает итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) Расчёт центров кластеров.&lt;br /&gt;
&lt;br /&gt;
2) Расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) Расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) Расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации.Если их разница меньше установленного значения, то алгоритм прекращает работу. Решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
J_{m} = \sum_{i = 1}^{N}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty &amp;amp; ; \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные на каждой итерации ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^{(k)} - u_{i,j}^{(k-1)}|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&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;
В каждой итерации алгоритма происходит 3 основных действия описанных в п. 1.2.1:&lt;br /&gt;
*вычисление центров кластеров&lt;br /&gt;
*вычисление коэффициентов принадлежности&lt;br /&gt;
*вычисление решающей функции&lt;br /&gt;
Подробное описание макроструктур в виде кода приведено в пункте 1.5&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Схему реализации последовательного алгоритма можно описать на C++ следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FCM (X[], C, m, eps){&lt;br /&gt;
    float deside = 0;&lt;br /&gt;
    float newDeside = 0;&lt;br /&gt;
    generateMembershipDegree();            //заполняет uPrev[][] случайными нормрованными коэффициентами&lt;br /&gt;
    while (true){&lt;br /&gt;
        newDeside = deside;&lt;br /&gt;
&lt;br /&gt;
        //вычисление центров кластеров&lt;br /&gt;
        for (int j=0; j&amp;lt;C; j++){           //для каждого кластера&lt;br /&gt;
            float numerator = 0;&lt;br /&gt;
            float denumerator = 0;&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++){        //для каждого вектора&lt;br /&gt;
                numerator+=pow(u[i][j], m) * x[i];&lt;br /&gt;
                denumerator+=pow(u[i][j], m);&lt;br /&gt;
            }&lt;br /&gt;
            c[j] = numerator / denumerator;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //вычисление коэффициентов u[][]&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                sum = 0;&lt;br /&gt;
                for (int k=0; k&amp;lt;C; k++)&lt;br /&gt;
                    sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&lt;br /&gt;
                u[i][j] = 1/sum&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        //определения максимального различия между u[][] и uPrev[][]&lt;br /&gt;
        float max = 0;&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                if (abs(uPrev[i][j]-u[i][j])&amp;gt;max)&lt;br /&gt;
                    max = abs(uPrev[i][j]-u[i][j]);&lt;br /&gt;
&lt;br /&gt;
        if (eps &amp;lt;= max)&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
                for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                    uPrev[i][j]=u[i][j];&lt;br /&gt;
        else&lt;br /&gt;
            break;&lt;br /&gt;
             &lt;br /&gt;
    }&lt;br /&gt;
    return u;&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;
* параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
* набора входных векторов &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
* выбора начальных коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;&lt;br /&gt;
то в данном пункте будет приведена сложность одной итерации относительно количества входных векторов.&lt;br /&gt;
Как видно из предыдущего пункта, для вычисления центров кластеров требуется &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, для определения коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;O(C^2*|X|)&amp;lt;/math&amp;gt; операций, а для вычисления решающей функции - &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, где &amp;lt;math&amp;gt;|X|&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;O(C^2*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Как видно из пункта 1.5, на каждом действии каждой итерации алгоритма все операции, выполняющиеся в цикле, не зависят друг от друга и могут быть распаралелены. Это показано на Рисунке 1.&lt;br /&gt;
&lt;br /&gt;
[[File:FCMIG.png|thumb|center|1200px|Рисунок 1. Информационный граф алгоритма. (1)-(7) - это наборы последовательных действий (например, (2) - последовательные операции деления, взятия адреса и присваивания).]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На каждом ярусе ярусно-параллельной формы алгоритма будет располагаться конечное число элементарных операций, например, взятие адреса, сложение или возведение в степень. Информационый граф из п.1.7 изображает свёрнутую ярусно-параллельную форму алгоритма. Как видно из информационного графа, Параллельная сложность вычисления центров кластеров составляет &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;, вычисления коэффициентов принадлежности - &amp;lt;math&amp;gt;O(\log_{2} C^2*|X|)&amp;lt;/math&amp;gt;, а вычисления решающей функции - не больше чем &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом Параллельная сложность итерации алгоритма составляет &amp;lt;math&amp;gt;O(\log_{2} C^4*|X|^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Так как задачи, решаемые в макроструктурах алгоритма могут быть сведены к задачам вычисления суммы элементов массива и максимального элемента массива, то на &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом ярусе графа будет находиться &amp;lt;math&amp;gt;{N}\over{2^i}&amp;lt;/math&amp;gt; операции, где N - количество элементов массива.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - набор входных векторов&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - количество кластеров&lt;br /&gt;
* &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - матрица принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Увеличение скорости работы алгоритма при распараллеливании на бесконечном количестве процессоров составляет &amp;lt;math&amp;gt;O({{C^2*|X|}\over{\log_{2} C^4*|X|^3}})&amp;lt;/math&amp;gt;. Например, для разбиения 1000 элементов на 10 кластеров производительность параллельного алгоритма будет в 2315 раз больше, а на 20 кластеров - уже в 8477 раз.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4522</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4522"/>
		<updated>2016-10-04T15:55:06Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: /* Свойства алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Нечеткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(C^2*N*D*IterNumber)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: [[Участник:Demon smd|Д.А.Гуськов]] [[Участник:marina abramenkova|М.А.Абраменкова]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means Данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризируемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних для каждого вектора определяет случайным образом значения принадлежности вектора к каждому кластеру и запускает итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) Расчёт центров кластеров.&lt;br /&gt;
&lt;br /&gt;
2) Расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) Расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) Расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации.Если их разница меньше установленного значения, то алгоритм прекращает работу. Решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
J_{m} = \sum_{i = 1}^{N}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty &amp;amp; ; \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные на каждой итерации ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^{(k)} - u_{i,j}^{(k-1)}|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&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;
В каждой итерации алгоритма происходит 3 основных действия описанных в п. 1.2.1:&lt;br /&gt;
*вычисление центров кластеров&lt;br /&gt;
*вычисление коэффициентов принадлежности&lt;br /&gt;
*вычисление решающей функции&lt;br /&gt;
Подробное описание макроструктур в виде кода приведено в пункте 1.5&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Схему реализации последовательного алгоритма можно описать на C++ следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FCM (X[], C, m, eps){&lt;br /&gt;
    float deside = 0;&lt;br /&gt;
    float newDeside = 0;&lt;br /&gt;
    generateMembershipDegree();            //заполняет uPrev[][] случайными нормрованными коэффициентами&lt;br /&gt;
    while (true){&lt;br /&gt;
        newDeside = deside;&lt;br /&gt;
&lt;br /&gt;
        //вычисление центров кластеров&lt;br /&gt;
        for (int j=0; j&amp;lt;C; j++){           //для каждого кластера&lt;br /&gt;
            float numerator = 0;&lt;br /&gt;
            float denumerator = 0;&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++){        //для каждого вектора&lt;br /&gt;
                numerator+=pow(u[i][j], m) * x[i];&lt;br /&gt;
                denumerator+=pow(u[i][j], m);&lt;br /&gt;
            }&lt;br /&gt;
            c[j] = numerator / denumerator;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //вычисление коэффициентов u[][]&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                sum = 0;&lt;br /&gt;
                for (int k=0; k&amp;lt;C; k++)&lt;br /&gt;
                    sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&lt;br /&gt;
                u[i][j] = 1/sum&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        //определения максимального различия между u[][] и uPrev[][]&lt;br /&gt;
        float max = 0;&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                if (abs(uPrev[i][j]-u[i][j])&amp;gt;max)&lt;br /&gt;
                    max = abs(uPrev[i][j]-u[i][j]);&lt;br /&gt;
&lt;br /&gt;
        if (eps &amp;lt;= max)&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
                for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                    uPrev[i][j]=u[i][j];&lt;br /&gt;
        else&lt;br /&gt;
            break;&lt;br /&gt;
             &lt;br /&gt;
    }&lt;br /&gt;
    return u;&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;
* параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
* набора входных векторов &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
* выбора начальных коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;&lt;br /&gt;
то в данном пункте будет приведена сложность одной итерации относительно количества входных векторов.&lt;br /&gt;
Как видно из предыдущего пункта, для вычисления центров кластеров требуется &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, для определения коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;O(C^2*|X|)&amp;lt;/math&amp;gt; операций, а для вычисления решающей функции - &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, где &amp;lt;math&amp;gt;|X|&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;O(C^2*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Как видно из пункта 1.5, на каждом действии каждой итерации алгоритма все операции, выполняющиеся в цикле, не зависят друг от друга и могут быть распаралелены. Это показано на Рисунке 1.&lt;br /&gt;
&lt;br /&gt;
[[File:FCMIG.png|thumb|center|1200px|Рисунок 1. Информационный граф алгоритма. (1)-(7) - это наборы последовательных действий (например, (2) - последовательные операции деления, взятия адреса и присваивания).]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На каждом ярусе ярусно-параллельной формы алгоритма будет располагаться конечное число элементарных операций, например, взятие адреса, сложение или возведение в степень. Информационый граф из п.1.7 изображает свёрнутую ярусно-параллельную форму алгоритма. Как видно из информационного графа, Параллельная сложность вычисления центров кластеров составляет &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;, вычисления коэффициентов принадлежности - &amp;lt;math&amp;gt;O(\log_{2} C^2*|X|)&amp;lt;/math&amp;gt;, а вычисления решающей функции - не больше чем &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом Параллельная сложность итерации алгоритма составляет &amp;lt;math&amp;gt;O(\log_{2} C^4*|X|^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Так как задачи, решаемые в макроструктурах алгоритма могут быть сведены к задачам вычисления суммы элементов массива и максимального элемента массива, то на &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом ярусе графа будет находиться &amp;lt;math&amp;gt;{N}\over{2^i}&amp;lt;/math&amp;gt; операции, где N - количество элементов массива.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - набор входных векторов&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - количество кластеров&lt;br /&gt;
* &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - матрица принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Увеличение скорости работы алгоритма при распараллеливании на бесконечном количестве процессоров составляет &amp;lt;math&amp;gt;O({C^2*|X|}\over{\log_{2} C^4*|X|^3})&amp;lt;/math&amp;gt;. Например, для разбиения 1000 элементов на 10 кластеров производительность параллельного алгоритма будет в 2315 раз больше, а на 20 кластеров - уже в 8477 раз.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4521</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4521"/>
		<updated>2016-10-04T15:53:21Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: /* Последовательная сложность алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Нечеткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(C^2*N*D*IterNumber)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: [[Участник:Demon smd|Д.А.Гуськов]] [[Участник:marina abramenkova|М.А.Абраменкова]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means Данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризируемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних для каждого вектора определяет случайным образом значения принадлежности вектора к каждому кластеру и запускает итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) Расчёт центров кластеров.&lt;br /&gt;
&lt;br /&gt;
2) Расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) Расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) Расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации.Если их разница меньше установленного значения, то алгоритм прекращает работу. Решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
J_{m} = \sum_{i = 1}^{N}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty &amp;amp; ; \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные на каждой итерации ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^{(k)} - u_{i,j}^{(k-1)}|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&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;
В каждой итерации алгоритма происходит 3 основных действия описанных в п. 1.2.1:&lt;br /&gt;
*вычисление центров кластеров&lt;br /&gt;
*вычисление коэффициентов принадлежности&lt;br /&gt;
*вычисление решающей функции&lt;br /&gt;
Подробное описание макроструктур в виде кода приведено в пункте 1.5&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Схему реализации последовательного алгоритма можно описать на C++ следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FCM (X[], C, m, eps){&lt;br /&gt;
    float deside = 0;&lt;br /&gt;
    float newDeside = 0;&lt;br /&gt;
    generateMembershipDegree();            //заполняет uPrev[][] случайными нормрованными коэффициентами&lt;br /&gt;
    while (true){&lt;br /&gt;
        newDeside = deside;&lt;br /&gt;
&lt;br /&gt;
        //вычисление центров кластеров&lt;br /&gt;
        for (int j=0; j&amp;lt;C; j++){           //для каждого кластера&lt;br /&gt;
            float numerator = 0;&lt;br /&gt;
            float denumerator = 0;&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++){        //для каждого вектора&lt;br /&gt;
                numerator+=pow(u[i][j], m) * x[i];&lt;br /&gt;
                denumerator+=pow(u[i][j], m);&lt;br /&gt;
            }&lt;br /&gt;
            c[j] = numerator / denumerator;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //вычисление коэффициентов u[][]&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                sum = 0;&lt;br /&gt;
                for (int k=0; k&amp;lt;C; k++)&lt;br /&gt;
                    sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&lt;br /&gt;
                u[i][j] = 1/sum&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        //определения максимального различия между u[][] и uPrev[][]&lt;br /&gt;
        float max = 0;&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                if (abs(uPrev[i][j]-u[i][j])&amp;gt;max)&lt;br /&gt;
                    max = abs(uPrev[i][j]-u[i][j]);&lt;br /&gt;
&lt;br /&gt;
        if (eps &amp;lt;= max)&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
                for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                    uPrev[i][j]=u[i][j];&lt;br /&gt;
        else&lt;br /&gt;
            break;&lt;br /&gt;
             &lt;br /&gt;
    }&lt;br /&gt;
    return u;&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;
* параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
* набора входных векторов &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
* выбора начальных коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;&lt;br /&gt;
то в данном пункте будет приведена сложность одной итерации относительно количества входных векторов.&lt;br /&gt;
Как видно из предыдущего пункта, для вычисления центров кластеров требуется &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, для определения коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;O(C^2*|X|)&amp;lt;/math&amp;gt; операций, а для вычисления решающей функции - &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, где &amp;lt;math&amp;gt;|X|&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;O(C^2*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Как видно из пункта 1.5, на каждом действии каждой итерации алгоритма все операции, выполняющиеся в цикле, не зависят друг от друга и могут быть распаралелены. Это показано на Рисунке 1.&lt;br /&gt;
&lt;br /&gt;
[[File:FCMIG.png|thumb|center|1200px|Рисунок 1. Информационный граф алгоритма. (1)-(7) - это наборы последовательных действий (например, (2) - последовательные операции деления, взятия адреса и присваивания).]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На каждом ярусе ярусно-параллельной формы алгоритма будет располагаться конечное число элементарных операций, например, взятие адреса, сложение или возведение в степень. Информационый граф из п.1.7 изображает свёрнутую ярусно-параллельную форму алгоритма. Как видно из информационного графа, Параллельная сложность вычисления центров кластеров составляет &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;, вычисления коэффициентов принадлежности - &amp;lt;math&amp;gt;O(\log_{2} C^2*|X|)&amp;lt;/math&amp;gt;, а вычисления решающей функции - не больше чем &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом Параллельная сложность итерации алгоритма составляет &amp;lt;math&amp;gt;O(\log_{2} C^4*|X|^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Так как задачи, решаемые в макроструктурах алгоритма могут быть сведены к задачам вычисления суммы элементов массива и максимального элемента массива, то на &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом ярусе графа будет находиться &amp;lt;math&amp;gt;{N}\over{2^i}&amp;lt;/math&amp;gt; операции, где N - количество элементов массива.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - набор входных векторов&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - количество кластеров&lt;br /&gt;
* &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&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;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4520</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4520"/>
		<updated>2016-10-04T15:53:07Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: /* Последовательная сложность алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Нечеткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(C^2*N*D*IterNumber)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: [[Участник:Demon smd|Д.А.Гуськов]] [[Участник:marina abramenkova|М.А.Абраменкова]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means Данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризируемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних для каждого вектора определяет случайным образом значения принадлежности вектора к каждому кластеру и запускает итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) Расчёт центров кластеров.&lt;br /&gt;
&lt;br /&gt;
2) Расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) Расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) Расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации.Если их разница меньше установленного значения, то алгоритм прекращает работу. Решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
J_{m} = \sum_{i = 1}^{N}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty &amp;amp; ; \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные на каждой итерации ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^{(k)} - u_{i,j}^{(k-1)}|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&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;
В каждой итерации алгоритма происходит 3 основных действия описанных в п. 1.2.1:&lt;br /&gt;
*вычисление центров кластеров&lt;br /&gt;
*вычисление коэффициентов принадлежности&lt;br /&gt;
*вычисление решающей функции&lt;br /&gt;
Подробное описание макроструктур в виде кода приведено в пункте 1.5&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Схему реализации последовательного алгоритма можно описать на C++ следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FCM (X[], C, m, eps){&lt;br /&gt;
    float deside = 0;&lt;br /&gt;
    float newDeside = 0;&lt;br /&gt;
    generateMembershipDegree();            //заполняет uPrev[][] случайными нормрованными коэффициентами&lt;br /&gt;
    while (true){&lt;br /&gt;
        newDeside = deside;&lt;br /&gt;
&lt;br /&gt;
        //вычисление центров кластеров&lt;br /&gt;
        for (int j=0; j&amp;lt;C; j++){           //для каждого кластера&lt;br /&gt;
            float numerator = 0;&lt;br /&gt;
            float denumerator = 0;&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++){        //для каждого вектора&lt;br /&gt;
                numerator+=pow(u[i][j], m) * x[i];&lt;br /&gt;
                denumerator+=pow(u[i][j], m);&lt;br /&gt;
            }&lt;br /&gt;
            c[j] = numerator / denumerator;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //вычисление коэффициентов u[][]&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                sum = 0;&lt;br /&gt;
                for (int k=0; k&amp;lt;C; k++)&lt;br /&gt;
                    sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&lt;br /&gt;
                u[i][j] = 1/sum&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        //определения максимального различия между u[][] и uPrev[][]&lt;br /&gt;
        float max = 0;&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                if (abs(uPrev[i][j]-u[i][j])&amp;gt;max)&lt;br /&gt;
                    max = abs(uPrev[i][j]-u[i][j]);&lt;br /&gt;
&lt;br /&gt;
        if (eps &amp;lt;= max)&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
                for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                    uPrev[i][j]=u[i][j];&lt;br /&gt;
        else&lt;br /&gt;
            break;&lt;br /&gt;
             &lt;br /&gt;
    }&lt;br /&gt;
    return u;&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;
* параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
* набора входных векторов &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
* выбора начальных коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;&lt;br /&gt;
то в данном пункте будет приведена сложность одной итерации относительно количества входных векторов.&lt;br /&gt;
Как видно из предыдущего пункта, для вычисления центров кластеров требуется &amp;lt;math&amp;gt;O(2*C*N)&amp;lt;/math&amp;gt; операций, для определения коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;O(C^2*|X|)&amp;lt;/math&amp;gt; операций, а для вычисления решающей функции - &amp;lt;math&amp;gt;O(2*C*|X|)&amp;lt;/math&amp;gt; операций, где &amp;lt;math&amp;gt;|X|&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;O(C^2*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Как видно из пункта 1.5, на каждом действии каждой итерации алгоритма все операции, выполняющиеся в цикле, не зависят друг от друга и могут быть распаралелены. Это показано на Рисунке 1.&lt;br /&gt;
&lt;br /&gt;
[[File:FCMIG.png|thumb|center|1200px|Рисунок 1. Информационный граф алгоритма. (1)-(7) - это наборы последовательных действий (например, (2) - последовательные операции деления, взятия адреса и присваивания).]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На каждом ярусе ярусно-параллельной формы алгоритма будет располагаться конечное число элементарных операций, например, взятие адреса, сложение или возведение в степень. Информационый граф из п.1.7 изображает свёрнутую ярусно-параллельную форму алгоритма. Как видно из информационного графа, Параллельная сложность вычисления центров кластеров составляет &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;, вычисления коэффициентов принадлежности - &amp;lt;math&amp;gt;O(\log_{2} C^2*|X|)&amp;lt;/math&amp;gt;, а вычисления решающей функции - не больше чем &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом Параллельная сложность итерации алгоритма составляет &amp;lt;math&amp;gt;O(\log_{2} C^4*|X|^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Так как задачи, решаемые в макроструктурах алгоритма могут быть сведены к задачам вычисления суммы элементов массива и максимального элемента массива, то на &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом ярусе графа будет находиться &amp;lt;math&amp;gt;{N}\over{2^i}&amp;lt;/math&amp;gt; операции, где N - количество элементов массива.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - набор входных векторов&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - количество кластеров&lt;br /&gt;
* &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&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;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4519</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4519"/>
		<updated>2016-10-04T15:33:08Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: /* Последовательная сложность алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Нечеткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(C^2*N*D*IterNumber)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: [[Участник:Demon smd|Д.А.Гуськов]] [[Участник:marina abramenkova|М.А.Абраменкова]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means Данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризируемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних для каждого вектора определяет случайным образом значения принадлежности вектора к каждому кластеру и запускает итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) Расчёт центров кластеров.&lt;br /&gt;
&lt;br /&gt;
2) Расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) Расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) Расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации.Если их разница меньше установленного значения, то алгоритм прекращает работу. Решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
J_{m} = \sum_{i = 1}^{N}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty &amp;amp; ; \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные на каждой итерации ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^{(k)} - u_{i,j}^{(k-1)}|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&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;
В каждой итерации алгоритма происходит 3 основных действия описанных в п. 1.2.1:&lt;br /&gt;
*вычисление центров кластеров&lt;br /&gt;
*вычисление коэффициентов принадлежности&lt;br /&gt;
*вычисление решающей функции&lt;br /&gt;
Подробное описание макроструктур в виде кода приведено в пункте 1.5&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Схему реализации последовательного алгоритма можно описать на C++ следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FCM (X[], C, m, eps){&lt;br /&gt;
    float deside = 0;&lt;br /&gt;
    float newDeside = 0;&lt;br /&gt;
    generateMembershipDegree();            //заполняет uPrev[][] случайными нормрованными коэффициентами&lt;br /&gt;
    while (true){&lt;br /&gt;
        newDeside = deside;&lt;br /&gt;
&lt;br /&gt;
        //вычисление центров кластеров&lt;br /&gt;
        for (int j=0; j&amp;lt;C; j++){           //для каждого кластера&lt;br /&gt;
            float numerator = 0;&lt;br /&gt;
            float denumerator = 0;&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++){        //для каждого вектора&lt;br /&gt;
                numerator+=pow(u[i][j], m) * x[i];&lt;br /&gt;
                denumerator+=pow(u[i][j], m);&lt;br /&gt;
            }&lt;br /&gt;
            c[j] = numerator / denumerator;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //вычисление коэффициентов u[][]&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                sum = 0;&lt;br /&gt;
                for (int k=0; k&amp;lt;C; k++)&lt;br /&gt;
                    sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&lt;br /&gt;
                u[i][j] = 1/sum&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        //определения максимального различия между u[][] и uPrev[][]&lt;br /&gt;
        float max = 0;&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                if (abs(uPrev[i][j]-u[i][j])&amp;gt;max)&lt;br /&gt;
                    max = abs(uPrev[i][j]-u[i][j]);&lt;br /&gt;
&lt;br /&gt;
        if (eps &amp;lt;= max)&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
                for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                    uPrev[i][j]=u[i][j];&lt;br /&gt;
        else&lt;br /&gt;
            break;&lt;br /&gt;
             &lt;br /&gt;
    }&lt;br /&gt;
    return u;&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;
* параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
* набора входных векторов &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
* выбора начальных коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;&lt;br /&gt;
то в данном пункте будет приведена сложность одной итерации относительно количества входных векторов.&lt;br /&gt;
Как видно из предыдущего пункта, для вычисления центров кластеров требуется &amp;lt;math&amp;gt;O(2*C*N)&amp;lt;/math&amp;gt; операций, для определения коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;O(C^2*N)&amp;lt;/math&amp;gt; операций, а для вычисления решающей функции - &amp;lt;math&amp;gt;O(2*C*N)&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; - количество кластеров.&lt;br /&gt;
&lt;br /&gt;
Таким образом итоговая сложность одной итерации составляет &amp;lt;math&amp;gt;O(C^2*N)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Как видно из пункта 1.5, на каждом действии каждой итерации алгоритма все операции, выполняющиеся в цикле, не зависят друг от друга и могут быть распаралелены. Это показано на Рисунке 1.&lt;br /&gt;
&lt;br /&gt;
[[File:FCMIG.png|thumb|center|1200px|Рисунок 1. Информационный граф алгоритма. (1)-(7) - это наборы последовательных действий (например, (2) - последовательные операции деления, взятия адреса и присваивания).]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На каждом ярусе ярусно-параллельной формы алгоритма будет располагаться конечное число элементарных операций, например, взятие адреса, сложение или возведение в степень. Информационый граф из п.1.7 изображает свёрнутую ярусно-параллельную форму алгоритма. Как видно из информационного графа, Параллельная сложность вычисления центров кластеров составляет &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;, вычисления коэффициентов принадлежности - &amp;lt;math&amp;gt;O(\log_{2} C^2*|X|)&amp;lt;/math&amp;gt;, а вычисления решающей функции - не больше чем &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом Параллельная сложность итерации алгоритма составляет &amp;lt;math&amp;gt;O(\log_{2} C^4*|X|^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Так как задачи, решаемые в макроструктурах алгоритма могут быть сведены к задачам вычисления суммы элементов массива и максимального элемента массива, то на &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом ярусе графа будет находиться &amp;lt;math&amp;gt;{N}\over{2^i}&amp;lt;/math&amp;gt; операции, где N - количество элементов массива.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - набор входных векторов&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - количество кластеров&lt;br /&gt;
* &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&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;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4518</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4518"/>
		<updated>2016-10-04T15:30:16Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: /* Ресурс параллелизма алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Нечеткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(C^2*N*D*IterNumber)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: [[Участник:Demon smd|Д.А.Гуськов]] [[Участник:marina abramenkova|М.А.Абраменкова]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means Данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризируемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних для каждого вектора определяет случайным образом значения принадлежности вектора к каждому кластеру и запускает итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) Расчёт центров кластеров.&lt;br /&gt;
&lt;br /&gt;
2) Расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) Расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) Расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации.Если их разница меньше установленного значения, то алгоритм прекращает работу. Решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
J_{m} = \sum_{i = 1}^{N}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty &amp;amp; ; \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные на каждой итерации ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^{(k)} - u_{i,j}^{(k-1)}|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&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;
В каждой итерации алгоритма происходит 3 основных действия описанных в п. 1.2.1:&lt;br /&gt;
*вычисление центров кластеров&lt;br /&gt;
*вычисление коэффициентов принадлежности&lt;br /&gt;
*вычисление решающей функции&lt;br /&gt;
Подробное описание макроструктур в виде кода приведено в пункте 1.5&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Схему реализации последовательного алгоритма можно описать на C++ следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FCM (X[], C, m, eps){&lt;br /&gt;
    float deside = 0;&lt;br /&gt;
    float newDeside = 0;&lt;br /&gt;
    generateMembershipDegree();            //заполняет uPrev[][] случайными нормрованными коэффициентами&lt;br /&gt;
    while (true){&lt;br /&gt;
        newDeside = deside;&lt;br /&gt;
&lt;br /&gt;
        //вычисление центров кластеров&lt;br /&gt;
        for (int j=0; j&amp;lt;C; j++){           //для каждого кластера&lt;br /&gt;
            float numerator = 0;&lt;br /&gt;
            float denumerator = 0;&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++){        //для каждого вектора&lt;br /&gt;
                numerator+=pow(u[i][j], m) * x[i];&lt;br /&gt;
                denumerator+=pow(u[i][j], m);&lt;br /&gt;
            }&lt;br /&gt;
            c[j] = numerator / denumerator;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //вычисление коэффициентов u[][]&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                sum = 0;&lt;br /&gt;
                for (int k=0; k&amp;lt;C; k++)&lt;br /&gt;
                    sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&lt;br /&gt;
                u[i][j] = 1/sum&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        //определения максимального различия между u[][] и uPrev[][]&lt;br /&gt;
        float max = 0;&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                if (abs(uPrev[i][j]-u[i][j])&amp;gt;max)&lt;br /&gt;
                    max = abs(uPrev[i][j]-u[i][j]);&lt;br /&gt;
&lt;br /&gt;
        if (eps &amp;lt;= max)&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
                for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                    uPrev[i][j]=u[i][j];&lt;br /&gt;
        else&lt;br /&gt;
            break;&lt;br /&gt;
             &lt;br /&gt;
    }&lt;br /&gt;
    return u;&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;
* параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
* набора входных векторов &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
* выбора начальных коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;&lt;br /&gt;
то в данном пункте будет приведена сложность одной итерации относительно количества входных векторов.&lt;br /&gt;
Как видно из предыдущего пункта, для вычисления центров кластеров требуется &amp;lt;math&amp;gt;O(2*C*N)&amp;lt;/math&amp;gt; операций, для определения коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;O(C^2*N*D)&amp;lt;/math&amp;gt; операций, а для вычисления решающей функции - &amp;lt;math&amp;gt;O(2*C*N)&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;
Таким образом итоговая сложность одной итерации составляет &amp;lt;math&amp;gt;O(C^2*N*D)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Как видно из пункта 1.5, на каждом действии каждой итерации алгоритма все операции, выполняющиеся в цикле, не зависят друг от друга и могут быть распаралелены. Это показано на Рисунке 1.&lt;br /&gt;
&lt;br /&gt;
[[File:FCMIG.png|thumb|center|1200px|Рисунок 1. Информационный граф алгоритма. (1)-(7) - это наборы последовательных действий (например, (2) - последовательные операции деления, взятия адреса и присваивания).]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На каждом ярусе ярусно-параллельной формы алгоритма будет располагаться конечное число элементарных операций, например, взятие адреса, сложение или возведение в степень. Информационый граф из п.1.7 изображает свёрнутую ярусно-параллельную форму алгоритма. Как видно из информационного графа, Параллельная сложность вычисления центров кластеров составляет &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;, вычисления коэффициентов принадлежности - &amp;lt;math&amp;gt;O(\log_{2} C^2*|X|)&amp;lt;/math&amp;gt;, а вычисления решающей функции - не больше чем &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом Параллельная сложность итерации алгоритма составляет &amp;lt;math&amp;gt;O(\log_{2} C^4*|X|^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Так как задачи, решаемые в макроструктурах алгоритма могут быть сведены к задачам вычисления суммы элементов массива и максимального элемента массива, то на &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом ярусе графа будет находиться &amp;lt;math&amp;gt;{N}\over{2^i}&amp;lt;/math&amp;gt; операции, где N - количество элементов массива.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - набор входных векторов&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - количество кластеров&lt;br /&gt;
* &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&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;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4517</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4517"/>
		<updated>2016-10-04T15:23:22Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: /* Ресурс параллелизма алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Нечеткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(C^2*N*D*IterNumber)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: [[Участник:Demon smd|Д.А.Гуськов]] [[Участник:marina abramenkova|М.А.Абраменкова]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means Данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризируемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних для каждого вектора определяет случайным образом значения принадлежности вектора к каждому кластеру и запускает итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) Расчёт центров кластеров.&lt;br /&gt;
&lt;br /&gt;
2) Расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) Расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) Расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации.Если их разница меньше установленного значения, то алгоритм прекращает работу. Решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
J_{m} = \sum_{i = 1}^{N}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty &amp;amp; ; \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные на каждой итерации ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^{(k)} - u_{i,j}^{(k-1)}|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&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;
В каждой итерации алгоритма происходит 3 основных действия описанных в п. 1.2.1:&lt;br /&gt;
*вычисление центров кластеров&lt;br /&gt;
*вычисление коэффициентов принадлежности&lt;br /&gt;
*вычисление решающей функции&lt;br /&gt;
Подробное описание макроструктур в виде кода приведено в пункте 1.5&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Схему реализации последовательного алгоритма можно описать на C++ следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FCM (X[], C, m, eps){&lt;br /&gt;
    float deside = 0;&lt;br /&gt;
    float newDeside = 0;&lt;br /&gt;
    generateMembershipDegree();            //заполняет uPrev[][] случайными нормрованными коэффициентами&lt;br /&gt;
    while (true){&lt;br /&gt;
        newDeside = deside;&lt;br /&gt;
&lt;br /&gt;
        //вычисление центров кластеров&lt;br /&gt;
        for (int j=0; j&amp;lt;C; j++){           //для каждого кластера&lt;br /&gt;
            float numerator = 0;&lt;br /&gt;
            float denumerator = 0;&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++){        //для каждого вектора&lt;br /&gt;
                numerator+=pow(u[i][j], m) * x[i];&lt;br /&gt;
                denumerator+=pow(u[i][j], m);&lt;br /&gt;
            }&lt;br /&gt;
            c[j] = numerator / denumerator;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //вычисление коэффициентов u[][]&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                sum = 0;&lt;br /&gt;
                for (int k=0; k&amp;lt;C; k++)&lt;br /&gt;
                    sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&lt;br /&gt;
                u[i][j] = 1/sum&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        //определения максимального различия между u[][] и uPrev[][]&lt;br /&gt;
        float max = 0;&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                if (abs(uPrev[i][j]-u[i][j])&amp;gt;max)&lt;br /&gt;
                    max = abs(uPrev[i][j]-u[i][j]);&lt;br /&gt;
&lt;br /&gt;
        if (eps &amp;lt;= max)&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
                for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                    uPrev[i][j]=u[i][j];&lt;br /&gt;
        else&lt;br /&gt;
            break;&lt;br /&gt;
             &lt;br /&gt;
    }&lt;br /&gt;
    return u;&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;
* параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
* набора входных векторов &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
* выбора начальных коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;&lt;br /&gt;
то в данном пункте будет приведена сложность одной итерации относительно количества входных векторов.&lt;br /&gt;
Как видно из предыдущего пункта, для вычисления центров кластеров требуется &amp;lt;math&amp;gt;O(2*C*N)&amp;lt;/math&amp;gt; операций, для определения коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;O(C^2*N*D)&amp;lt;/math&amp;gt; операций, а для вычисления решающей функции - &amp;lt;math&amp;gt;O(2*C*N)&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;
Таким образом итоговая сложность одной итерации составляет &amp;lt;math&amp;gt;O(C^2*N*D)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Как видно из пункта 1.5, на каждом действии каждой итерации алгоритма все операции, выполняющиеся в цикле, не зависят друг от друга и могут быть распаралелены. Это показано на Рисунке 1.&lt;br /&gt;
&lt;br /&gt;
[[File:FCMIG.png|thumb|center|1200px|Рисунок 1. Информационный граф алгоритма. (1)-(7) - это наборы последовательных действий (например, (2) - последовательные операции деления, взятия адреса и присваивания).]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На каждом ярусе ярусно-параллельной формы алгоритма будет располагаться конечное число элементарных операций, например, взятие адреса, сложение или возведение в степень. Информационый граф из п.1.7 изображает свёрнутую ярусно-параллельную форму алгоритма. Как видно из информационного графа, Параллельная сложность вычисления центров кластеров составляет &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;, вычисления коэффициентов принадлежности - &amp;lt;math&amp;gt;O(\log_{2} C^2*|X|)&amp;lt;/math&amp;gt;, а вычисления решающей функции - не больше чем &amp;lt;math&amp;gt;O(\log_{2} C*|X|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом Параллельная сложность итерации алгоритма составляет &amp;lt;math&amp;gt;O(\log_{2} C^4*|X|^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;x_{i}&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;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&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;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4455</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4455"/>
		<updated>2016-10-02T11:56:05Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Нечеткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(C^2*N*D*IterNumber)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: [[Участник:Demon smd|Д.А.Гуськов]] [[Участник:marina abramenkova|М.А.Абраменкова]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means Данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризируемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних для каждого вектора определяет случайным образом значения принадлежности вектора к каждому кластеру и запускает итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) Расчёт центров кластеров.&lt;br /&gt;
&lt;br /&gt;
2) Расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) Расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) Расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации.Если их разница меньше установленного значения, то алгоритм прекращает работу. Решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
J_{m} = \sum_{i = 1}^{N}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty &amp;amp; ; \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные на каждой итерации ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^{(k)} - u_{i,j}^{(k-1)}|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&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;
В каждой итерации алгоритма происходит 3 основных действия описанных в п. 1.2.1:&lt;br /&gt;
*вычисление центров кластеров&lt;br /&gt;
*вычисление коэффициентов принадлежности&lt;br /&gt;
*вычисление решающей функции&lt;br /&gt;
Подробное описание макроструктур в виде кода приведено в пункте 1.5&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Схему реализации последовательного алгоритма можно описать на C++ следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FCM (X[], C, m, eps){&lt;br /&gt;
    float deside = 0;&lt;br /&gt;
    float newDeside = 0;&lt;br /&gt;
    generateMembershipDegree();            //заполняет uPrev[][] случайными нормрованными коэффициентами&lt;br /&gt;
    while (true){&lt;br /&gt;
        newDeside = deside;&lt;br /&gt;
&lt;br /&gt;
        //вычисление центров кластеров&lt;br /&gt;
        for (int j=0; j&amp;lt;C; j++){           //для каждого кластера&lt;br /&gt;
            float numerator = 0;&lt;br /&gt;
            float denumerator = 0;&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++){        //для каждого вектора&lt;br /&gt;
                numerator+=pow(u[i][j], m) * x[i];&lt;br /&gt;
                denumerator+=pow(u[i][j], m);&lt;br /&gt;
            }&lt;br /&gt;
            c[j] = numerator / denumerator;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //вычисление коэффициентов u[][]&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                sum = 0;&lt;br /&gt;
                for (int k=0; k&amp;lt;C; k++)&lt;br /&gt;
                    sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&lt;br /&gt;
                u[i][j] = 1/sum&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        //определения максимального различия между u[][] и uPrev[][]&lt;br /&gt;
        float max = 0;&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                if (abs(uPrev[i][j]-u[i][j])&amp;gt;max)&lt;br /&gt;
                    max = abs(uPrev[i][j]-u[i][j]);&lt;br /&gt;
&lt;br /&gt;
        if (eps &amp;lt;= max)&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
                for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                    uPrev[i][j]=u[i][j];&lt;br /&gt;
        else&lt;br /&gt;
            break;&lt;br /&gt;
             &lt;br /&gt;
    }&lt;br /&gt;
    return u;&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;
* параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
* набора входных векторов &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
* выбора начальных коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;&lt;br /&gt;
то в данном пункте будет приведена сложность одной итерации относительно количества входных векторов.&lt;br /&gt;
Как видно из предыдущего пункта, для вычисления центров кластеров требуется &amp;lt;math&amp;gt;O(2*C*N)&amp;lt;/math&amp;gt; операций, для определения коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;O(C^2*N*D)&amp;lt;/math&amp;gt; операций, а для вычисления решающей функции - &amp;lt;math&amp;gt;O(2*C*N)&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;
Таким образом итоговая сложность одной итерации составляет &amp;lt;math&amp;gt;O(C^2*N*D)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Как видно из пункта 1.5, на каждом действии каждой итерации алгоритма все операции, выполняющиеся в цикле, не зависят друг от друга и могут быть распаралелены. Это показано на Рисунке 1.&lt;br /&gt;
&lt;br /&gt;
[[File:FCMIG.png|thumb|center|1200px|Рисунок 1. Информационный граф алгоритма. (1)-(7) - это наборы последовательных действий (например, (2) - последовательные операции деления, взятия адреса и присваивания).]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;x_{i}&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;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&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;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4454</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4454"/>
		<updated>2016-10-02T11:55:42Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Нечеткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(C^2*N*D*IterNumber)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: [[Участник:Demon smd|Д.А.Гуськов]] [[Участник:marina abramenkova|М.А.Абраменкова]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means Данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризируемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних для каждого вектора определяет случайным образом значения принадлежности вектора к каждому кластеру и запускает итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) Расчёт центров кластеров.&lt;br /&gt;
&lt;br /&gt;
2) Расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) Расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) Расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации.Если их разница меньше установленного значения, то алгоритм прекращает работу. Решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
J_{m} = \sum_{i = 1}^{N}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty &amp;amp; ; \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные на каждой итерации ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^{(k)} - u_{i,j}^{(k-1)}|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&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;
В каждой итерации алгоритма происходит 3 основных действия описанных в п. 1.2.1:&lt;br /&gt;
*вычисление центров кластеров&lt;br /&gt;
*вычисление коэффициентов принадлежности&lt;br /&gt;
*вычисление решающей функции&lt;br /&gt;
Подробное описание макроструктур в виде кода приведено в пункте 1.5&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Схему реализации последовательного алгоритма можно описать на C++ следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FCM (X[], C, m, eps){&lt;br /&gt;
    float deside = 0;&lt;br /&gt;
    float newDeside = 0;&lt;br /&gt;
    generateMembershipDegree();            //заполняет uPrev[][] случайными нормрованными коэффициентами&lt;br /&gt;
    while (true){&lt;br /&gt;
        newDeside = deside;&lt;br /&gt;
&lt;br /&gt;
        //вычисление центров кластеров&lt;br /&gt;
        for (int j=0; j&amp;lt;C; j++){           //для каждого кластера&lt;br /&gt;
            float numerator = 0;&lt;br /&gt;
            float denumerator = 0;&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++){        //для каждого вектора&lt;br /&gt;
                numerator+=pow(u[i][j], m) * x[i];&lt;br /&gt;
                denumerator+=pow(u[i][j], m);&lt;br /&gt;
            }&lt;br /&gt;
            c[j] = numerator / denumerator;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //вычисление коэффициентов u[][]&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                sum = 0;&lt;br /&gt;
                for (int k=0; k&amp;lt;C; k++)&lt;br /&gt;
                    sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&lt;br /&gt;
                u[i][j] = 1/sum&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        //определения максимального различия между u[][] и uPrev[][]&lt;br /&gt;
        float max = 0;&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                if (abs(uPrev[i][j]-u[i][j])&amp;gt;max)&lt;br /&gt;
                    max = abs(uPrev[i][j]-u[i][j]);&lt;br /&gt;
&lt;br /&gt;
        if (eps &amp;lt;= max)&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
                for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                    uPrev[i][j]=u[i][j];&lt;br /&gt;
        else&lt;br /&gt;
            break;&lt;br /&gt;
             &lt;br /&gt;
    }&lt;br /&gt;
    return u;&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;
* параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
* набора входных векторов &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
* выбора начальных коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;&lt;br /&gt;
то в данном пункте будет приведена сложность одной итерации относительно количества входных векторов.&lt;br /&gt;
Как видно из предыдущего пункта, для вычисления центров кластеров требуется &amp;lt;math&amp;gt;O(2*C*N)&amp;lt;/math&amp;gt; операций, для определения коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;O(C^2*N*D)&amp;lt;/math&amp;gt; операций, а для вычисления решающей функции - &amp;lt;math&amp;gt;O(2*C*N)&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;
Таким образом итоговая сложность одной итерации составляет &amp;lt;math&amp;gt;O(C^2*N*D)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Как видно из пункта 1.5, на каждом действии каждой итерации алгоритма все операции, выполняющиеся в цикле, не зависят друг от друга и могут быть распаралелены. Это показано на Рисунке 1.&lt;br /&gt;
&lt;br /&gt;
[[File:FCMIG.png|thumb|center|1100px|Рисунок 1. Информационный граф алгоритма. (1)-(7) - это наборы последовательных действий (например, (2) - последовательные операции деления, взятия адреса и присваивания).]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;x_{i}&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;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&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;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4453</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4453"/>
		<updated>2016-10-02T11:51:27Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Нечеткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(C^2*N*D*IterNumber)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: [[Участник:Demon smd|Д.А.Гуськов]] [[Участник:marina abramenkova|М.А.Абраменкова]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means Данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризируемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних для каждого вектора определяет случайным образом значения принадлежности вектора к каждому кластеру и запускает итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) Расчёт центров кластеров.&lt;br /&gt;
&lt;br /&gt;
2) Расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) Расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) Расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации.Если их разница меньше установленного значения, то алгоритм прекращает работу. Решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
J_{m} = \sum_{i = 1}^{N}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty &amp;amp; ; \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные на каждой итерации ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^{(k)} - u_{i,j}^{(k-1)}|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&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;
В каждой итерации алгоритма происходит 3 основных действия описанных в п. 1.2.1:&lt;br /&gt;
*вычисление центров кластеров&lt;br /&gt;
*вычисление коэффициентов принадлежности&lt;br /&gt;
*вычисление решающей функции&lt;br /&gt;
Подробное описание макроструктур в виде кода приведено в пункте 1.5&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Схему реализации последовательного алгоритма можно описать на C++ следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FCM (X[], C, m, eps){&lt;br /&gt;
    float deside = 0;&lt;br /&gt;
    float newDeside = 0;&lt;br /&gt;
    generateMembershipDegree();            //заполняет uPrev[][] случайными нормрованными коэффициентами&lt;br /&gt;
    while (true){&lt;br /&gt;
        newDeside = deside;&lt;br /&gt;
&lt;br /&gt;
        //вычисление центров кластеров&lt;br /&gt;
        for (int j=0; j&amp;lt;C; j++){           //для каждого кластера&lt;br /&gt;
            float numerator = 0;&lt;br /&gt;
            float denumerator = 0;&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++){        //для каждого вектора&lt;br /&gt;
                numerator+=pow(u[i][j], m) * x[i];&lt;br /&gt;
                denumerator+=pow(u[i][j], m);&lt;br /&gt;
            }&lt;br /&gt;
            c[j] = numerator / denumerator;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //вычисление коэффициентов u[][]&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                sum = 0;&lt;br /&gt;
                for (int k=0; k&amp;lt;C; k++)&lt;br /&gt;
                    sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&lt;br /&gt;
                u[i][j] = 1/sum&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        //определения максимального различия между u[][] и uPrev[][]&lt;br /&gt;
        float max = 0;&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                if (abs(uPrev[i][j]-u[i][j])&amp;gt;max)&lt;br /&gt;
                    max = abs(uPrev[i][j]-u[i][j]);&lt;br /&gt;
&lt;br /&gt;
        if (eps &amp;lt;= max)&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
                for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                    uPrev[i][j]=u[i][j];&lt;br /&gt;
        else&lt;br /&gt;
            break;&lt;br /&gt;
             &lt;br /&gt;
    }&lt;br /&gt;
    return u;&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;
* параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
* набора входных векторов &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
* выбора начальных коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;&lt;br /&gt;
то в данном пункте будет приведена сложность одной итерации относительно количества входных векторов.&lt;br /&gt;
Как видно из предыдущего пункта, для вычисления центров кластеров требуется &amp;lt;math&amp;gt;O(2*C*N)&amp;lt;/math&amp;gt; операций, для определения коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;O(C^2*N*D)&amp;lt;/math&amp;gt; операций, а для вычисления решающей функции - &amp;lt;math&amp;gt;O(2*C*N)&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;
Таким образом итоговая сложность одной итерации составляет &amp;lt;math&amp;gt;O(C^2*N*D)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Как видно из пункта 1.5, на каждом действии каждой итерации алгоритма все операции, выполняющиеся в цикле, не зависят друг от друга и могут быть распаралелены. Это показано на Рисунке 1.&lt;br /&gt;
&lt;br /&gt;
[[File:FCMIG.png|thumb|center|1400px|Рисунок 1. Информационный граф алгоритма. (1)-(7) - это наборы последовательных действий (например, (2) - последовательные операции деления, взятия адреса и присваивания).]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;x_{i}&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;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&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;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4452</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4452"/>
		<updated>2016-10-02T11:51:09Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Нечеткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(C^2*N*D*IterNumber)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: [[Участник:Demon smd|Д.А.Гуськов]] [[Участник:marina abramenkova|М.А.Абраменкова]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means Данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризируемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних для каждого вектора определяет случайным образом значения принадлежности вектора к каждому кластеру и запускает итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) Расчёт центров кластеров.&lt;br /&gt;
&lt;br /&gt;
2) Расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) Расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) Расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации.Если их разница меньше установленного значения, то алгоритм прекращает работу. Решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
J_{m} = \sum_{i = 1}^{N}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty &amp;amp; ; \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные на каждой итерации ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^{(k)} - u_{i,j}^{(k-1)}|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&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;
В каждой итерации алгоритма происходит 3 основных действия описанных в п. 1.2.1:&lt;br /&gt;
*вычисление центров кластеров&lt;br /&gt;
*вычисление коэффициентов принадлежности&lt;br /&gt;
*вычисление решающей функции&lt;br /&gt;
Подробное описание макроструктур в виде кода приведено в пункте 1.5&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Схему реализации последовательного алгоритма можно описать на C++ следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FCM (X[], C, m, eps){&lt;br /&gt;
    float deside = 0;&lt;br /&gt;
    float newDeside = 0;&lt;br /&gt;
    generateMembershipDegree();            //заполняет uPrev[][] случайными нормрованными коэффициентами&lt;br /&gt;
    while (true){&lt;br /&gt;
        newDeside = deside;&lt;br /&gt;
&lt;br /&gt;
        //вычисление центров кластеров&lt;br /&gt;
        for (int j=0; j&amp;lt;C; j++){           //для каждого кластера&lt;br /&gt;
            float numerator = 0;&lt;br /&gt;
            float denumerator = 0;&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++){        //для каждого вектора&lt;br /&gt;
                numerator+=pow(u[i][j], m) * x[i];&lt;br /&gt;
                denumerator+=pow(u[i][j], m);&lt;br /&gt;
            }&lt;br /&gt;
            c[j] = numerator / denumerator;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //вычисление коэффициентов u[][]&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                sum = 0;&lt;br /&gt;
                for (int k=0; k&amp;lt;C; k++)&lt;br /&gt;
                    sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&lt;br /&gt;
                u[i][j] = 1/sum&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        //определения максимального различия между u[][] и uPrev[][]&lt;br /&gt;
        float max = 0;&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                if (abs(uPrev[i][j]-u[i][j])&amp;gt;max)&lt;br /&gt;
                    max = abs(uPrev[i][j]-u[i][j]);&lt;br /&gt;
&lt;br /&gt;
        if (eps &amp;lt;= max)&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
                for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                    uPrev[i][j]=u[i][j];&lt;br /&gt;
        else&lt;br /&gt;
            break;&lt;br /&gt;
             &lt;br /&gt;
    }&lt;br /&gt;
    return u;&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;
* параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
* набора входных векторов &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
* выбора начальных коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;&lt;br /&gt;
то в данном пункте будет приведена сложность одной итерации относительно количества входных векторов.&lt;br /&gt;
Как видно из предыдущего пункта, для вычисления центров кластеров требуется &amp;lt;math&amp;gt;O(2*C*N)&amp;lt;/math&amp;gt; операций, для определения коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;O(C^2*N*D)&amp;lt;/math&amp;gt; операций, а для вычисления решающей функции - &amp;lt;math&amp;gt;O(2*C*N)&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;
Таким образом итоговая сложность одной итерации составляет &amp;lt;math&amp;gt;O(C^2*N*D)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Как видно из пункта 1.5, на каждом действии каждой итерации алгоритма все операции, выполняющиеся в цикле, не зависят друг от друга и могут быть распаралелены. Это показано на Рисунке 1.&lt;br /&gt;
&lt;br /&gt;
[[File:FCMIG.png|thumb|center|1100px|Рисунок 1. Информационный граф алгоритма. (1)-(7) - это наборы последовательных действий (например, (2) - последовательные операции деления, взятия адреса и присваивания).]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;x_{i}&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;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&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;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4451</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4451"/>
		<updated>2016-10-02T11:50:50Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Нечеткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(C^2*N*D*IterNumber)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: [[Участник:Demon smd|Д.А.Гуськов]] [[Участник:marina abramenkova|М.А.Абраменкова]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means Данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризируемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних для каждого вектора определяет случайным образом значения принадлежности вектора к каждому кластеру и запускает итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) Расчёт центров кластеров.&lt;br /&gt;
&lt;br /&gt;
2) Расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) Расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) Расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации.Если их разница меньше установленного значения, то алгоритм прекращает работу. Решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
J_{m} = \sum_{i = 1}^{N}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty &amp;amp; ; \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные на каждой итерации ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^{(k)} - u_{i,j}^{(k-1)}|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&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;
В каждой итерации алгоритма происходит 3 основных действия описанных в п. 1.2.1:&lt;br /&gt;
*вычисление центров кластеров&lt;br /&gt;
*вычисление коэффициентов принадлежности&lt;br /&gt;
*вычисление решающей функции&lt;br /&gt;
Подробное описание макроструктур в виде кода приведено в пункте 1.5&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Схему реализации последовательного алгоритма можно описать на C++ следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FCM (X[], C, m, eps){&lt;br /&gt;
    float deside = 0;&lt;br /&gt;
    float newDeside = 0;&lt;br /&gt;
    generateMembershipDegree();            //заполняет uPrev[][] случайными нормрованными коэффициентами&lt;br /&gt;
    while (true){&lt;br /&gt;
        newDeside = deside;&lt;br /&gt;
&lt;br /&gt;
        //вычисление центров кластеров&lt;br /&gt;
        for (int j=0; j&amp;lt;C; j++){           //для каждого кластера&lt;br /&gt;
            float numerator = 0;&lt;br /&gt;
            float denumerator = 0;&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++){        //для каждого вектора&lt;br /&gt;
                numerator+=pow(u[i][j], m) * x[i];&lt;br /&gt;
                denumerator+=pow(u[i][j], m);&lt;br /&gt;
            }&lt;br /&gt;
            c[j] = numerator / denumerator;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //вычисление коэффициентов u[][]&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                sum = 0;&lt;br /&gt;
                for (int k=0; k&amp;lt;C; k++)&lt;br /&gt;
                    sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&lt;br /&gt;
                u[i][j] = 1/sum&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        //определения максимального различия между u[][] и uPrev[][]&lt;br /&gt;
        float max = 0;&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                if (abs(uPrev[i][j]-u[i][j])&amp;gt;max)&lt;br /&gt;
                    max = abs(uPrev[i][j]-u[i][j]);&lt;br /&gt;
&lt;br /&gt;
        if (eps &amp;lt;= max)&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
                for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                    uPrev[i][j]=u[i][j];&lt;br /&gt;
        else&lt;br /&gt;
            break;&lt;br /&gt;
             &lt;br /&gt;
    }&lt;br /&gt;
    return u;&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;
* параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
* набора входных векторов &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
* выбора начальных коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;&lt;br /&gt;
то в данном пункте будет приведена сложность одной итерации относительно количества входных векторов.&lt;br /&gt;
Как видно из предыдущего пункта, для вычисления центров кластеров требуется &amp;lt;math&amp;gt;O(2*C*N)&amp;lt;/math&amp;gt; операций, для определения коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;O(C^2*N*D)&amp;lt;/math&amp;gt; операций, а для вычисления решающей функции - &amp;lt;math&amp;gt;O(2*C*N)&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;
Таким образом итоговая сложность одной итерации составляет &amp;lt;math&amp;gt;O(C^2*N*D)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Как видно из пункта 1.5, на каждом действии каждой итерации алгоритма все операции, выполняющиеся в цикле, не зависят друг от друга и могут быть распаралелены. Это показано на Рисунке 1.&lt;br /&gt;
&lt;br /&gt;
[[File:FCMIG.png|thumb|center|1400px|Рисунок 1. Информационный граф алгоритма. (1)-(7) - это наборы последовательных действий (например, (2) - последовательные операции деления, взятия адреса и присваивания).]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;x_{i}&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;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&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;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4450</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4450"/>
		<updated>2016-10-02T11:50:29Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Нечеткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(C^2*N*D*IterNumber)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: [[Участник:Demon smd|Д.А.Гуськов]] [[Участник:marina abramenkova|М.А.Абраменкова]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means Данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризируемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних для каждого вектора определяет случайным образом значения принадлежности вектора к каждому кластеру и запускает итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) Расчёт центров кластеров.&lt;br /&gt;
&lt;br /&gt;
2) Расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) Расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) Расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации.Если их разница меньше установленного значения, то алгоритм прекращает работу. Решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
J_{m} = \sum_{i = 1}^{N}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty &amp;amp; ; \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные на каждой итерации ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^{(k)} - u_{i,j}^{(k-1)}|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&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;
В каждой итерации алгоритма происходит 3 основных действия описанных в п. 1.2.1:&lt;br /&gt;
*вычисление центров кластеров&lt;br /&gt;
*вычисление коэффициентов принадлежности&lt;br /&gt;
*вычисление решающей функции&lt;br /&gt;
Подробное описание макроструктур в виде кода приведено в пункте 1.5&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Схему реализации последовательного алгоритма можно описать на C++ следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FCM (X[], C, m, eps){&lt;br /&gt;
    float deside = 0;&lt;br /&gt;
    float newDeside = 0;&lt;br /&gt;
    generateMembershipDegree();            //заполняет uPrev[][] случайными нормрованными коэффициентами&lt;br /&gt;
    while (true){&lt;br /&gt;
        newDeside = deside;&lt;br /&gt;
&lt;br /&gt;
        //вычисление центров кластеров&lt;br /&gt;
        for (int j=0; j&amp;lt;C; j++){           //для каждого кластера&lt;br /&gt;
            float numerator = 0;&lt;br /&gt;
            float denumerator = 0;&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++){        //для каждого вектора&lt;br /&gt;
                numerator+=pow(u[i][j], m) * x[i];&lt;br /&gt;
                denumerator+=pow(u[i][j], m);&lt;br /&gt;
            }&lt;br /&gt;
            c[j] = numerator / denumerator;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //вычисление коэффициентов u[][]&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                sum = 0;&lt;br /&gt;
                for (int k=0; k&amp;lt;C; k++)&lt;br /&gt;
                    sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&lt;br /&gt;
                u[i][j] = 1/sum&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        //определения максимального различия между u[][] и uPrev[][]&lt;br /&gt;
        float max = 0;&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                if (abs(uPrev[i][j]-u[i][j])&amp;gt;max)&lt;br /&gt;
                    max = abs(uPrev[i][j]-u[i][j]);&lt;br /&gt;
&lt;br /&gt;
        if (eps &amp;lt;= max)&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
                for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                    uPrev[i][j]=u[i][j];&lt;br /&gt;
        else&lt;br /&gt;
            break;&lt;br /&gt;
             &lt;br /&gt;
    }&lt;br /&gt;
    return u;&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;
* параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
* набора входных векторов &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
* выбора начальных коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;&lt;br /&gt;
то в данном пункте будет приведена сложность одной итерации относительно количества входных векторов.&lt;br /&gt;
Как видно из предыдущего пункта, для вычисления центров кластеров требуется &amp;lt;math&amp;gt;O(2*C*N)&amp;lt;/math&amp;gt; операций, для определения коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;O(C^2*N*D)&amp;lt;/math&amp;gt; операций, а для вычисления решающей функции - &amp;lt;math&amp;gt;O(2*C*N)&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;
Таким образом итоговая сложность одной итерации составляет &amp;lt;math&amp;gt;O(C^2*N*D)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Как видно из пункта 1.5, на каждом действии каждой итерации алгоритма все операции, выполняющиеся в цикле, не зависят друг от друга и могут быть распаралелены. Это показано на Рисунке 1.&lt;br /&gt;
&lt;br /&gt;
[[File:FCMIG.png|thumb|center|1100px|Рисунок 1. Информационный граф алгоритма. (1)-(7) - это наборы последовательных действий (например, (2) - последовательные операции деления, взятия адреса и присваивания).]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;x_{i}&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;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&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;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4449</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4449"/>
		<updated>2016-10-02T11:47:18Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Нечеткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(C^2*N*D*IterNumber)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: [[Участник:Demon smd|Д.А.Гуськов]] [[Участник:marina abramenkova|М.А.Абраменкова]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means Данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризируемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних для каждого вектора определяет случайным образом значения принадлежности вектора к каждому кластеру и запускает итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) Расчёт центров кластеров.&lt;br /&gt;
&lt;br /&gt;
2) Расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) Расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) Расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации.Если их разница меньше установленного значения, то алгоритм прекращает работу. Решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
J_{m} = \sum_{i = 1}^{N}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty &amp;amp; ; \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные на каждой итерации ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^{(k)} - u_{i,j}^{(k-1)}|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&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;
В каждой итерации алгоритма происходит 3 основных действия описанных в п. 1.2.1:&lt;br /&gt;
*вычисление центров кластеров&lt;br /&gt;
*вычисление коэффициентов принадлежности&lt;br /&gt;
*вычисление решающей функции&lt;br /&gt;
Подробное описание макроструктур в виде кода приведено в пункте 1.5&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Схему реализации последовательного алгоритма можно описать на C++ следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FCM (X[], C, m, eps){&lt;br /&gt;
    float deside = 0;&lt;br /&gt;
    float newDeside = 0;&lt;br /&gt;
    generateMembershipDegree();            //заполняет uPrev[][] случайными нормрованными коэффициентами&lt;br /&gt;
    while (true){&lt;br /&gt;
        newDeside = deside;&lt;br /&gt;
&lt;br /&gt;
        //вычисление центров кластеров&lt;br /&gt;
        for (int j=0; j&amp;lt;C; j++){           //для каждого кластера&lt;br /&gt;
            float numerator = 0;&lt;br /&gt;
            float denumerator = 0;&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++){        //для каждого вектора&lt;br /&gt;
                numerator+=pow(u[i][j], m) * x[i];&lt;br /&gt;
                denumerator+=pow(u[i][j], m);&lt;br /&gt;
            }&lt;br /&gt;
            c[j] = numerator / denumerator;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //вычисление коэффициентов u[][]&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                sum = 0;&lt;br /&gt;
                for (int k=0; k&amp;lt;C; k++)&lt;br /&gt;
                    sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&lt;br /&gt;
                u[i][j] = 1/sum&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        //определения максимального различия между u[][] и uPrev[][]&lt;br /&gt;
        float max = 0;&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                if (abs(uPrev[i][j]-u[i][j])&amp;gt;max)&lt;br /&gt;
                    max = abs(uPrev[i][j]-u[i][j]);&lt;br /&gt;
&lt;br /&gt;
        if (eps &amp;lt;= max)&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
                for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                    uPrev[i][j]=u[i][j];&lt;br /&gt;
        else&lt;br /&gt;
            break;&lt;br /&gt;
             &lt;br /&gt;
    }&lt;br /&gt;
    return u;&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;
* параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
* набора входных векторов &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
* выбора начальных коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;&lt;br /&gt;
то в данном пункте будет приведена сложность одной итерации относительно количества входных векторов.&lt;br /&gt;
Как видно из предыдущего пункта, для вычисления центров кластеров требуется &amp;lt;math&amp;gt;O(2*C*N)&amp;lt;/math&amp;gt; операций, для определения коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;O(C^2*N*D)&amp;lt;/math&amp;gt; операций, а для вычисления решающей функции - &amp;lt;math&amp;gt;O(2*C*N)&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;
Таким образом итоговая сложность одной итерации составляет &amp;lt;math&amp;gt;O(C^2*N*D)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Как видно из пункта 1.5, на каждом действии каждой итерации алгоритма все операции, выполняющиеся в цикле, не зависят друг от друга и могут быть распаралелены. Это показано на Рисунке 1.&lt;br /&gt;
&lt;br /&gt;
[[File:1.png|thumb|center|1100px|Рисунок 1. Информационный граф алгоритма. (1)-(7) - это наборы последовательных действий (например, (2) - последовательные операции деления, взятия адреса и присваивания).]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;x_{i}&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;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&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;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4448</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4448"/>
		<updated>2016-10-02T11:45:25Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Нечеткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(C^2*N*D*IterNumber)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: [[Участник:Demon smd|Д.А.Гуськов]] [[Участник:marina abramenkova|М.А.Абраменкова]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means Данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризируемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних для каждого вектора определяет случайным образом значения принадлежности вектора к каждому кластеру и запускает итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) Расчёт центров кластеров.&lt;br /&gt;
&lt;br /&gt;
2) Расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) Расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) Расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации.Если их разница меньше установленного значения, то алгоритм прекращает работу. Решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
J_{m} = \sum_{i = 1}^{N}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty &amp;amp; ; \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные на каждой итерации ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^{(k)} - u_{i,j}^{(k-1)}|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&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;
В каждой итерации алгоритма происходит 3 основных действия описанных в п. 1.2.1:&lt;br /&gt;
*вычисление центров кластеров&lt;br /&gt;
*вычисление коэффициентов принадлежности&lt;br /&gt;
*вычисление решающей функции&lt;br /&gt;
Подробное описание макроструктур в виде кода приведено в пункте 1.5&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Схему реализации последовательного алгоритма можно описать на C++ следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FCM (X[], C, m, eps){&lt;br /&gt;
    float deside = 0;&lt;br /&gt;
    float newDeside = 0;&lt;br /&gt;
    generateMembershipDegree();            //заполняет uPrev[][] случайными нормрованными коэффициентами&lt;br /&gt;
    while (true){&lt;br /&gt;
        newDeside = deside;&lt;br /&gt;
&lt;br /&gt;
        //вычисление центров кластеров&lt;br /&gt;
        for (int j=0; j&amp;lt;C; j++){           //для каждого кластера&lt;br /&gt;
            float numerator = 0;&lt;br /&gt;
            float denumerator = 0;&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++){        //для каждого вектора&lt;br /&gt;
                numerator+=pow(u[i][j], m) * x[i];&lt;br /&gt;
                denumerator+=pow(u[i][j], m);&lt;br /&gt;
            }&lt;br /&gt;
            c[j] = numerator / denumerator;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //вычисление коэффициентов u[][]&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                sum = 0;&lt;br /&gt;
                for (int k=0; k&amp;lt;C; k++)&lt;br /&gt;
                    sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&lt;br /&gt;
                u[i][j] = 1/sum&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        //определения максимального различия между u[][] и uPrev[][]&lt;br /&gt;
        float max = 0;&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                if (abs(uPrev[i][j]-u[i][j])&amp;gt;max)&lt;br /&gt;
                    max = abs(uPrev[i][j]-u[i][j]);&lt;br /&gt;
&lt;br /&gt;
        if (eps &amp;lt;= max)&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
                for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                    uPrev[i][j]=u[i][j];&lt;br /&gt;
        else&lt;br /&gt;
            break;&lt;br /&gt;
             &lt;br /&gt;
    }&lt;br /&gt;
    return u;&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;
* параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
* набора входных векторов &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
* выбора начальных коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;&lt;br /&gt;
то в данном пункте будет приведена сложность одной итерации относительно количества входных векторов.&lt;br /&gt;
Как видно из предыдущего пункта, для вычисления центров кластеров требуется &amp;lt;math&amp;gt;O(2*C*N)&amp;lt;/math&amp;gt; операций, для определения коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;O(C^2*N*D)&amp;lt;/math&amp;gt; операций, а для вычисления решающей функции - &amp;lt;math&amp;gt;O(2*C*N)&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;
Таким образом итоговая сложность одной итерации составляет &amp;lt;math&amp;gt;O(C^2*N*D)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Как видно из пункта 1.5, на каждом действии каждой итерации алгоритма все операции, выполняющиеся в цикле, не зависят друг от друга и могут быть распаралелены. Это показано на Рисунке 1.&lt;br /&gt;
&lt;br /&gt;
[[File:1.png|thumb|center|1000px|Рисунок 1. Информационный граф алгоритма. (1)-(7) - это наборы последовательных действий (например, (2) - последовательные операции деления, взятия адреса и присваивания).]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;x_{i}&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;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&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;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4447</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4447"/>
		<updated>2016-10-02T11:44:26Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Нечеткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(C^2*N*D*IterNumber)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: [[Участник:Demon smd|Д.А.Гуськов]] [[Участник:marina abramenkova|М.А.Абраменкова]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means Данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризируемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних для каждого вектора определяет случайным образом значения принадлежности вектора к каждому кластеру и запускает итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) Расчёт центров кластеров.&lt;br /&gt;
&lt;br /&gt;
2) Расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) Расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) Расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации.Если их разница меньше установленного значения, то алгоритм прекращает работу. Решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
J_{m} = \sum_{i = 1}^{N}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty &amp;amp; ; \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные на каждой итерации ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^{(k)} - u_{i,j}^{(k-1)}|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&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;
В каждой итерации алгоритма происходит 3 основных действия описанных в п. 1.2.1:&lt;br /&gt;
*вычисление центров кластеров&lt;br /&gt;
*вычисление коэффициентов принадлежности&lt;br /&gt;
*вычисление решающей функции&lt;br /&gt;
Подробное описание макроструктур в виде кода приведено в пункте 1.5&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Схему реализации последовательного алгоритма можно описать на C++ следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FCM (X[], C, m, eps){&lt;br /&gt;
    float deside = 0;&lt;br /&gt;
    float newDeside = 0;&lt;br /&gt;
    generateMembershipDegree();            //заполняет uPrev[][] случайными нормрованными коэффициентами&lt;br /&gt;
    while (true){&lt;br /&gt;
        newDeside = deside;&lt;br /&gt;
&lt;br /&gt;
        //вычисление центров кластеров&lt;br /&gt;
        for (int j=0; j&amp;lt;C; j++){           //для каждого кластера&lt;br /&gt;
            float numerator = 0;&lt;br /&gt;
            float denumerator = 0;&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++){        //для каждого вектора&lt;br /&gt;
                numerator+=pow(u[i][j], m) * x[i];&lt;br /&gt;
                denumerator+=pow(u[i][j], m);&lt;br /&gt;
            }&lt;br /&gt;
            c[j] = numerator / denumerator;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //вычисление коэффициентов u[][]&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                sum = 0;&lt;br /&gt;
                for (int k=0; k&amp;lt;C; k++)&lt;br /&gt;
                    sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&lt;br /&gt;
                u[i][j] = 1/sum&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        //определения максимального различия между u[][] и uPrev[][]&lt;br /&gt;
        float max = 0;&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                if (abs(uPrev[i][j]-u[i][j])&amp;gt;max)&lt;br /&gt;
                    max = abs(uPrev[i][j]-u[i][j]);&lt;br /&gt;
&lt;br /&gt;
        if (eps &amp;lt;= max)&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
                for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                    uPrev[i][j]=u[i][j];&lt;br /&gt;
        else&lt;br /&gt;
            break;&lt;br /&gt;
             &lt;br /&gt;
    }&lt;br /&gt;
    return u;&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;
* параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
* набора входных векторов &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
* выбора начальных коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;&lt;br /&gt;
то в данном пункте будет приведена сложность одной итерации относительно количества входных векторов.&lt;br /&gt;
Как видно из предыдущего пункта, для вычисления центров кластеров требуется &amp;lt;math&amp;gt;O(2*C*N)&amp;lt;/math&amp;gt; операций, для определения коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;O(C^2*N*D)&amp;lt;/math&amp;gt; операций, а для вычисления решающей функции - &amp;lt;math&amp;gt;O(2*C*N)&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;
Таким образом итоговая сложность одной итерации составляет &amp;lt;math&amp;gt;O(C^2*N*D)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Как видно из пункта 1.5, на каждом действии каждой итерации алгоритма все операции, выполняющиеся в цикле, не зависят друг от друга и могут быть распаралелены. Это показано на Рисунке 1.&lt;br /&gt;
&lt;br /&gt;
[[File:1.png|thumb|center|1200px|Рисунок 1. Информационный граф алгоритма. (1)-(7) - это наборы последовательных действий (например, (2) - последовательные операции деления, взятия адреса и присваивания).]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;x_{i}&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;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&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;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4446</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4446"/>
		<updated>2016-10-02T11:40:23Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Нечеткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(C^2*N*D*IterNumber)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: [[Участник:Demon smd|Д.А.Гуськов]] [[Участник:marina abramenkova|М.А.Абраменкова]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means Данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризируемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних для каждого вектора определяет случайным образом значения принадлежности вектора к каждому кластеру и запускает итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) Расчёт центров кластеров.&lt;br /&gt;
&lt;br /&gt;
2) Расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) Расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) Расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации.Если их разница меньше установленного значения, то алгоритм прекращает работу. Решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
J_{m} = \sum_{i = 1}^{N}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty &amp;amp; ; \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные на каждой итерации ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^{(k)} - u_{i,j}^{(k-1)}|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&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;
В каждой итерации алгоритма происходит 3 основных действия описанных в п. 1.2.1:&lt;br /&gt;
*вычисление центров кластеров&lt;br /&gt;
*вычисление коэффициентов принадлежности&lt;br /&gt;
*вычисление решающей функции&lt;br /&gt;
Подробное описание макроструктур в виде кода приведено в пункте 1.5&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Схему реализации последовательного алгоритма можно описать на C++ следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
FCM (X[], C, m, eps){&lt;br /&gt;
    float deside = 0;&lt;br /&gt;
    float newDeside = 0;&lt;br /&gt;
    generateMembershipDegree();            //заполняет uPrev[][] случайными нормрованными коэффициентами&lt;br /&gt;
    while (true){&lt;br /&gt;
        newDeside = deside;&lt;br /&gt;
&lt;br /&gt;
        //вычисление центров кластеров&lt;br /&gt;
        for (int j=0; j&amp;lt;C; j++){           //для каждого кластера&lt;br /&gt;
            float numerator = 0;&lt;br /&gt;
            float denumerator = 0;&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++){        //для каждого вектора&lt;br /&gt;
                numerator+=pow(u[i][j], m) * x[i];&lt;br /&gt;
                denumerator+=pow(u[i][j], m);&lt;br /&gt;
            }&lt;br /&gt;
            c[j] = numerator / denumerator;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        //вычисление коэффициентов u[][]&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                sum = 0;&lt;br /&gt;
                for (int k=0; k&amp;lt;C; k++)&lt;br /&gt;
                    sum+= pow( dist(x[i], c[j]) / dist(x[i], c[k]), 2/(m-1));&lt;br /&gt;
                u[i][j] = 1/sum&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
        //определения максимального различия между u[][] и uPrev[][]&lt;br /&gt;
        float max = 0;&lt;br /&gt;
        for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
            for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                if (abs(uPrev[i][j]-u[i][j])&amp;gt;max)&lt;br /&gt;
                    max = abs(uPrev[i][j]-u[i][j]);&lt;br /&gt;
&lt;br /&gt;
        if (eps &amp;lt;= max)&lt;br /&gt;
            for (int i=0; i&amp;lt;X.size(); i++)    //для каждого вектора&lt;br /&gt;
                for (int j=0; j&amp;lt;C; j++){   //для каждого кластера&lt;br /&gt;
                    uPrev[i][j]=u[i][j];&lt;br /&gt;
        else&lt;br /&gt;
            break;&lt;br /&gt;
             &lt;br /&gt;
    }&lt;br /&gt;
    return u;&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;
* параметра &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
* набора входных векторов &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;&lt;br /&gt;
* выбора начальных коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;&lt;br /&gt;
то в данном пункте будет приведена сложность одной итерации относительно количества входных векторов.&lt;br /&gt;
Как видно из предыдущего пункта, для вычисления центров кластеров требуется &amp;lt;math&amp;gt;O(2*C*N)&amp;lt;/math&amp;gt; операций, для определения коэффициентов &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;O(C^2*N*D)&amp;lt;/math&amp;gt; операций, а для вычисления решающей функции - &amp;lt;math&amp;gt;O(2*C*N)&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;
Таким образом итоговая сложность одной итерации составляет &amp;lt;math&amp;gt;O(C^2*N*D)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Как видно из пункта 1.5, на каждом действии каждой итерации алгоритма все операции, выполняющиеся в цикле, не зависят друг от друга и могут быть распаралелены. Это показано на Рисунке 1.&lt;br /&gt;
&lt;br /&gt;
[[file:1.png|thumb|center|1400px|Рисунок 1. Информационный граф алгоритма.(1)-(7) - это наборы последовательных действий (например, (2) - последовательные операции деления, взятия адреса и присваивания).]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;x_{i}&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;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&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;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4352</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4352"/>
		<updated>2016-09-25T16:50:03Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: /* Вычисляемые данные */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Нечткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: [[Участник:Demon smd|Д.А.Гуськов]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means Данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризируемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних для каждого вектора определяет случайным образом значения принадлежности вектора к каждому кластеру и запускает итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) Расчёт центров кластеров.&lt;br /&gt;
&lt;br /&gt;
2) Расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) Расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) Расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации.Если их разница меньше установленного значения, то алгоритм прекращает работу. Решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
J_{m} = \sum_{i = 1}^{N}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty &amp;amp; ; \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - набор входных векторов&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - количество кластеров&lt;br /&gt;
* &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - матрица принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Евклидово расстояние от вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; до центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; рассчитывается по формуле: &amp;lt;math&amp;gt;\left\Vert{x_{i}-c_{j}}\right\|^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Нормализация всех коэффициентов принадлежности объекта производится по формуле: &amp;lt;math&amp;gt;u_{i,j} = {u_{i,j} \over \sum_{j = 1}^{C}{u_{i,j}}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^{(k)} - u_{i,j}^{(k-1)}|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - номер итерации алгоритма&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4351</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4351"/>
		<updated>2016-09-25T16:49:31Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: /* Свойства и структура алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Нечткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: [[Участник:Demon smd|Д.А.Гуськов]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means Данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризируемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, определяющий точность алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних для каждого вектора определяет случайным образом значения принадлежности вектора к каждому кластеру и запускает итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) Расчёт центров кластеров.&lt;br /&gt;
&lt;br /&gt;
2) Расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) Расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) Расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации.Если их разница меньше установленного значения, то алгоритм прекращает работу. Решающая функция возвращает сумму всех Евклидовых расстояний каждого объекта к каждому центру кластера умноженному на коэффициент принадлежности&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
J_{m} = \sum_{i = 1}^{N}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty &amp;amp; ; \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - набор входных векторов&lt;br /&gt;
* &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; - количество кластеров&lt;br /&gt;
* &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - коэффициент неопределённости&lt;br /&gt;
* &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt; - коэффициент, определяющий точность алгоритма.&lt;br /&gt;
&lt;br /&gt;
==== Выходные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - матрица принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
==== Вычисляемые данные ====&lt;br /&gt;
* Центры кластеров рассчитываются по следующей формуле: &amp;lt;math&amp;gt;c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; — коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; вектора к кластеру &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Евклидово расстояние от вектора &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; до центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; рассчитывается по формуле: &amp;lt;math&amp;gt;\left\Vert{x_{i}-c_{j}}\right\|^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Коэффициент принадлежности рассчитывается по формуле: &amp;lt;math&amp;gt;u_{i,j} = {1 \over \sum_{k = 1}^{C}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Нормализация всех коэффициентов принадлежности объекта производится по формуле: &amp;lt;math&amp;gt;u_{i,j} = {u_{i,j} \over \sum_{j = 1}^{C}{u_{i,j}}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Решающая функция рассчитывается по формуле: &amp;lt;math&amp;gt;\max_{i,j}(|u_{i,j}^(k) - u_{i,j}^(k-1)|)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - номер итерации алгоритма&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4350</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4350"/>
		<updated>2016-09-25T16:17:42Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Нечткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: [[Участник:Demon smd|Д.А.Гуськов]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means Данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризируемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, являющийся критерием останова алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних для каждого вектора определяет случайным образом значения принадлежности вектора к каждому кластеру и запускает итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) Расчёт центров кластеров.&lt;br /&gt;
&lt;br /&gt;
2) Расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) Расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) Расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации.Если их разница меньше установленного значения, то алгоритм прекращает работу.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Нечеткий алгоритм С средних минимизирует величину:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
J_{m} = \sum_{i = 1}^{N}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty &amp;amp; ; \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма.&lt;br /&gt;
&lt;br /&gt;
Входные данные алгоритма:&lt;br /&gt;
* &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - набор входных векторов&lt;br /&gt;
* &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - набор входных векторов&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
u_{i,j} = {1 \over \sum_{k = 1}^{c}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}} &amp;amp; ; \\&lt;br /&gt;
c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4349</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4349"/>
		<updated>2016-09-25T16:10:38Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: /* Свойства и структура алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Нечткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: [[Участник:Demon smd|Д.А.Гуськов]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means Данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризируемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, являющийся критерием останова алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних для каждого вектора определяет случайным образом значения принадлежности вектора к каждому кластеру и запускает итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
&lt;br /&gt;
1) Расчёт центров кластеров.&lt;br /&gt;
&lt;br /&gt;
2) Расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) Расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) Расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации.Если их разница меньше установленного значения, то алгоритм прекращает работу.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
J_{m} = \sum_{i = 1}^{N}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty &amp;amp; ; \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма по формулам:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
u_{i,j} = {1 \over \sum_{k = 1}^{c}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}} &amp;amp; ; \\&lt;br /&gt;
c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4348</id>
		<title>Участник:Demon smd/Нечеткий алгоритм С средних</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:Demon_smd/%D0%9D%D0%B5%D1%87%D0%B5%D1%82%D0%BA%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&amp;diff=4348"/>
		<updated>2016-09-25T16:08:10Z</updated>

		<summary type="html">&lt;p&gt;Demon smd: /* Общее описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Нечткий алгоритм C средних (Fuzzy C-means)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы описания алгоритма: [[Участник:Demon smd|Д.А.Гуськов]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Нечёткий алгоритм кластеризации С-средних был разработан (для случая m=2) J.C. Dunn в 1973 г. &lt;br /&gt;
&amp;lt;ref&amp;gt;Dunn, J. C. (1973-01-01). &amp;quot;A Fuzzy Relative of the ISODATA Process and Its Use in Detecting Compact Well-Separated Clusters&amp;quot;. Journal of Cybernetics. 3 (3): 32–57. doi:10.1080/01969727308546046. ISSN 0022-0280.&amp;lt;/ref&amp;gt; &lt;br /&gt;
и усовершенствован (для случая m&amp;gt;1) &lt;br /&gt;
J.C. Bezdek в 1981 г. &amp;lt;ref&amp;gt;Bezdek, James C. (1981). Pattern Recognition with Fuzzy Objective Function Algorithms. ISBN 0-306-40671-3.&amp;lt;/ref&amp;gt; &lt;br /&gt;
. В отличие от алгоритма c-means Данный метод кластеризации предполагает, что входные данные могут принадлежать более, чем одному кластеру одновременно.&lt;br /&gt;
Алгоритм получает на вход набор кластеризируемых векторов, количество кластеров, коэффициент неопределённости m и коэффициент &amp;lt;math&amp;gt;\varepsilon &amp;gt; 0&amp;lt;/math&amp;gt;, являющийся критерием останова алгоритма. На выходе алгоритма получаем матрицу вероятностей принадлежности каждого входного вектора каждому кластеру.&lt;br /&gt;
&lt;br /&gt;
Нечеткий алгоритм С средних для каждого вектора определяет случайным образом значения принадлежности вектора к каждому кластеру и запускает итерационный процесс, на каждой итерации которого происходит:&lt;br /&gt;
\begin{align}&lt;br /&gt;
1) Расчёт центров кластеров.&lt;br /&gt;
&lt;br /&gt;
2) Расчёт Евклидова расстояния от каждого вектора до центра каждого кластера &lt;br /&gt;
&lt;br /&gt;
3) Расчёт и нормализация коэффициентов принадлежности векторов кластерам&lt;br /&gt;
&lt;br /&gt;
4) Расчёт значения решающей функции и сравнение этого значения со значением решающей функции на предшествующей итерации.Если их разница меньше установленного значения, то алгоритм прекращает работу.&lt;br /&gt;
\end{align}&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
J_{m} = \sum_{i = 1}^{N}\sum_{j = 1}^{C}u_{i,j}^m\left\Vert{x_{i}-c_{j}}\right\|^2 &amp;amp; &amp;amp; , &amp;amp; &amp;amp;  1 \le m \le \infty &amp;amp; ; \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где m - это действительное число не меньше единицы, &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; - коэффициент принадлежности &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; к кластеру &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_{i}&amp;lt;/math&amp;gt; - &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый компонент &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-мерного вектора &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt;&lt;br /&gt;
- центр &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ого кластера, а &amp;lt;math&amp;gt;\left\Vert{*}\right\|&amp;lt;/math&amp;gt; - это любая норма, определяющая расстояние от вектора до центра кластера.&lt;br /&gt;
Нечёткое разбиение входных данных на кластеры производится итеративной оптимизацией вышеуказанной функции с обновлением коэффициента принадлежности &amp;lt;math&amp;gt;u_{i,j}&amp;lt;/math&amp;gt; и переопределением центра кластера &amp;lt;math&amp;gt;c_{j}&amp;lt;/math&amp;gt; на каждой итерации алгоритма по формулам:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
u_{i,j} = {1 \over \sum_{k = 1}^{c}{({\left\Vert{x_{i}-c_{j}}\right\| \over \left\Vert{x_{i}-c_{k}}\right\|})}^{2 \over m-1}} &amp;amp; ; \\&lt;br /&gt;
c_{j} = {{\sum_{i = 1}^{n}{u_{i,j}^m} * x_{i}} \over {\sum_{i = 1}^{n}{u_{i,j}^m}}}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Demon smd</name></author>
	</entry>
</feed>