<?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=Marina+abramenkova</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=Marina+abramenkova"/>
	<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/Marina_abramenkova"/>
	<updated>2026-10-22T17:09:16Z</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=21179</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=21179"/>
		<updated>2016-12-18T14:02:00Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: &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;
* параметра &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>Marina abramenkova</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=21177</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=21177"/>
		<updated>2016-12-18T14:00:38Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: /* Статья Участник:Demon_smd/Нечеткий_алгоритм_С_средних */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Статья [[Участник:Demon_smd/Нечеткий_алгоритм_С_средних]] =&lt;br /&gt;
&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;
* не указан вклад каждого автора [[Участник: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>Marina abramenkova</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=21176</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=21176"/>
		<updated>2016-12-18T14:00:02Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: /* Математическое описание алгоритма */&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;
* параметра &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>Marina abramenkova</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=21174</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=21174"/>
		<updated>2016-12-18T13:46:54Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: &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}^{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&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;
Как видно из предыдущих пунктов, масштабируется данный алгоритм хорошо. С увеличением количества процессоров время работы падает, а с увеличением количества входных данных и количества кластеров - растёт. &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>Marina abramenkova</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=21172</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=21172"/>
		<updated>2016-12-18T13:30:22Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: /* Статья Участник:Demon_smd/Нечеткий_алгоритм_С_средних */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Статья [[Участник:Demon_smd/Нечеткий_алгоритм_С_средних]] =&lt;br /&gt;
&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;
* 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;
* Пунктуация местами отсутствует в принципе. В том числе и в самом первом предложении. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 20:15, 17 декабря 2016 (MSK)&lt;br /&gt;
* Размерность входных векторов (p) не входит в сложность? Длина векторов (определена как |X| ниже) не входит в сложность? [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 20:15, 17 декабря 2016 (MSK)&lt;br /&gt;
* Где определены N и D? Во входных данных их нет. [[Участник:Chalker|Chalker]] ([[Обсуждение участника:Chalker|обсуждение]]) 20:15, 17 декабря 2016 (MSK)&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;
* не указан вклад каждого автора [[Участник: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>Marina abramenkova</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=21171</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=21171"/>
		<updated>2016-12-18T13:24:25Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: &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*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&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;
Как видно из предыдущих пунктов, масштабируется данный алгоритм хорошо. С увеличением количества процессоров время работы падает, а с увеличением количества входных данных и количества кластеров - растёт. &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>Marina abramenkova</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=21170</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=21170"/>
		<updated>2016-12-18T13:15:28Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: /* Математическое описание алгоритма */&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*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&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;
Как видно из предыдущих пунктов, масштабируется данный алгоритм хорошо. С увеличением количества процессоров время работы падает, а с увеличением количества входных данных и количества кластеров - растёт. &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>Marina abramenkova</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=21169</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=21169"/>
		<updated>2016-12-18T13:13:51Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: &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*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;
Как видно из предыдущих пунктов, масштабируется данный алгоритм хорошо. С увеличением количества процессоров время работы падает, а с увеличением количества входных данных и количества кластеров - растёт. &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>Marina abramenkova</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=20022</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=20022"/>
		<updated>2016-12-04T13:09:41Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&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*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;
Как видно из предыдущих пунктов, масштабируется данный алгоритм хорошо. С увеличением количества процессоров время работы падает, а с увеличением количества входных данных и количества кластеров - растёт. &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>Marina abramenkova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:FCMclusters_color.png&amp;diff=20021</id>
		<title>Файл:FCMclusters color.png</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:FCMclusters_color.png&amp;diff=20021"/>
		<updated>2016-12-04T13:08:50Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: Marina abramenkova загрузил новую версию Файл:FCMclusters color.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Marina abramenkova</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=20020</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=20020"/>
		<updated>2016-12-04T13:05:20Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: &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;
Как видно из предыдущих пунктов, масштабируется данный алгоритм хорошо. С увеличением количества процессоров время работы падает, а с увеличением количества входных данных и количества кластеров - растёт. &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>Marina abramenkova</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=20019</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=20019"/>
		<updated>2016-12-04T13:04:10Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&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*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;
Как видно из предыдущих пунктов, масштабируется данный алгоритм хорошо. С увеличением количества процессоров время работы падает, а с увеличением количества входных данных и количества кластеров - растёт. &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>Marina abramenkova</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=20018</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=20018"/>
		<updated>2016-12-04T13:01:56Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: /* Статья Нечеткий алгоритм С средних */&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;
*** Указали в подписях к рисункам &amp;quot;зависимость времени работы&amp;quot;&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;br /&gt;
**Указали компилятор и характеристики узлов на IBM Blue Gene/P&lt;/div&gt;</summary>
		<author><name>Marina abramenkova</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=20017</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=20017"/>
		<updated>2016-12-04T13:00:14Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: /* Масштабируемость алгоритма и его реализации */&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;
Как видно из предыдущих пунктов, масштабируется данный алгоритм хорошо. С увеличением количества процессоров время работы падает, а с увеличением количества входных данных и количества кластеров - растёт. &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>Marina abramenkova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:FCMclusters_color.png&amp;diff=20016</id>
		<title>Файл:FCMclusters color.png</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:FCMclusters_color.png&amp;diff=20016"/>
		<updated>2016-12-04T12:57:05Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Marina abramenkova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:FCMvectors_color2.png&amp;diff=20015</id>
		<title>Файл:FCMvectors color2.png</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:FCMvectors_color2.png&amp;diff=20015"/>
		<updated>2016-12-04T12:56:14Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Marina abramenkova</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=19971</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=19971"/>
		<updated>2016-12-03T10:36:25Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: /* Статья Нечеткий алгоритм С средних */&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;
*** Указали в подписях к рисункам &amp;quot;зависимость времени работы&amp;quot;&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;br /&gt;
**Указали компилятор и характеристики узлов на IBM Blue Gene/P&lt;/div&gt;</summary>
		<author><name>Marina abramenkova</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=19970</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=19970"/>
		<updated>2016-12-03T10:33:25Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: /* Масштабируемость алгоритма и его реализации */&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;
Как видно из предыдущих пунктов, масштабируется данный алгоритм хорошо. С увеличением количества процессоров время работы падает, а с увеличением количества входных данных и количества кластеров - растёт. &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_color.png|thumb|center|1280px|Рисунок 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>Marina abramenkova</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=19969</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=19969"/>
		<updated>2016-12-03T10:31:36Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: /* Масштабируемость алгоритма и его реализации */&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;
Как видно из предыдущих пунктов, масштабируется данный алгоритм хорошо. С увеличением количества процессоров время работы падает, а с увеличением количества входных данных и количества кластеров - растёт. &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.png|thumb|center|1500px|Рисунок 2. Масштабируемость алгоритма. Зависимость времени работы алгоритма от количества процессоров и входных данных при фиксированном количестве кластеров.]]&lt;br /&gt;
[[File:FCMvectors_color.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>Marina abramenkova</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=19967</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=19967"/>
		<updated>2016-12-03T09:59:25Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: /* Масштабируемость алгоритма и его реализации */&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;
Как видно из предыдущих пунктов, масштабируется данный алгоритм хорошо. С увеличением количества процессоров время работы падает, а с увеличением количества входных данных и количества кластеров - растёт. &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.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>Marina abramenkova</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=19966</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=19966"/>
		<updated>2016-12-03T09:58:11Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: /* Масштабируемость алгоритма и его реализации */&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;
Как видно из предыдущих пунктов, масштабируется данный алгоритм хорошо. С увеличением количества процессоров время работы падает, а с увеличением количества входных данных и количества кластеров - растёт. &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.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>Marina abramenkova</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=19965</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=19965"/>
		<updated>2016-12-03T09:44:36Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: /* Масштабируемость алгоритма и его реализации */&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>Marina abramenkova</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=14664</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=14664"/>
		<updated>2016-10-29T09:30:23Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: /* Статья Нечеткий алгоритм С средних */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Статья [[Нечеткий алгоритм С средних]] =&lt;br /&gt;
* не указан вклад каждого автора [[Участник:Coctic|Coctic]] ([[Обсуждение участника:Coctic|обсуждение]]) 12:58, 25 октября 2016 (MSK) - исправлено&lt;br /&gt;
* п. 1.9 не приведены оценки объема входных и выходных данных [[Участник:Coctic|Coctic]] ([[Обсуждение участника:Coctic|обсуждение]]) 12:58, 25 октября 2016 (MSK) - исправлено&lt;/div&gt;</summary>
		<author><name>Marina abramenkova</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=14663</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=14663"/>
		<updated>2016-10-29T09:29:19Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&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;|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;
[[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>Marina abramenkova</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=14661</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=14661"/>
		<updated>2016-10-29T09:27:18Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: /* Входные и выходные данные алгоритма */&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;|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;
[[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>Marina abramenkova</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=14660</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=14660"/>
		<updated>2016-10-29T09:25:07Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: /* Информационный граф */&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>Marina abramenkova</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=14657</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=14657"/>
		<updated>2016-10-29T09:20:20Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: &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>Marina abramenkova</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=14321</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=14321"/>
		<updated>2016-10-28T09:45:06Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: &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_{i}&amp;lt;/math&amp;gt; - набор из &amp;lt;math&amp;gt;k&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>Marina abramenkova</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=14320</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=14320"/>
		<updated>2016-10-28T09:06:35Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: /* Входные и выходные данные алгоритма */&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;
Авторы описания алгоритма: [[Участник: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;  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_{i}&amp;lt;/math&amp;gt; - набор из &amp;lt;math&amp;gt;k&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>Marina abramenkova</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=14319</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=14319"/>
		<updated>2016-10-28T09:04:56Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: /* Входные данные алгоритма */&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;
Авторы описания алгоритма: [[Участник: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;  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_{i}&amp;lt;/math&amp;gt; - набор из &amp;lt;math&amp;gt;k&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;
=== Свойства алгоритма ===&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>Marina abramenkova</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=7846</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=7846"/>
		<updated>2016-10-14T17:47:59Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&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*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;  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_{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;
=== Масштабируемость алгоритма и его реализации ===&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>Marina abramenkova</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:Lineprinter&amp;diff=7835</id>
		<title>Обсуждение участника:Lineprinter</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:Lineprinter&amp;diff=7835"/>
		<updated>2016-10-14T17:42:37Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Перенос ==&lt;br /&gt;
Статья: [[Алгоритм кластеризации, основанный на сетях Кохоннена]];&lt;br /&gt;
Выполняют:  Логвиненко Александра и Адиев Тохтар&lt;br /&gt;
&lt;br /&gt;
Статья: [[Ортогонализация Грама-Шмидта]];&lt;br /&gt;
Выполняют: [[Участник:KibAndrey| Кибанов Андрей]] и Аджиева Татьяна&lt;br /&gt;
&lt;br /&gt;
Статья: [[Самоорганизующиеся карты Кохонена]];&lt;br /&gt;
Выполняет: [[Участник:Anton goy| Гой Антон]]&lt;br /&gt;
&lt;br /&gt;
Статья:[[ЕМ-алгоритм_(Тематическое_моделирование)]];&lt;br /&gt;
Выполняют: Мурат Апишев и Андрей Заночкин&lt;br /&gt;
&lt;br /&gt;
Статья:[[Алгоритм_Ланцоша_с_полной_переортогонализацией]];&lt;br /&gt;
Выполняет:[[Участник:Sfedotov| Федотов С.А.]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Алгоритм_k-средних]]&lt;br /&gt;
Выполняют: [[Участник:Error2407|Богомазов Евгений]], [[Участник:Илья_Егоров|Егоров Илья]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Нечеткий_алгоритм_С_средних]]&lt;br /&gt;
Выполняют: [[Участник:Demon smd|Д.А.Гуськов]], [[Участник:marina abramenkova|М.А.Абраменкова]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Решение_задачи_Коши_для_системы_ОДУ_методом_Рунге-Кутты_4_порядка]];&lt;br /&gt;
Выполняют: [[Участник:Алимов_Дамир_Алиевич|Алимов Дамир]] и [[Участник:Anlesnichiy|Антон Лесничий]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Строгий_алгоритм_С_средних_(Hard_C-Means,_HCM)]];&lt;br /&gt;
Выполняют: [[Участник:Светлана_Лукьяненко|Лукьяненко Светлана]] и [[Участник:Юрий_Комаров|Комаров Юрий]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Алгоритм кластеризации, основанный на минимальном остовном дереве]];&lt;br /&gt;
Выполняет: [[Участник:Astandrik | Стандрик Антон Сергеевич]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Нахождение_собственных_чисел_квадратной_матрицы_методом_QR_разложения_(3)|Нахождение собственных чисел квадратной матрицы методом QR разложения (3)]];&lt;br /&gt;
Выполняют: [[Участник:Смирнова_Александра|Смирнова А.С.]], [[Участник:Александра_Киямова|Киямова А.]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Метод_Якоби_вычисления_сингулярных_чисел_и_векторов]];&lt;br /&gt;
Выполняют: [[Участница:Почернина_Елена| Почернина Елена]] и [[Участница:Светлана|Костюкова Светлана]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Метод_Ньютона_для_решения_систем_нелинейных_уравнений(2)]];&lt;br /&gt;
Выполняют: [[Участник:Oleggium|Гирняк О.Р.]], [[Участник:Dimx19|Васильков Д.А.]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Алгоритм_кластеризации_с_использованием_представлений]];&lt;br /&gt;
Выполняют: [[Участник:Cookie|Шатков С.А.]], [[Антохина Ю.А.]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Быстрое_преобразование_Фурье_(FFT)|Быстрое преобразование Фурье (FFT)]];&lt;br /&gt;
Выполняют: [[Участник:Victoria_Stepanischeva|Степанищева Виктория]] и [[Участник:Igor_Munkin|Мунькин Игорь]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Быстрое_дискретное_преобразование_Фурье|Быстрое_дискретное_преобразование_Фурье]];&lt;br /&gt;
Выполняют: [[Участник:ivanov.kir.m | К.М.Иванов]], [[Участник:Pumpkin | А.C.Сапин]]&lt;br /&gt;
&lt;br /&gt;
Статья:[[Алгоритм_k_средних]]&lt;br /&gt;
Выполняют: [[Участник:Parkhomenko|Пархоменко Павел]], [[Участник:ivan.mashonskiy|Машонский Иван]]&lt;br /&gt;
&lt;br /&gt;
Статья:[[EM-алгоритм_кластеризации]]&lt;br /&gt;
Выполняет: [[Участник:Noite|Зинченко Дмитрий]]&lt;br /&gt;
&lt;br /&gt;
Статья:[[Алгоритм_k_means]]&lt;br /&gt;
Выполняют: [[Участник:IanaV| Валуйская Яна]], [[Глотов Евгений]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Метод Якоби вычисления собственных значений симметричной матрицы ЗП |Метод Якоби вычисления собственных значений симметричной матрицы ЗП]];&lt;br /&gt;
Выполняют: [[Участник:Зиновьев Владимир|Зиновьев В.С.]], [[Участник:Пронин Андрей|Пронин А.М.]]&lt;br /&gt;
&lt;br /&gt;
Статья:[[Алгоритм_кластеризации,_основанный_на_минимальном_покрывающем_дереве]]&lt;br /&gt;
Выполняет: [[Участник:Kanast74|Дмитриева Анастасия]]&lt;br /&gt;
&lt;br /&gt;
Статья:[[Нахождение_собственных_чисел_квадратной_матрицы_методом_QR_разложения_(4)]]&lt;br /&gt;
Выполняют: [[Участник:F-morozov|Морозов Ф. В.]], [[Участник:Nataliya|Пащенко Н. Ф.]]&lt;br /&gt;
&lt;br /&gt;
Статья:[[Хранение_ненулевых_элементов_разреженных_матриц._Умножение_разреженной_матрицы_на_вектор]];&lt;br /&gt;
Выполняют: [[Участник:Trrufina|Третьякова Р.М.]] и [[Участник:Екатерина_Буторина|Буторина Е.В.]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Алгоритм_кластеризации_с_использованием_представлений2]];&lt;br /&gt;
Выполняет: [[Участник:Лукьянова Анна|Лукьянова А.Я.]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Метод Якоби вычисления собственных значений симметричной матрицы]];&lt;br /&gt;
Выполняют: [[Участник: Galkina|Галкина А.С.]], [[Участник: Игорь|Плахов И.А.]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Метод рекурсивной координатной бисекции]];&lt;br /&gt;
Выполняют: [[Участник: Obirvalger|Гордеев Михаил]], [[Участник: KolmakovEA|Колмаков Евгений]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Итерационный метод решения системы линейных алгебраических уравнений GMRES (обобщенный метод минимальных невязок)]];&lt;br /&gt;
Выполняют: [[Участник: Эльвира Ахиярова|Ахиярова Эльвира]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Хранение ненулевых элементов разреженной матрицы. Умножение разреженной матрицы на вектор]];&lt;br /&gt;
Выполняют: [[Участник: Janyell|Сычева Евгения]], [[Участник: Ahahalin|Хахалин Анатолий]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Построение матрицы Адамара произвольного размера]];&lt;br /&gt;
Выполняют: [[Участник: Бугаков Юрий|Бугаков Юрий]], Кужамалиев Ернур&lt;br /&gt;
&lt;br /&gt;
Статья: [[Вычисление определенного интеграла с использованием адаптивно сгущающейся сетки (1)]]&lt;br /&gt;
Выполняют: [[Участница:Sannikovats| Санникова Татьяна Сергеевна]], [[Участник:Plukshin| Лукшин Петр Андреевич]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Алгоритм кластеризации, основанный на построении каркаса]];&lt;br /&gt;
Выполняют: [[Участник:SenderovichNikita| Сендерович Никита]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Алгоритм кластеризации, основанный на максимизации ожидания]];&lt;br /&gt;
Выполняют: Готман Мария, Лукашкина Юлия&lt;/div&gt;</summary>
		<author><name>Marina abramenkova</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=7823</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=7823"/>
		<updated>2016-10-14T17:31:39Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: &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;  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_{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;
=== Масштабируемость алгоритма и его реализации ===&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>Marina abramenkova</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=7804</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=7804"/>
		<updated>2016-10-14T17:15:10Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: &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;  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_{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>Marina abramenkova</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=4445</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=4445"/>
		<updated>2016-10-02T11:35:59Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: /* Информационный граф */&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. Информационный граф алгоритма, где /, &amp;lt;, := - операции деления, сравнения и присваивания соответственно. (1) - это последовательный набор операций возведения в степень, умножения, сложения и  присваивания, а (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>Marina abramenkova</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=4441</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=4441"/>
		<updated>2016-10-02T10:04:36Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: /* Схема реализации последовательного алгоритма */&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;
=== Ресурс параллелизма алгоритма ===&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>Marina abramenkova</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=4440</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=4440"/>
		<updated>2016-10-02T10:04:06Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: /* Схема реализации последовательного алгоритма */&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; 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; 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; 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;
=== Ресурс параллелизма алгоритма ===&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>Marina abramenkova</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=4439</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=4439"/>
		<updated>2016-10-02T09:54:38Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: /* Схема реализации последовательного алгоритма */&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; 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; 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; 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; 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;
=== Ресурс параллелизма алгоритма ===&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>Marina abramenkova</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=4414</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=4414"/>
		<updated>2016-09-30T16:33:20Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: /* Макроструктура алгоритма */&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; 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; 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; 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; 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;
=== Ресурс параллелизма алгоритма ===&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>Marina abramenkova</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=4411</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=4411"/>
		<updated>2016-09-30T16:27:56Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: /* Вычисляемые данные на каждой итерации */&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;
=== Схема реализации последовательного алгоритма ===&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; 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; 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; 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; 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;
=== Ресурс параллелизма алгоритма ===&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>Marina abramenkova</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=4410</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=4410"/>
		<updated>2016-09-30T16:27:40Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: /* Вычисляемые данные на каждой итерации */&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;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;\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;
Схему реализации последовательного алгоритма можно описать на 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; 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; 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; 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; 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;
=== Ресурс параллелизма алгоритма ===&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>Marina abramenkova</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=4409</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=4409"/>
		<updated>2016-09-30T16:25:40Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: &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;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;
Из вышесказанного следует, что ядром алгоритма является вычисление нового центра кластеров, для каждого входного вектора вычисление Евклидова расстояния до центров кластеров, а также коэффициент принадлежности и вычисления решающей функции.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&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; 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; 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; 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; 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;
=== Ресурс параллелизма алгоритма ===&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>Marina abramenkova</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=4408</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=4408"/>
		<updated>2016-09-30T16:20:56Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: /* Последовательная сложность алгоритма */&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|Д.А.Гуськов]] [[Участник: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;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;
Из вышесказанного следует, что ядром алгоритма является вычисление нового центра кластеров, для каждого входного вектора вычисление Евклидова расстояния до центров кластеров, а также коэффициент принадлежности и вычисления решающей функции.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&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; 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; 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; 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; 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;
=== Ресурс параллелизма алгоритма ===&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>Marina abramenkova</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=4407</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=4407"/>
		<updated>2016-09-30T16:20:39Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: /* Последовательная сложность алгоритма */&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|Д.А.Гуськов]] [[Участник: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;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;
Из вышесказанного следует, что ядром алгоритма является вычисление нового центра кластеров, для каждого входного вектора вычисление Евклидова расстояния до центров кластеров, а также коэффициент принадлежности и вычисления решающей функции.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&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; 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; 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; 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; 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;
Таким образом итоговая сложность одной итерации составляет &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;
=== Ресурс параллелизма алгоритма ===&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>Marina abramenkova</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=4406</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=4406"/>
		<updated>2016-09-30T16:18:19Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: /* Последовательная сложность алгоритма */&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|Д.А.Гуськов]] [[Участник: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;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;
Из вышесказанного следует, что ядром алгоритма является вычисление нового центра кластеров, для каждого входного вектора вычисление Евклидова расстояния до центров кластеров, а также коэффициент принадлежности и вычисления решающей функции.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&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; 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; 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; 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; 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(С^{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;
Таким образом итоговая сложность одной итерации составляет &amp;lt;math&amp;gt;O(С*N*D)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &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>Marina abramenkova</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=4405</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=4405"/>
		<updated>2016-09-30T16:17:44Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: /* Последовательная сложность алгоритма */&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|Д.А.Гуськов]] [[Участник: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;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;
Из вышесказанного следует, что ядром алгоритма является вычисление нового центра кластеров, для каждого входного вектора вычисление Евклидова расстояния до центров кластеров, а также коэффициент принадлежности и вычисления решающей функции.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&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; 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; 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; 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; 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(С^{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;
Таким образом итоговая сложность одной итерации составляет &amp;lt;math&amp;gt;O(С^{2} * N * D)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &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>Marina abramenkova</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=4404</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=4404"/>
		<updated>2016-09-30T16:16:00Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: /* Последовательная сложность алгоритма */&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|Д.А.Гуськов]] [[Участник: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;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;
Из вышесказанного следует, что ядром алгоритма является вычисление нового центра кластеров, для каждого входного вектора вычисление Евклидова расстояния до центров кластеров, а также коэффициент принадлежности и вычисления решающей функции.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&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; 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; 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; 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; 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( С^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;
Таким образом итоговая сложность одной итерации составляет &amp;lt;math&amp;gt;O(С^{2}*N*D)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &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>Marina abramenkova</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=4403</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=4403"/>
		<updated>2016-09-30T16:14:39Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: /* Последовательная сложность алгоритма */&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|Д.А.Гуськов]] [[Участник: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;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;
Из вышесказанного следует, что ядром алгоритма является вычисление нового центра кластеров, для каждого входного вектора вычисление Евклидова расстояния до центров кластеров, а также коэффициент принадлежности и вычисления решающей функции.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&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; 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; 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; 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; 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(С^{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;
Таким образом итоговая сложность одной итерации составляет &amp;lt;math&amp;gt;O(С^{2}*N*D)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &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>Marina abramenkova</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=4402</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=4402"/>
		<updated>2016-09-30T16:03:26Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: /* Схема реализации последовательного алгоритма */&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|Д.А.Гуськов]] [[Участник: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;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;
Из вышесказанного следует, что ядром алгоритма является вычисление нового центра кластеров, для каждого входного вектора вычисление Евклидова расстояния до центров кластеров, а также коэффициент принадлежности и вычисления решающей функции.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&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; 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; 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; 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; 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;
Как видно из предыдущего пункта,&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;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>Marina abramenkova</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=4401</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=4401"/>
		<updated>2016-09-30T15:57:41Z</updated>

		<summary type="html">&lt;p&gt;Marina abramenkova: /* Последовательная сложность алгоритма */&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|Д.А.Гуськов]] [[Участник: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;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;
Из вышесказанного следует, что ядром алгоритма является вычисление нового центра кластеров, для каждого входного вектора вычисление Евклидова расстояния до центров кластеров, а также коэффициент принадлежности и вычисления решающей функции.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&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;
        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; 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;
        for (int i=0; i&amp;lt;X; 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;
        float max = 0;&lt;br /&gt;
        for (int i=0; i&amp;lt;X; 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; 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;
Как видно из предыдущего пункта,&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
==== Входные данные алгоритма ====&lt;br /&gt;
* &amp;lt;math&amp;gt;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>Marina abramenkova</name></author>
	</entry>
</feed>