<?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=Hromovalexander</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=Hromovalexander"/>
	<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/Hromovalexander"/>
	<updated>2026-10-22T17:18:00Z</updated>
	<subtitle>Вклад</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=22128</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=22128"/>
		<updated>2017-02-04T11:16:20Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{assignment}}&lt;br /&gt;
Автор статьи: Хромов А. К.&lt;br /&gt;
 &lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;studo&amp;quot;&amp;gt;http://studopedia.ru/7_41934_algoritm-dinamicheskoy-ierarhicheskoy-klasterizatsii-CHAMELEON.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&amp;lt;ref name=&amp;quot;chamel&amp;quot;&amp;gt;http://www-users.cs.umn.edu/~han/dmclass/chameleon.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
1. Построение графа k-ближайших соседей по исходным данным&lt;br /&gt;
&lt;br /&gt;
2. Разбиения полученного на первом этапе графа на множество подграфов. На очередной итерации выбирается максимальный подграф, для него определяется оптимальное разбиение (подробнее описано в разделе 1.2), подграф разбивается в соответсвии с данным разбиением, начинается следующая итерация. В определенный момент, когда количество вершни в максимальном подграфе становится меньше, чем некоторая изначально заданная доля от количества вершин в первоначальном графе, разбиение прекращается.&lt;br /&gt;
&lt;br /&gt;
3. Итеративно осуществляется обхединение подграфов, на основе метрик взаимной связности и взаимного сходства. Процесс объединения завершается в момент достижения целевых показателей по данным метрикам.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:Инфограф.png]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
На первом этапе вычисление &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших вершин для &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й вершины можно распараллелить между &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; процессами (это вычисление независимо для каждой вершины).&lt;br /&gt;
На втором и третьем этапах процессы разбиения и объединения подграфов происходят последовательно.&lt;br /&gt;
Получаем оценку параллельной сложности алгоритма &amp;lt;math&amp;gt;O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
На вход алгоритму подается множество из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов длины &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt;, описывающих объекты для кластеризации.&lt;br /&gt;
Также передаются параметры &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (для построения графа k ближайших соседей на первом этапе) и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; (используется на втором этапе для определения критерия прекращения итерационного процесса).&lt;br /&gt;
На выходе алгоритм выдает массив длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, заполненный числами от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, показывающими, в какой кластер попал соответствующий объект.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Первый этап алгоритма хорошо распараллеливается (так как нахождение &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;
&amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для первого этапа &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;O(\frac{nm}{n^2+m^2})&amp;lt;/math&amp;gt; для второго этапа&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;O(\frac{m^2log(m)}{m^2+n})&amp;lt;/math&amp;gt; для третьего этапа&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1-й этап алгоритма детерминирован (граф &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;
Реализации алгоритма Chameleon для систем с распределенной памятью найдено не было, но была найдена параллельная реализация для систем с общей памятью &amp;lt;ref name=&amp;quot;real&amp;quot;&amp;gt;http://research.ijcaonline.org/volume79/number8/pxc3891600.pdf&amp;lt;/ref&amp;gt;. Для данной реализации авторы приводят информацию о производительности, но не приводят исходный код программы. По этой причине была исследована масштабируемость алгоритма в зависимости от количества точек для кластеризации для реализации в пределах одного узла для реализации &amp;lt;ref name=&amp;quot;rel_code&amp;quot;&amp;gt;http://www.codeforge.com/article/192925&amp;lt;/ref&amp;gt;. Запуск программы осуществлялся на вычислительном комплексе IBM Blue Gene/P на одном узле. Характеристики узла приведены по ссылке &amp;lt;ref name=&amp;quot;har&amp;quot;&amp;gt;http://hpc.cmc.msu.ru/bgp&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Далее приведены графики зависимости времени работы программы от размера входных данных. Графики для 4-х и 8 процессов оценочны.&lt;br /&gt;
&lt;br /&gt;
[[Файл:718bad6be0fe40419c7ad15675f079f4.png|600px]]&lt;br /&gt;
&lt;br /&gt;
Эффективность алгоритма убывает с ростом числа процессов. Темпы убывания эффективности растут с ростом размера входных данных.&lt;br /&gt;
&lt;br /&gt;
===Динамические характеристики и эффективность реализации алгоритма===&lt;br /&gt;
===Выводы для классов архитектур===&lt;br /&gt;
===Существующие реализации алгоритма===&lt;br /&gt;
Одна из последовательных реализаций алгоритма находится по ссылке [http://codeforge.com/article/192925]&lt;br /&gt;
&lt;br /&gt;
Параллельных реализаций алгоритма найдено не было&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=22112</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=22112"/>
		<updated>2017-02-03T15:06:55Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{assignment}}&lt;br /&gt;
Автор статьи: Хромов А. К.&lt;br /&gt;
 &lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;studo&amp;quot;&amp;gt;http://studopedia.ru/7_41934_algoritm-dinamicheskoy-ierarhicheskoy-klasterizatsii-CHAMELEON.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&amp;lt;ref name=&amp;quot;chamel&amp;quot;&amp;gt;http://www-users.cs.umn.edu/~han/dmclass/chameleon.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
1. Построение графа k-ближайших соседей по исходным данным&lt;br /&gt;
&lt;br /&gt;
2. Разбиения полученного на первом этапе графа на множество подграфов. На очередной итерации выбирается максимальный подграф, для него определяется оптимальное разбиение (подробнее описано в разделе 1.2), подграф разбивается в соответсвии с данным разбиением, начинается следующая итерация. В определенный момент, когда количество вершни в максимальном подграфе становится меньше, чем некоторая изначально заданная доля от количества вершин в первоначальном графе, разбиение прекращается.&lt;br /&gt;
&lt;br /&gt;
3. Итеративно осуществляется обхединение подграфов, на основе метрик взаимной связности и взаимного сходства. Процесс объединения завершается в момент достижения целевых показателей по данным метрикам.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:Инфограф.png]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
На первом этапе вычисление &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших вершин для &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й вершины можно распараллелить между &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; процессами (это вычисление независимо для каждой вершины).&lt;br /&gt;
На втором и третьем этапах процессы разбиения и объединения подграфов происходят последовательно.&lt;br /&gt;
Получаем оценку параллельной сложности алгоритма &amp;lt;math&amp;gt;O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
На вход алгоритму подается множество из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов длины &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt;, описывающих объекты для кластеризации.&lt;br /&gt;
Также передаются параметры &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (для построения графа k ближайших соседей на первом этапе) и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; (используется на втором этапе для определения критерия прекращения итерационного процесса).&lt;br /&gt;
На выходе алгоритм выдает массив длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, заполненный числами от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, показывающими, в какой кластер попал соответствующий объект.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Первый этап алгоритма хорошо распараллеливается (так как нахождение &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;
&amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для первого этапа &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;O(\frac{nm}{n^2+m^2})&amp;lt;/math&amp;gt; для второго этапа&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;O(\frac{m^2log(m)}{m^2+n})&amp;lt;/math&amp;gt; для третьего этапа&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1-й этап алгоритма детерминирован (граф &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;
[[Файл:Chameleo.png|300px]]&lt;br /&gt;
&lt;br /&gt;
На приведенном графике видна зависимость эффективности от объема данных и числа процессоров для реализации алгоритма, описанной в &amp;lt;ref name=&amp;quot;real&amp;quot;&amp;gt;http://research.ijcaonline.org/volume79/number8/pxc3891600.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
График построен для экспериментальной версии алгоритма для малого числа потоков.&lt;br /&gt;
Для тестирования использовался процессор Intel Pentium IV для одного потока, Intel Core i5 для 4-х потоков и Intel Core i7 для 8 потоков.&lt;br /&gt;
&lt;br /&gt;
Для набора из 8000 точек запуск на 8 потоках даёт ускорение 4,46x по сравнению с запуском на 1 потоке.&lt;br /&gt;
Для набора из 10000 точек запуск на 8 процессорах даёт ускорение 4,8x по сравнению с запуском на 1 процессоре.&lt;br /&gt;
Для набора из 20000 точек запуск на 8 процессорах даёт ускорение 5x по сравнению с запуском на 1 процессоре.&lt;br /&gt;
&lt;br /&gt;
Эффективность алгоритма падает при увеличении числа потоков (при увеличении числа потоков в 8 раз ускорение составляет ориентировочно 4-5x, то есть эффективность падает практически вдвое)&lt;br /&gt;
&lt;br /&gt;
===Динамические характеристики и эффективность реализации алгоритма===&lt;br /&gt;
===Выводы для классов архитектур===&lt;br /&gt;
===Существующие реализации алгоритма===&lt;br /&gt;
Одна из последовательных реализаций алгоритма находится по ссылке [http://codeforge.com/article/192925]&lt;br /&gt;
&lt;br /&gt;
Параллельных реализаций алгоритма найдено не было&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=22100</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=22100"/>
		<updated>2017-02-03T14:43:16Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{assignment}}&lt;br /&gt;
Автор статьи: Хромов А. К.&lt;br /&gt;
 &lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;studo&amp;quot;&amp;gt;http://studopedia.ru/7_41934_algoritm-dinamicheskoy-ierarhicheskoy-klasterizatsii-CHAMELEON.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&amp;lt;ref name=&amp;quot;chamel&amp;quot;&amp;gt;http://www-users.cs.umn.edu/~han/dmclass/chameleon.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
1. Построение графа k-ближайших соседей по исходным данным&lt;br /&gt;
&lt;br /&gt;
2. Разбиения полученного на первом этапе графа на множество подграфов. На очередной итерации выбирается максимальный подграф, для него определяется оптимальное разбиение (подробнее описано в разделе 1.2), подграф разбивается в соответсвии с данным разбиением, начинается следующая итерация. В определенный момент, когда количество вершни в максимальном подграфе становится меньше, чем некоторая изначально заданная доля от количества вершин в первоначальном графе, разбиение прекращается.&lt;br /&gt;
&lt;br /&gt;
3. Итеративно осуществляется обхединение подграфов, на основе метрик взаимной связности и взаимного сходства. Процесс объединения завершается в момент достижения целевых показателей по данным метрикам.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:Инфограф.png]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
На первом этапе вычисление &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших вершин для &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й вершины можно распараллелить между &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; процессами (это вычисление независимо для каждой вершины).&lt;br /&gt;
На втором и третьем этапах процессы разбиения и объединения подграфов происходят последовательно.&lt;br /&gt;
Получаем оценку параллельной сложности алгоритма &amp;lt;math&amp;gt;O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
На вход алгоритму подается множество из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов длины &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt;, описывающих объекты для кластеризации.&lt;br /&gt;
Также передаются параметры &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (для построения графа k ближайших соседей на первом этапе) и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; (используется на втором этапе для определения критерия прекращения итерационного процесса).&lt;br /&gt;
На выходе алгоритм выдает массив длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, заполненный числами от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, показывающими, в какой кластер попал соответствующий объект.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Первый этап алгоритма хорошо распараллеливается (так как нахождение &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;
&amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для первого этапа &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;O(\frac{nm}{n^2+m^2})&amp;lt;/math&amp;gt; для второго этапа&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;O(\frac{m^2log(m)}{m^2+n})&amp;lt;/math&amp;gt; для третьего этапа&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1-й этап алгоритма детерминирован (граф &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;
[[Файл:Chameleo.png|300px]]&lt;br /&gt;
&lt;br /&gt;
На приведенном графике видна зависимость эффективности от объема данных и числа процессоров для реализации алгоритма, описанной в &amp;lt;ref name=&amp;quot;real&amp;quot;&amp;gt;http://research.ijcaonline.org/volume79/number8/pxc3891600.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
График построен для экспериментальной версии алгоритма для малого числа потоков.&lt;br /&gt;
Для тестирования использовался процессор Intel Pentium IV для одного потока, Intel Core i5 для 4-х потоков и Intel Core i7 для 8 потоков.&lt;br /&gt;
&lt;br /&gt;
К сожалению, в исследовании, на основе которого строится данный график, не приведены более подробные данные о том, как именно запускались тесты. Приводится только информация о процессорах, на которых выполнялись вычисления. Также в исследовании не приведён запускавшийся код. Вместе с тем, данное исследование является единственным, опирающимся на параллельный код и приводящее результаты запуска данного кода. Других параллельных реализаций найдено не было.&lt;br /&gt;
&lt;br /&gt;
Для набора из 8000 точек запуск на 8 потоках даёт ускорение 4,46x по сравнению с запуском на 1 потоке.&lt;br /&gt;
Для набора из 10000 точек запуск на 8 процессорах даёт ускорение 4,8x по сравнению с запуском на 1 процессоре.&lt;br /&gt;
Для набора из 20000 точек запуск на 8 процессорах даёт ускорение 5x по сравнению с запуском на 1 процессоре.&lt;br /&gt;
&lt;br /&gt;
Эффективность алгоритма падает при увеличении числа потоков (при увеличении числа потоков в 8 раз ускорение составляет ориентировочно 4-5x, то есть эффективность падает практически вдвое)&lt;br /&gt;
&lt;br /&gt;
===Динамические характеристики и эффективность реализации алгоритма===&lt;br /&gt;
===Выводы для классов архитектур===&lt;br /&gt;
===Существующие реализации алгоритма===&lt;br /&gt;
Одна из последовательных реализаций алгоритма находится по ссылке [http://codeforge.com/article/192925]&lt;br /&gt;
&lt;br /&gt;
Параллельных реализаций алгоритма найдено не было&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=22099</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=22099"/>
		<updated>2017-02-03T14:43:10Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{assignment}&lt;br /&gt;
Автор статьи: Хромов А. К.&lt;br /&gt;
 &lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;studo&amp;quot;&amp;gt;http://studopedia.ru/7_41934_algoritm-dinamicheskoy-ierarhicheskoy-klasterizatsii-CHAMELEON.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&amp;lt;ref name=&amp;quot;chamel&amp;quot;&amp;gt;http://www-users.cs.umn.edu/~han/dmclass/chameleon.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
1. Построение графа k-ближайших соседей по исходным данным&lt;br /&gt;
&lt;br /&gt;
2. Разбиения полученного на первом этапе графа на множество подграфов. На очередной итерации выбирается максимальный подграф, для него определяется оптимальное разбиение (подробнее описано в разделе 1.2), подграф разбивается в соответсвии с данным разбиением, начинается следующая итерация. В определенный момент, когда количество вершни в максимальном подграфе становится меньше, чем некоторая изначально заданная доля от количества вершин в первоначальном графе, разбиение прекращается.&lt;br /&gt;
&lt;br /&gt;
3. Итеративно осуществляется обхединение подграфов, на основе метрик взаимной связности и взаимного сходства. Процесс объединения завершается в момент достижения целевых показателей по данным метрикам.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:Инфограф.png]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
На первом этапе вычисление &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших вершин для &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й вершины можно распараллелить между &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; процессами (это вычисление независимо для каждой вершины).&lt;br /&gt;
На втором и третьем этапах процессы разбиения и объединения подграфов происходят последовательно.&lt;br /&gt;
Получаем оценку параллельной сложности алгоритма &amp;lt;math&amp;gt;O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
На вход алгоритму подается множество из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов длины &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt;, описывающих объекты для кластеризации.&lt;br /&gt;
Также передаются параметры &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (для построения графа k ближайших соседей на первом этапе) и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; (используется на втором этапе для определения критерия прекращения итерационного процесса).&lt;br /&gt;
На выходе алгоритм выдает массив длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, заполненный числами от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, показывающими, в какой кластер попал соответствующий объект.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Первый этап алгоритма хорошо распараллеливается (так как нахождение &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;
&amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для первого этапа &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;O(\frac{nm}{n^2+m^2})&amp;lt;/math&amp;gt; для второго этапа&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;O(\frac{m^2log(m)}{m^2+n})&amp;lt;/math&amp;gt; для третьего этапа&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1-й этап алгоритма детерминирован (граф &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;
[[Файл:Chameleo.png|300px]]&lt;br /&gt;
&lt;br /&gt;
На приведенном графике видна зависимость эффективности от объема данных и числа процессоров для реализации алгоритма, описанной в &amp;lt;ref name=&amp;quot;real&amp;quot;&amp;gt;http://research.ijcaonline.org/volume79/number8/pxc3891600.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
График построен для экспериментальной версии алгоритма для малого числа потоков.&lt;br /&gt;
Для тестирования использовался процессор Intel Pentium IV для одного потока, Intel Core i5 для 4-х потоков и Intel Core i7 для 8 потоков.&lt;br /&gt;
&lt;br /&gt;
К сожалению, в исследовании, на основе которого строится данный график, не приведены более подробные данные о том, как именно запускались тесты. Приводится только информация о процессорах, на которых выполнялись вычисления. Также в исследовании не приведён запускавшийся код. Вместе с тем, данное исследование является единственным, опирающимся на параллельный код и приводящее результаты запуска данного кода. Других параллельных реализаций найдено не было.&lt;br /&gt;
&lt;br /&gt;
Для набора из 8000 точек запуск на 8 потоках даёт ускорение 4,46x по сравнению с запуском на 1 потоке.&lt;br /&gt;
Для набора из 10000 точек запуск на 8 процессорах даёт ускорение 4,8x по сравнению с запуском на 1 процессоре.&lt;br /&gt;
Для набора из 20000 точек запуск на 8 процессорах даёт ускорение 5x по сравнению с запуском на 1 процессоре.&lt;br /&gt;
&lt;br /&gt;
Эффективность алгоритма падает при увеличении числа потоков (при увеличении числа потоков в 8 раз ускорение составляет ориентировочно 4-5x, то есть эффективность падает практически вдвое)&lt;br /&gt;
&lt;br /&gt;
===Динамические характеристики и эффективность реализации алгоритма===&lt;br /&gt;
===Выводы для классов архитектур===&lt;br /&gt;
===Существующие реализации алгоритма===&lt;br /&gt;
Одна из последовательных реализаций алгоритма находится по ссылке [http://codeforge.com/article/192925]&lt;br /&gt;
&lt;br /&gt;
Параллельных реализаций алгоритма найдено не было&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=22098</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=22098"/>
		<updated>2017-02-03T14:42:02Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{assigned}&lt;br /&gt;
Автор статьи: Хромов А. К.&lt;br /&gt;
 &lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;studo&amp;quot;&amp;gt;http://studopedia.ru/7_41934_algoritm-dinamicheskoy-ierarhicheskoy-klasterizatsii-CHAMELEON.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&amp;lt;ref name=&amp;quot;chamel&amp;quot;&amp;gt;http://www-users.cs.umn.edu/~han/dmclass/chameleon.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
1. Построение графа k-ближайших соседей по исходным данным&lt;br /&gt;
&lt;br /&gt;
2. Разбиения полученного на первом этапе графа на множество подграфов. На очередной итерации выбирается максимальный подграф, для него определяется оптимальное разбиение (подробнее описано в разделе 1.2), подграф разбивается в соответсвии с данным разбиением, начинается следующая итерация. В определенный момент, когда количество вершни в максимальном подграфе становится меньше, чем некоторая изначально заданная доля от количества вершин в первоначальном графе, разбиение прекращается.&lt;br /&gt;
&lt;br /&gt;
3. Итеративно осуществляется обхединение подграфов, на основе метрик взаимной связности и взаимного сходства. Процесс объединения завершается в момент достижения целевых показателей по данным метрикам.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:Инфограф.png]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
На первом этапе вычисление &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших вершин для &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й вершины можно распараллелить между &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; процессами (это вычисление независимо для каждой вершины).&lt;br /&gt;
На втором и третьем этапах процессы разбиения и объединения подграфов происходят последовательно.&lt;br /&gt;
Получаем оценку параллельной сложности алгоритма &amp;lt;math&amp;gt;O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
На вход алгоритму подается множество из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов длины &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt;, описывающих объекты для кластеризации.&lt;br /&gt;
Также передаются параметры &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (для построения графа k ближайших соседей на первом этапе) и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; (используется на втором этапе для определения критерия прекращения итерационного процесса).&lt;br /&gt;
На выходе алгоритм выдает массив длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, заполненный числами от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, показывающими, в какой кластер попал соответствующий объект.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Первый этап алгоритма хорошо распараллеливается (так как нахождение &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;
&amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для первого этапа &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;O(\frac{nm}{n^2+m^2})&amp;lt;/math&amp;gt; для второго этапа&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;O(\frac{m^2log(m)}{m^2+n})&amp;lt;/math&amp;gt; для третьего этапа&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1-й этап алгоритма детерминирован (граф &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;
[[Файл:Chameleo.png|300px]]&lt;br /&gt;
&lt;br /&gt;
На приведенном графике видна зависимость эффективности от объема данных и числа процессоров для реализации алгоритма, описанной в &amp;lt;ref name=&amp;quot;real&amp;quot;&amp;gt;http://research.ijcaonline.org/volume79/number8/pxc3891600.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
График построен для экспериментальной версии алгоритма для малого числа потоков.&lt;br /&gt;
Для тестирования использовался процессор Intel Pentium IV для одного потока, Intel Core i5 для 4-х потоков и Intel Core i7 для 8 потоков.&lt;br /&gt;
&lt;br /&gt;
К сожалению, в исследовании, на основе которого строится данный график, не приведены более подробные данные о том, как именно запускались тесты. Приводится только информация о процессорах, на которых выполнялись вычисления. Также в исследовании не приведён запускавшийся код. Вместе с тем, данное исследование является единственным, опирающимся на параллельный код и приводящее результаты запуска данного кода. Других параллельных реализаций найдено не было.&lt;br /&gt;
&lt;br /&gt;
Для набора из 8000 точек запуск на 8 потоках даёт ускорение 4,46x по сравнению с запуском на 1 потоке.&lt;br /&gt;
Для набора из 10000 точек запуск на 8 процессорах даёт ускорение 4,8x по сравнению с запуском на 1 процессоре.&lt;br /&gt;
Для набора из 20000 точек запуск на 8 процессорах даёт ускорение 5x по сравнению с запуском на 1 процессоре.&lt;br /&gt;
&lt;br /&gt;
Эффективность алгоритма падает при увеличении числа потоков (при увеличении числа потоков в 8 раз ускорение составляет ориентировочно 4-5x, то есть эффективность падает практически вдвое)&lt;br /&gt;
&lt;br /&gt;
===Динамические характеристики и эффективность реализации алгоритма===&lt;br /&gt;
===Выводы для классов архитектур===&lt;br /&gt;
===Существующие реализации алгоритма===&lt;br /&gt;
Одна из последовательных реализаций алгоритма находится по ссылке [http://codeforge.com/article/192925]&lt;br /&gt;
&lt;br /&gt;
Параллельных реализаций алгоритма найдено не было&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=22097</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=22097"/>
		<updated>2017-02-03T14:41:20Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор статьи: Хромов А. К.&lt;br /&gt;
 &lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;studo&amp;quot;&amp;gt;http://studopedia.ru/7_41934_algoritm-dinamicheskoy-ierarhicheskoy-klasterizatsii-CHAMELEON.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&amp;lt;ref name=&amp;quot;chamel&amp;quot;&amp;gt;http://www-users.cs.umn.edu/~han/dmclass/chameleon.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
1. Построение графа k-ближайших соседей по исходным данным&lt;br /&gt;
&lt;br /&gt;
2. Разбиения полученного на первом этапе графа на множество подграфов. На очередной итерации выбирается максимальный подграф, для него определяется оптимальное разбиение (подробнее описано в разделе 1.2), подграф разбивается в соответсвии с данным разбиением, начинается следующая итерация. В определенный момент, когда количество вершни в максимальном подграфе становится меньше, чем некоторая изначально заданная доля от количества вершин в первоначальном графе, разбиение прекращается.&lt;br /&gt;
&lt;br /&gt;
3. Итеративно осуществляется обхединение подграфов, на основе метрик взаимной связности и взаимного сходства. Процесс объединения завершается в момент достижения целевых показателей по данным метрикам.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:Инфограф.png]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
На первом этапе вычисление &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших вершин для &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й вершины можно распараллелить между &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; процессами (это вычисление независимо для каждой вершины).&lt;br /&gt;
На втором и третьем этапах процессы разбиения и объединения подграфов происходят последовательно.&lt;br /&gt;
Получаем оценку параллельной сложности алгоритма &amp;lt;math&amp;gt;O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
На вход алгоритму подается множество из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов длины &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt;, описывающих объекты для кластеризации.&lt;br /&gt;
Также передаются параметры &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (для построения графа k ближайших соседей на первом этапе) и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; (используется на втором этапе для определения критерия прекращения итерационного процесса).&lt;br /&gt;
На выходе алгоритм выдает массив длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, заполненный числами от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, показывающими, в какой кластер попал соответствующий объект.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Первый этап алгоритма хорошо распараллеливается (так как нахождение &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;
&amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для первого этапа &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;O(\frac{nm}{n^2+m^2})&amp;lt;/math&amp;gt; для второго этапа&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;O(\frac{m^2log(m)}{m^2+n})&amp;lt;/math&amp;gt; для третьего этапа&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1-й этап алгоритма детерминирован (граф &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;
[[Файл:Chameleo.png|300px]]&lt;br /&gt;
&lt;br /&gt;
На приведенном графике видна зависимость эффективности от объема данных и числа процессоров для реализации алгоритма, описанной в &amp;lt;ref name=&amp;quot;real&amp;quot;&amp;gt;http://research.ijcaonline.org/volume79/number8/pxc3891600.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
График построен для экспериментальной версии алгоритма для малого числа потоков.&lt;br /&gt;
Для тестирования использовался процессор Intel Pentium IV для одного потока, Intel Core i5 для 4-х потоков и Intel Core i7 для 8 потоков.&lt;br /&gt;
&lt;br /&gt;
К сожалению, в исследовании, на основе которого строится данный график, не приведены более подробные данные о том, как именно запускались тесты. Приводится только информация о процессорах, на которых выполнялись вычисления. Также в исследовании не приведён запускавшийся код. Вместе с тем, данное исследование является единственным, опирающимся на параллельный код и приводящее результаты запуска данного кода. Других параллельных реализаций найдено не было.&lt;br /&gt;
&lt;br /&gt;
Для набора из 8000 точек запуск на 8 потоках даёт ускорение 4,46x по сравнению с запуском на 1 потоке.&lt;br /&gt;
Для набора из 10000 точек запуск на 8 процессорах даёт ускорение 4,8x по сравнению с запуском на 1 процессоре.&lt;br /&gt;
Для набора из 20000 точек запуск на 8 процессорах даёт ускорение 5x по сравнению с запуском на 1 процессоре.&lt;br /&gt;
&lt;br /&gt;
Эффективность алгоритма падает при увеличении числа потоков (при увеличении числа потоков в 8 раз ускорение составляет ориентировочно 4-5x, то есть эффективность падает практически вдвое)&lt;br /&gt;
&lt;br /&gt;
===Динамические характеристики и эффективность реализации алгоритма===&lt;br /&gt;
===Выводы для классов архитектур===&lt;br /&gt;
===Существующие реализации алгоритма===&lt;br /&gt;
Одна из последовательных реализаций алгоритма находится по ссылке [http://codeforge.com/article/192925]&lt;br /&gt;
&lt;br /&gt;
Параллельных реализаций алгоритма найдено не было&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=22082</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=22082"/>
		<updated>2017-02-03T13:53:04Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор статьи: Хромов А. К.&lt;br /&gt;
 &lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;studo&amp;quot;&amp;gt;http://studopedia.ru/7_41934_algoritm-dinamicheskoy-ierarhicheskoy-klasterizatsii-CHAMELEON.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&amp;lt;ref name=&amp;quot;chamel&amp;quot;&amp;gt;http://www-users.cs.umn.edu/~han/dmclass/chameleon.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
1. Построение графа k-ближайших соседей по исходным данным&lt;br /&gt;
&lt;br /&gt;
2. Разбиения полученного на первом этапе графа на множество подграфов. На очередной итерации выбирается максимальный подграф, для него определяется оптимальное разбиение (подробнее описано в разделе 1.2), подграф разбивается в соответсвии с данным разбиением, начинается следующая итерация. В определенный момент, когда количество вершни в максимальном подграфе становится меньше, чем некоторая изначально заданная доля от количества вершин в первоначальном графе, разбиение прекращается.&lt;br /&gt;
&lt;br /&gt;
3. Итеративно осуществляется обхединение подграфов, на основе метрик взаимной связности и взаимного сходства. Процесс объединения завершается в момент достижения целевых показателей по данным метрикам.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:Инфограф.png]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
На первом этапе вычисление &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших вершин для &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й вершины можно распараллелить между &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; процессами (это вычисление независимо для каждой вершины).&lt;br /&gt;
На втором и третьем этапах процессы разбиения и объединения подграфов происходят последовательно.&lt;br /&gt;
Получаем оценку параллельной сложности алгоритма &amp;lt;math&amp;gt;O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
На вход алгоритму подается множество из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов длины &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt;, описывающих объекты для кластеризации.&lt;br /&gt;
Также передаются параметры &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (для построения графа k ближайших соседей на первом этапе) и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; (используется на втором этапе для определения критерия прекращения итерационного процесса).&lt;br /&gt;
На выходе алгоритм выдает массив длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, заполненный числами от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, показывающими, в какой кластер попал соответствующий объект.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Первый этап алгоритма хорошо распараллеливается (так как нахождение &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;
&amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для первого этапа &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;O(\frac{nm}{n^2+m^2})&amp;lt;/math&amp;gt; для второго этапа&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;O(\frac{m^2log(m)}{m^2+n})&amp;lt;/math&amp;gt; для третьего этапа&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1-й этап алгоритма детерминирован (граф &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;
[[Файл:Chameleo.png|300px]]&lt;br /&gt;
&lt;br /&gt;
На приведенном графике видна зависимость эффективности от объема данных и числа процессоров для реализации алгоритма, описанной в &amp;lt;ref name=&amp;quot;real&amp;quot;&amp;gt;http://research.ijcaonline.org/volume79/number8/pxc3891600.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
Для тестирования использовался процессор Intel Pentium IV для одного потока, Intel Core i5 для 4-х потоков и Intel Core i7 для 8 потоков.&lt;br /&gt;
&lt;br /&gt;
К сожалению, в исследовании, на основе которого строится данный график, не приведены более подробные данные о том, как именно запускались тесты. Приводится только информация о процессорах, на которых выполнялись вычисления. Также в исследовании не приведён запускавшийся код. Вместе с тем, данное исследование является единственным, опирающимся на параллельный код и приводящее результаты запуска данного кода. Других параллельных реализаций найдено не было.&lt;br /&gt;
&lt;br /&gt;
График построен для экспериментальной версии алгоритма для малого числа потоков.&lt;br /&gt;
&lt;br /&gt;
===Динамические характеристики и эффективность реализации алгоритма===&lt;br /&gt;
===Выводы для классов архитектур===&lt;br /&gt;
===Существующие реализации алгоритма===&lt;br /&gt;
Одна из последовательных реализаций алгоритма находится по ссылке [http://codeforge.com/article/192925]&lt;br /&gt;
&lt;br /&gt;
Параллельных реализаций алгоритма найдено не было&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=22077</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=22077"/>
		<updated>2017-02-03T13:40:36Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /*  Макроструктура алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор статьи: Хромов А. К.&lt;br /&gt;
 &lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;studo&amp;quot;&amp;gt;http://studopedia.ru/7_41934_algoritm-dinamicheskoy-ierarhicheskoy-klasterizatsii-CHAMELEON.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&amp;lt;ref name=&amp;quot;chamel&amp;quot;&amp;gt;http://www-users.cs.umn.edu/~han/dmclass/chameleon.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
1. Построение графа k-ближайших соседей по исходным данным&lt;br /&gt;
&lt;br /&gt;
2. Разбиения полученного на первом этапе графа на множество подграфов. На очередной итерации выбирается максимальный подграф, для него определяется оптимальное разбиение (подробнее описано в разделе 1.2), подграф разбивается в соответсвии с данным разбиением, начинается следующая итерация. В определенный момент, когда количество вершни в максимальном подграфе становится меньше, чем некоторая изначально заданная доля от количества вершин в первоначальном графе, разбиение прекращается.&lt;br /&gt;
&lt;br /&gt;
3. Итеративно осуществляется обхединение подграфов, на основе метрик взаимной связности и взаимного сходства. Процесс объединения завершается в момент достижения целевых показателей по данным метрикам.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:Инфограф.png]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
На первом этапе вычисление &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших вершин для &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й вершины можно распараллелить между &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; процессами (это вычисление независимо для каждой вершины).&lt;br /&gt;
На втором и третьем этапах процессы разбиения и объединения подграфов происходят последовательно.&lt;br /&gt;
Получаем оценку параллельной сложности алгоритма &amp;lt;math&amp;gt;O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
На вход алгоритму подается множество из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов длины &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt;, описывающих объекты для кластеризации.&lt;br /&gt;
Также передаются параметры &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (для построения графа k ближайших соседей на первом этапе) и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; (используется на втором этапе для определения критерия прекращения итерационного процесса).&lt;br /&gt;
На выходе алгоритм выдает массив длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, заполненный числами от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, показывающими, в какой кластер попал соответствующий объект.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Первый этап алгоритма хорошо распараллеливается (так как нахождение &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;
&amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для первого этапа &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;O(\frac{nm}{n^2+m^2})&amp;lt;/math&amp;gt; для второго этапа&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;O(\frac{m^2log(m)}{m^2+n})&amp;lt;/math&amp;gt; для третьего этапа&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1-й этап алгоритма детерминирован (граф &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;
[[Файл:Chameleo.png|300px]]&lt;br /&gt;
&lt;br /&gt;
На приведенном графике видна зависимость эффективности от объема данных и числа процессоров для реализации алгоритма, описанной в &amp;lt;ref name=&amp;quot;real&amp;quot;&amp;gt;http://research.ijcaonline.org/volume79/number8/pxc3891600.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
График построен для экспериментальной версии алгоритма для малого числа потоков.&lt;br /&gt;
&lt;br /&gt;
===Динамические характеристики и эффективность реализации алгоритма===&lt;br /&gt;
===Выводы для классов архитектур===&lt;br /&gt;
===Существующие реализации алгоритма===&lt;br /&gt;
Одна из последовательных реализаций алгоритма находится по ссылке [http://codeforge.com/article/192925]&lt;br /&gt;
&lt;br /&gt;
Параллельных реализаций алгоритма найдено не было&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=22076</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=22076"/>
		<updated>2017-02-03T13:40:08Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /*  Макроструктура алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор статьи: Хромов А. К.&lt;br /&gt;
 &lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;studo&amp;quot;&amp;gt;http://studopedia.ru/7_41934_algoritm-dinamicheskoy-ierarhicheskoy-klasterizatsii-CHAMELEON.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&amp;lt;ref name=&amp;quot;chamel&amp;quot;&amp;gt;http://www-users.cs.umn.edu/~han/dmclass/chameleon.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
1. Построение графа k-ближайших соседей по исходным данным&lt;br /&gt;
2. Разбиения полученного на первом этапе графа на множество подграфов. На очередной итерации выбирается максимальный подграф, для него определяется оптимальное разбиение (подробнее описано в разделе 1.2), подграф разбивается в соответсвии с данным разбиением, начинается следующая итерация. В определенный момент, когда количество вершни в максимальном подграфе становится меньше, чем некоторая изначально заданная доля от количества вершин в первоначальном графе, разбиение прекращается.&lt;br /&gt;
3. Итеративно осуществляется обхединение подграфов, на основе метрик взаимной связности и взаимного сходства. Процесс объединения завершается в момент достижения целевых показателей по данным метрикам.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:Инфограф.png]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
На первом этапе вычисление &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших вершин для &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й вершины можно распараллелить между &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; процессами (это вычисление независимо для каждой вершины).&lt;br /&gt;
На втором и третьем этапах процессы разбиения и объединения подграфов происходят последовательно.&lt;br /&gt;
Получаем оценку параллельной сложности алгоритма &amp;lt;math&amp;gt;O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
На вход алгоритму подается множество из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов длины &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt;, описывающих объекты для кластеризации.&lt;br /&gt;
Также передаются параметры &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (для построения графа k ближайших соседей на первом этапе) и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; (используется на втором этапе для определения критерия прекращения итерационного процесса).&lt;br /&gt;
На выходе алгоритм выдает массив длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, заполненный числами от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, показывающими, в какой кластер попал соответствующий объект.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Первый этап алгоритма хорошо распараллеливается (так как нахождение &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;
&amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для первого этапа &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;O(\frac{nm}{n^2+m^2})&amp;lt;/math&amp;gt; для второго этапа&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;O(\frac{m^2log(m)}{m^2+n})&amp;lt;/math&amp;gt; для третьего этапа&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1-й этап алгоритма детерминирован (граф &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;
[[Файл:Chameleo.png|300px]]&lt;br /&gt;
&lt;br /&gt;
На приведенном графике видна зависимость эффективности от объема данных и числа процессоров для реализации алгоритма, описанной в &amp;lt;ref name=&amp;quot;real&amp;quot;&amp;gt;http://research.ijcaonline.org/volume79/number8/pxc3891600.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
График построен для экспериментальной версии алгоритма для малого числа потоков.&lt;br /&gt;
&lt;br /&gt;
===Динамические характеристики и эффективность реализации алгоритма===&lt;br /&gt;
===Выводы для классов архитектур===&lt;br /&gt;
===Существующие реализации алгоритма===&lt;br /&gt;
Одна из последовательных реализаций алгоритма находится по ссылке [http://codeforge.com/article/192925]&lt;br /&gt;
&lt;br /&gt;
Параллельных реализаций алгоритма найдено не было&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21804</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21804"/>
		<updated>2017-01-30T21:24:01Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{assignment}}&lt;br /&gt;
Автор статьи: Хромов А. К.&lt;br /&gt;
 &lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;studo&amp;quot;&amp;gt;http://studopedia.ru/7_41934_algoritm-dinamicheskoy-ierarhicheskoy-klasterizatsii-CHAMELEON.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&amp;lt;ref name=&amp;quot;chamel&amp;quot;&amp;gt;http://www-users.cs.umn.edu/~han/dmclass/chameleon.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В рамках первого этапа макрооперацияй считается построение графа k-ближайших соседей&lt;br /&gt;
&lt;br /&gt;
В рамках второго этапа макрооперациями считаются операции разбиения подграфа.&lt;br /&gt;
&lt;br /&gt;
В рамках третьего этапа макрооперациями считаются вычисления метрики, на основании которой делается вывод о том, какие подграфы нужно объединять.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:Инфограф.png]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
На первом этапе вычисление &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших вершин для &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й вершины можно распараллелить между &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; процессами (это вычисление независимо для каждой вершины).&lt;br /&gt;
На втором и третьем этапах процессы разбиения и объединения подграфов происходят последовательно.&lt;br /&gt;
Получаем оценку параллельной сложности алгоритма &amp;lt;math&amp;gt;O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
На вход алгоритму подается множество из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов длины &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt;, описывающих объекты для кластеризации.&lt;br /&gt;
Также передаются параметры &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (для построения графа k ближайших соседей на первом этапе) и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; (используется на втором этапе для определения критерия прекращения итерационного процесса).&lt;br /&gt;
На выходе алгоритм выдает массив длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, заполненный числами от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, показывающими, в какой кластер попал соответствующий объект.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Первый этап алгоритма хорошо распараллеливается (так как нахождение &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;
&amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для первого этапа &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;O(\frac{nm}{n^2+m^2})&amp;lt;/math&amp;gt; для второго этапа&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;O(\frac{m^2log(m)}{m^2+n})&amp;lt;/math&amp;gt; для третьего этапа&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1-й этап алгоритма детерминирован (граф &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;
[[Файл:Chameleo.png|300px]]&lt;br /&gt;
&lt;br /&gt;
На приведенном графике видна зависимость эффективности от объема данных и числа процессоров для реализации алгоритма, описанной в &amp;lt;ref name=&amp;quot;real&amp;quot;&amp;gt;http://research.ijcaonline.org/volume79/number8/pxc3891600.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
График построен для экспериментальной версии алгоритма для малого числа потоков.&lt;br /&gt;
&lt;br /&gt;
===Динамические характеристики и эффективность реализации алгоритма===&lt;br /&gt;
===Выводы для классов архитектур===&lt;br /&gt;
===Существующие реализации алгоритма===&lt;br /&gt;
Одна из последовательных реализаций алгоритма находится по ссылке [http://codeforge.com/article/192925]&lt;br /&gt;
&lt;br /&gt;
Параллельных реализаций алгоритма найдено не было&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21803</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21803"/>
		<updated>2017-01-30T21:20:52Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В инкубаторе}}&lt;br /&gt;
Автор статьи: Хромов А. К.&lt;br /&gt;
 &lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;studo&amp;quot;&amp;gt;http://studopedia.ru/7_41934_algoritm-dinamicheskoy-ierarhicheskoy-klasterizatsii-CHAMELEON.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&amp;lt;ref name=&amp;quot;chamel&amp;quot;&amp;gt;http://www-users.cs.umn.edu/~han/dmclass/chameleon.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В рамках первого этапа макрооперацияй считается построение графа k-ближайших соседей&lt;br /&gt;
&lt;br /&gt;
В рамках второго этапа макрооперациями считаются операции разбиения подграфа.&lt;br /&gt;
&lt;br /&gt;
В рамках третьего этапа макрооперациями считаются вычисления метрики, на основании которой делается вывод о том, какие подграфы нужно объединять.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:Инфограф.png]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
На первом этапе вычисление &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших вершин для &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й вершины можно распараллелить между &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; процессами (это вычисление независимо для каждой вершины).&lt;br /&gt;
На втором и третьем этапах процессы разбиения и объединения подграфов происходят последовательно.&lt;br /&gt;
Получаем оценку параллельной сложности алгоритма &amp;lt;math&amp;gt;O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
На вход алгоритму подается множество из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов длины &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt;, описывающих объекты для кластеризации.&lt;br /&gt;
Также передаются параметры &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (для построения графа k ближайших соседей на первом этапе) и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; (используется на втором этапе для определения критерия прекращения итерационного процесса).&lt;br /&gt;
На выходе алгоритм выдает массив длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, заполненный числами от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, показывающими, в какой кластер попал соответствующий объект.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Первый этап алгоритма хорошо распараллеливается (так как нахождение &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;
&amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для первого этапа &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;O(\frac{nm}{n^2+m^2})&amp;lt;/math&amp;gt; для второго этапа&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;O(\frac{m^2log(m)}{m^2+n})&amp;lt;/math&amp;gt; для третьего этапа&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1-й этап алгоритма детерминирован (граф &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;
[[Файл:Chameleo.png|300px]]&lt;br /&gt;
&lt;br /&gt;
На приведенном графике видна зависимость эффективности от объема данных и числа процессоров для реализации алгоритма, описанной в &amp;lt;ref name=&amp;quot;real&amp;quot;&amp;gt;http://research.ijcaonline.org/volume79/number8/pxc3891600.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
График построен для экспериментальной версии алгоритма для малого числа потоков.&lt;br /&gt;
&lt;br /&gt;
===Динамические характеристики и эффективность реализации алгоритма===&lt;br /&gt;
===Выводы для классов архитектур===&lt;br /&gt;
===Существующие реализации алгоритма===&lt;br /&gt;
Одна из последовательных реализаций алгоритма находится по ссылке [http://codeforge.com/article/192925]&lt;br /&gt;
&lt;br /&gt;
Параллельных реализаций алгоритма найдено не было&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21765</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21765"/>
		<updated>2017-01-26T11:46:33Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* Существующие реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В инкубаторе}}&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;studo&amp;quot;&amp;gt;http://studopedia.ru/7_41934_algoritm-dinamicheskoy-ierarhicheskoy-klasterizatsii-CHAMELEON.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&amp;lt;ref name=&amp;quot;chamel&amp;quot;&amp;gt;http://www-users.cs.umn.edu/~han/dmclass/chameleon.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В рамках первого этапа макрооперацияй считается построение графа k-ближайших соседей&lt;br /&gt;
&lt;br /&gt;
В рамках второго этапа макрооперациями считаются операции разбиения подграфа.&lt;br /&gt;
&lt;br /&gt;
В рамках третьего этапа макрооперациями считаются вычисления метрики, на основании которой делается вывод о том, какие подграфы нужно объединять.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:Инфограф.png]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
На первом этапе вычисление &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших вершин для &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й вершины можно распараллелить между &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; процессами (это вычисление независимо для каждой вершины).&lt;br /&gt;
На втором и третьем этапах процессы разбиения и объединения подграфов происходят последовательно.&lt;br /&gt;
Получаем оценку параллельной сложности алгоритма &amp;lt;math&amp;gt;O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
На вход алгоритму подается множество из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов длины &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt;, описывающих объекты для кластеризации.&lt;br /&gt;
Также передаются параметры &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (для построения графа k ближайших соседей на первом этапе) и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; (используется на втором этапе для определения критерия прекращения итерационного процесса).&lt;br /&gt;
На выходе алгоритм выдает массив длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, заполненный числами от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, показывающими, в какой кластер попал соответствующий объект.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Первый этап алгоритма хорошо распараллеливается (так как нахождение &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;
&amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для первого этапа &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;O(\frac{nm}{n^2+m^2})&amp;lt;/math&amp;gt; для второго этапа&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;O(\frac{m^2log(m)}{m^2+n})&amp;lt;/math&amp;gt; для третьего этапа&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1-й этап алгоритма детерминирован (граф &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;
[[Файл:Chameleo.png|300px]]&lt;br /&gt;
&lt;br /&gt;
На приведенном графике видна зависимость эффективности от объема данных и числа процессоров для реализации алгоритма, описанной в &amp;lt;ref name=&amp;quot;real&amp;quot;&amp;gt;http://research.ijcaonline.org/volume79/number8/pxc3891600.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
График построен для экспериментальной версии алгоритма для малого числа потоков.&lt;br /&gt;
&lt;br /&gt;
===Динамические характеристики и эффективность реализации алгоритма===&lt;br /&gt;
===Выводы для классов архитектур===&lt;br /&gt;
===Существующие реализации алгоритма===&lt;br /&gt;
Одна из последовательных реализаций алгоритма находится по ссылке [http://codeforge.com/article/192925]&lt;br /&gt;
&lt;br /&gt;
Параллельных реализаций алгоритма найдено не было&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21764</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21764"/>
		<updated>2017-01-26T11:46:23Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В инкубаторе}}&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;studo&amp;quot;&amp;gt;http://studopedia.ru/7_41934_algoritm-dinamicheskoy-ierarhicheskoy-klasterizatsii-CHAMELEON.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&amp;lt;ref name=&amp;quot;chamel&amp;quot;&amp;gt;http://www-users.cs.umn.edu/~han/dmclass/chameleon.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В рамках первого этапа макрооперацияй считается построение графа k-ближайших соседей&lt;br /&gt;
&lt;br /&gt;
В рамках второго этапа макрооперациями считаются операции разбиения подграфа.&lt;br /&gt;
&lt;br /&gt;
В рамках третьего этапа макрооперациями считаются вычисления метрики, на основании которой делается вывод о том, какие подграфы нужно объединять.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:Инфограф.png]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
На первом этапе вычисление &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших вершин для &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й вершины можно распараллелить между &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; процессами (это вычисление независимо для каждой вершины).&lt;br /&gt;
На втором и третьем этапах процессы разбиения и объединения подграфов происходят последовательно.&lt;br /&gt;
Получаем оценку параллельной сложности алгоритма &amp;lt;math&amp;gt;O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
На вход алгоритму подается множество из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов длины &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt;, описывающих объекты для кластеризации.&lt;br /&gt;
Также передаются параметры &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (для построения графа k ближайших соседей на первом этапе) и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; (используется на втором этапе для определения критерия прекращения итерационного процесса).&lt;br /&gt;
На выходе алгоритм выдает массив длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, заполненный числами от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, показывающими, в какой кластер попал соответствующий объект.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Первый этап алгоритма хорошо распараллеливается (так как нахождение &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;
&amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для первого этапа &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;O(\frac{nm}{n^2+m^2})&amp;lt;/math&amp;gt; для второго этапа&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;O(\frac{m^2log(m)}{m^2+n})&amp;lt;/math&amp;gt; для третьего этапа&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1-й этап алгоритма детерминирован (граф &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;
[[Файл:Chameleo.png|300px]]&lt;br /&gt;
&lt;br /&gt;
На приведенном графике видна зависимость эффективности от объема данных и числа процессоров для реализации алгоритма, описанной в &amp;lt;ref name=&amp;quot;real&amp;quot;&amp;gt;http://research.ijcaonline.org/volume79/number8/pxc3891600.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
График построен для экспериментальной версии алгоритма для малого числа потоков.&lt;br /&gt;
&lt;br /&gt;
===Динамические характеристики и эффективность реализации алгоритма===&lt;br /&gt;
===Выводы для классов архитектур===&lt;br /&gt;
===Существующие реализации алгоритма===&lt;br /&gt;
Одна из последовательных реализаций алгоритма находится по ссылке [http://codeforge.com/article/192925]&lt;br /&gt;
Параллельных реализаций алгоритма найдено не было&lt;br /&gt;
==Литература==&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21763</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21763"/>
		<updated>2017-01-26T11:46:04Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В инкубаторе}}&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;studo&amp;quot;&amp;gt;http://studopedia.ru/7_41934_algoritm-dinamicheskoy-ierarhicheskoy-klasterizatsii-CHAMELEON.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&amp;lt;ref name=&amp;quot;chamel&amp;quot;&amp;gt;http://www-users.cs.umn.edu/~han/dmclass/chameleon.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В рамках первого этапа макрооперацияй считается построение графа k-ближайших соседей&lt;br /&gt;
&lt;br /&gt;
В рамках второго этапа макрооперациями считаются операции разбиения подграфа.&lt;br /&gt;
&lt;br /&gt;
В рамках третьего этапа макрооперациями считаются вычисления метрики, на основании которой делается вывод о том, какие подграфы нужно объединять.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:Инфограф.png]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
На первом этапе вычисление &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших вершин для &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й вершины можно распараллелить между &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; процессами (это вычисление независимо для каждой вершины).&lt;br /&gt;
На втором и третьем этапах процессы разбиения и объединения подграфов происходят последовательно.&lt;br /&gt;
Получаем оценку параллельной сложности алгоритма &amp;lt;math&amp;gt;O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
На вход алгоритму подается множество из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов длины &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt;, описывающих объекты для кластеризации.&lt;br /&gt;
Также передаются параметры &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (для построения графа k ближайших соседей на первом этапе) и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; (используется на втором этапе для определения критерия прекращения итерационного процесса).&lt;br /&gt;
На выходе алгоритм выдает массив длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, заполненный числами от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, показывающими, в какой кластер попал соответствующий объект.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Первый этап алгоритма хорошо распараллеливается (так как нахождение &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;
&amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для первого этапа &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;O(\frac{nm}{n^2+m^2})&amp;lt;/math&amp;gt; для второго этапа&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;O(\frac{m^2log(m)}{m^2+n})&amp;lt;/math&amp;gt; для третьего этапа&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1-й этап алгоритма детерминирован (граф &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;
[[Файл:Chameleo.png|300px]]&lt;br /&gt;
&lt;br /&gt;
На приведенном графике видна зависимость эффективности от объема данных и числа процессоров для реализации алгоритма, описанной в &amp;lt;ref name=&amp;quot;real&amp;quot;&amp;gt;http://research.ijcaonline.org/volume79/number8/pxc3891600.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
График построен для экспериментальной версии алгоритма для малого числа потоков.&lt;br /&gt;
&lt;br /&gt;
===Динамические характеристики и эффективность реализации алгоритма===&lt;br /&gt;
===Выводы для классов архитектур===&lt;br /&gt;
===Существующие реализации алгоритма===&lt;br /&gt;
Одна из последовательных реализаций алгоритма находится по ссылке [http://codeforge.com/article/192925]&lt;br /&gt;
Параллельных реализаций алгоритма найдено не было&lt;br /&gt;
==Литература==&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21761</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21761"/>
		<updated>2017-01-25T13:55:37Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* Свойства алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В инкубаторе}}&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;studo&amp;quot;&amp;gt;http://studopedia.ru/7_41934_algoritm-dinamicheskoy-ierarhicheskoy-klasterizatsii-CHAMELEON.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&amp;lt;ref name=&amp;quot;chamel&amp;quot;&amp;gt;http://www-users.cs.umn.edu/~han/dmclass/chameleon.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В рамках первого этапа макрооперацияй считается построение графа k-ближайших соседей&lt;br /&gt;
&lt;br /&gt;
В рамках второго этапа макрооперациями считаются операции разбиения подграфа.&lt;br /&gt;
&lt;br /&gt;
В рамках третьего этапа макрооперациями считаются вычисления метрики, на основании которой делается вывод о том, какие подграфы нужно объединять.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:Инфограф.png]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
На первом этапе вычисление &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших вершин для &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й вершины можно распараллелить между &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; процессами (это вычисление независимо для каждой вершины).&lt;br /&gt;
На втором и третьем этапах процессы разбиения и объединения подграфов происходят последовательно.&lt;br /&gt;
Получаем оценку параллельной сложности алгоритма &amp;lt;math&amp;gt;O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
На вход алгоритму подается множество из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов длины &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt;, описывающих объекты для кластеризации.&lt;br /&gt;
Также передаются параметры &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (для построения графа k ближайших соседей на первом этапе) и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; (используется на втором этапе для определения критерия прекращения итерационного процесса).&lt;br /&gt;
На выходе алгоритм выдает массив длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, заполненный числами от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, показывающими, в какой кластер попал соответствующий объект.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Первый этап алгоритма хорошо распараллеливается (так как нахождение &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;
&amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для первого этапа &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;O(\frac{nm}{n^2+m^2})&amp;lt;/math&amp;gt; для второго этапа&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;O(\frac{m^2log(m)}{m^2+n})&amp;lt;/math&amp;gt; для третьего этапа&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1-й этап алгоритма детерминирован (граф &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;
[[Файл:Chameleo.png|300px]]&lt;br /&gt;
&lt;br /&gt;
На приведенном графике видна зависимость эффективности от объема данных и числа процессоров для реализации алгоритма, описанной в &amp;lt;ref name=&amp;quot;real&amp;quot;&amp;gt;http://research.ijcaonline.org/volume79/number8/pxc3891600.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Динамические характеристики и эффективность реализации алгоритма===&lt;br /&gt;
===Выводы для классов архитектур===&lt;br /&gt;
===Существующие реализации алгоритма===&lt;br /&gt;
Одна из последовательных реализаций алгоритма находится по ссылке [http://codeforge.com/article/192925]&lt;br /&gt;
Параллельных реализаций алгоритма найдено не было&lt;br /&gt;
==Литература==&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21760</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21760"/>
		<updated>2017-01-25T13:55:16Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* Свойства алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В инкубаторе}}&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;studo&amp;quot;&amp;gt;http://studopedia.ru/7_41934_algoritm-dinamicheskoy-ierarhicheskoy-klasterizatsii-CHAMELEON.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&amp;lt;ref name=&amp;quot;chamel&amp;quot;&amp;gt;http://www-users.cs.umn.edu/~han/dmclass/chameleon.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В рамках первого этапа макрооперацияй считается построение графа k-ближайших соседей&lt;br /&gt;
&lt;br /&gt;
В рамках второго этапа макрооперациями считаются операции разбиения подграфа.&lt;br /&gt;
&lt;br /&gt;
В рамках третьего этапа макрооперациями считаются вычисления метрики, на основании которой делается вывод о том, какие подграфы нужно объединять.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:Инфограф.png]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
На первом этапе вычисление &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших вершин для &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й вершины можно распараллелить между &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; процессами (это вычисление независимо для каждой вершины).&lt;br /&gt;
На втором и третьем этапах процессы разбиения и объединения подграфов происходят последовательно.&lt;br /&gt;
Получаем оценку параллельной сложности алгоритма &amp;lt;math&amp;gt;O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
На вход алгоритму подается множество из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов длины &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt;, описывающих объекты для кластеризации.&lt;br /&gt;
Также передаются параметры &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (для построения графа k ближайших соседей на первом этапе) и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; (используется на втором этапе для определения критерия прекращения итерационного процесса).&lt;br /&gt;
На выходе алгоритм выдает массив длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, заполненный числами от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, показывающими, в какой кластер попал соответствующий объект.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Первый этап алгоритма хорошо распараллеливается (так как нахождение &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;
&amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для первого этапа &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;O(\frac{nm}{n^2+m^2})&amp;lt;/math&amp;gt; для второго этапа&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;O(\frac{m^2log(m)}{m^2+n})&amp;lt;/math&amp;gt; для третьего этапа&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1-й этап алгоритма детерминирован (граф k ближайших соседей всегда одинаков), второй и третий этапы недетерминированы (зависят от того, какие подграфы будут выбираться на итерациях алгоритма)&lt;br /&gt;
&lt;br /&gt;
==Программная реализация алгоритма==&lt;br /&gt;
===Особенности реализации последовательного алгоритма===&lt;br /&gt;
===Локальность данных и вычислений===&lt;br /&gt;
===Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
===Масштабируемость алгоритма и его реализации===&lt;br /&gt;
[[Файл:Chameleo.png|300px]]&lt;br /&gt;
&lt;br /&gt;
На приведенном графике видна зависимость эффективности от объема данных и числа процессоров для реализации алгоритма, описанной в &amp;lt;ref name=&amp;quot;real&amp;quot;&amp;gt;http://research.ijcaonline.org/volume79/number8/pxc3891600.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Динамические характеристики и эффективность реализации алгоритма===&lt;br /&gt;
===Выводы для классов архитектур===&lt;br /&gt;
===Существующие реализации алгоритма===&lt;br /&gt;
Одна из последовательных реализаций алгоритма находится по ссылке [http://codeforge.com/article/192925]&lt;br /&gt;
Параллельных реализаций алгоритма найдено не было&lt;br /&gt;
==Литература==&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21759</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21759"/>
		<updated>2017-01-25T13:55:02Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* Свойства и структура алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В инкубаторе}}&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;studo&amp;quot;&amp;gt;http://studopedia.ru/7_41934_algoritm-dinamicheskoy-ierarhicheskoy-klasterizatsii-CHAMELEON.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&amp;lt;ref name=&amp;quot;chamel&amp;quot;&amp;gt;http://www-users.cs.umn.edu/~han/dmclass/chameleon.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В рамках первого этапа макрооперацияй считается построение графа k-ближайших соседей&lt;br /&gt;
&lt;br /&gt;
В рамках второго этапа макрооперациями считаются операции разбиения подграфа.&lt;br /&gt;
&lt;br /&gt;
В рамках третьего этапа макрооперациями считаются вычисления метрики, на основании которой делается вывод о том, какие подграфы нужно объединять.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:Инфограф.png]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
На первом этапе вычисление &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших вершин для &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й вершины можно распараллелить между &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; процессами (это вычисление независимо для каждой вершины).&lt;br /&gt;
На втором и третьем этапах процессы разбиения и объединения подграфов происходят последовательно.&lt;br /&gt;
Получаем оценку параллельной сложности алгоритма &amp;lt;math&amp;gt;O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
На вход алгоритму подается множество из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов длины &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt;, описывающих объекты для кластеризации.&lt;br /&gt;
Также передаются параметры &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (для построения графа k ближайших соседей на первом этапе) и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; (используется на втором этапе для определения критерия прекращения итерационного процесса).&lt;br /&gt;
На выходе алгоритм выдает массив длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, заполненный числами от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, показывающими, в какой кластер попал соответствующий объект.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Первый этап алгоритма хорошо распараллеливается (так как нахождение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших вершин для каждой вершины можно осуществлять независимо).&lt;br /&gt;
Второй и третий этап выполняются последовательно итерация за итерацией, но возможно их частичное распараллеливание.&lt;br /&gt;
&lt;br /&gt;
Вычислительная мощность (соотношение времени выполнения и объема входных и выходных данных) для разных этапов:&lt;br /&gt;
&amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для первого этапа &lt;br /&gt;
&amp;lt;math&amp;gt;O(\frac{nm}{n^2+m^2})&amp;lt;/math&amp;gt; для второго этапа&lt;br /&gt;
&amp;lt;math&amp;gt;O(\frac{m^2log(m)}{m^2+n})&amp;lt;/math&amp;gt; для третьего этапа&lt;br /&gt;
&lt;br /&gt;
1-й этап алгоритма детерминирован (граф k ближайших соседей всегда одинаков), второй и третий этапы недетерминированы (зависят от того, какие подграфы будут выбираться на итерациях алгоритма)&lt;br /&gt;
&lt;br /&gt;
==Программная реализация алгоритма==&lt;br /&gt;
===Особенности реализации последовательного алгоритма===&lt;br /&gt;
===Локальность данных и вычислений===&lt;br /&gt;
===Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
===Масштабируемость алгоритма и его реализации===&lt;br /&gt;
[[Файл:Chameleo.png|300px]]&lt;br /&gt;
&lt;br /&gt;
На приведенном графике видна зависимость эффективности от объема данных и числа процессоров для реализации алгоритма, описанной в &amp;lt;ref name=&amp;quot;real&amp;quot;&amp;gt;http://research.ijcaonline.org/volume79/number8/pxc3891600.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Динамические характеристики и эффективность реализации алгоритма===&lt;br /&gt;
===Выводы для классов архитектур===&lt;br /&gt;
===Существующие реализации алгоритма===&lt;br /&gt;
Одна из последовательных реализаций алгоритма находится по ссылке [http://codeforge.com/article/192925]&lt;br /&gt;
Параллельных реализаций алгоритма найдено не было&lt;br /&gt;
==Литература==&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21758</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21758"/>
		<updated>2017-01-25T13:44:13Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В инкубаторе}}&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;studo&amp;quot;&amp;gt;http://studopedia.ru/7_41934_algoritm-dinamicheskoy-ierarhicheskoy-klasterizatsii-CHAMELEON.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&amp;lt;ref name=&amp;quot;chamel&amp;quot;&amp;gt;http://www-users.cs.umn.edu/~han/dmclass/chameleon.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В рамках первого этапа макрооперацияй считается построение графа k-ближайших соседей&lt;br /&gt;
&lt;br /&gt;
В рамках второго этапа макрооперациями считаются операции разбиения подграфа.&lt;br /&gt;
&lt;br /&gt;
В рамках третьего этапа макрооперациями считаются вычисления метрики, на основании которой делается вывод о том, какие подграфы нужно объединять.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:Инфограф.png]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
На первом этапе вычисление &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших вершин для &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й вершины можно распараллелить между &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; процессами (это вычисление независимо для каждой вершины).&lt;br /&gt;
На втором и третьем этапах процессы разбиения и объединения подграфов происходят последовательно.&lt;br /&gt;
Получаем оценку параллельной сложности алгоритма &amp;lt;math&amp;gt;O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
На вход алгоритму подается множество из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов длины &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt;, описывающих объекты для кластеризации.&lt;br /&gt;
Также передаются параметры &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (для построения графа k ближайших соседей на первом этапе) и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; (используется на втором этапе для определения критерия прекращения итерационного процесса).&lt;br /&gt;
На выходе алгоритм выдает массив длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, заполненный числами от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, показывающими, в какой кластер попал соответствующий объект.&lt;br /&gt;
&lt;br /&gt;
==Программная реализация алгоритма==&lt;br /&gt;
===Особенности реализации последовательного алгоритма===&lt;br /&gt;
===Локальность данных и вычислений===&lt;br /&gt;
===Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
===Масштабируемость алгоритма и его реализации===&lt;br /&gt;
[[Файл:Chameleo.png|300px]]&lt;br /&gt;
&lt;br /&gt;
На приведенном графике видна зависимость эффективности от объема данных и числа процессоров для реализации алгоритма, описанной в &amp;lt;ref name=&amp;quot;real&amp;quot;&amp;gt;http://research.ijcaonline.org/volume79/number8/pxc3891600.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Динамические характеристики и эффективность реализации алгоритма===&lt;br /&gt;
===Выводы для классов архитектур===&lt;br /&gt;
===Существующие реализации алгоритма===&lt;br /&gt;
Одна из последовательных реализаций алгоритма находится по ссылке [http://codeforge.com/article/192925]&lt;br /&gt;
Параллельных реализаций алгоритма найдено не было&lt;br /&gt;
==Литература==&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21757</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21757"/>
		<updated>2017-01-25T13:41:10Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* Общее описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В инкубаторе}}&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;studo&amp;quot;&amp;gt;http://studopedia.ru/7_41934_algoritm-dinamicheskoy-ierarhicheskoy-klasterizatsii-CHAMELEON.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В рамках первого этапа макрооперацияй считается построение графа k-ближайших соседей&lt;br /&gt;
&lt;br /&gt;
В рамках второго этапа макрооперациями считаются операции разбиения подграфа.&lt;br /&gt;
&lt;br /&gt;
В рамках третьего этапа макрооперациями считаются вычисления метрики, на основании которой делается вывод о том, какие подграфы нужно объединять.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:Инфограф.png]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
На первом этапе вычисление &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших вершин для &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й вершины можно распараллелить между &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; процессами (это вычисление независимо для каждой вершины).&lt;br /&gt;
На втором и третьем этапах процессы разбиения и объединения подграфов происходят последовательно.&lt;br /&gt;
Получаем оценку параллельной сложности алгоритма &amp;lt;math&amp;gt;O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
На вход алгоритму подается множество из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов длины &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt;, описывающих объекты для кластеризации.&lt;br /&gt;
Также передаются параметры &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (для построения графа k ближайших соседей на первом этапе) и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; (используется на втором этапе для определения критерия прекращения итерационного процесса).&lt;br /&gt;
На выходе алгоритм выдает массив длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, заполненный числами от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, показывающими, в какой кластер попал соответствующий объект.&lt;br /&gt;
&lt;br /&gt;
==Программная реализация алгоритма==&lt;br /&gt;
===Особенности реализации последовательного алгоритма===&lt;br /&gt;
===Локальность данных и вычислений===&lt;br /&gt;
===Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
===Масштабируемость алгоритма и его реализации===&lt;br /&gt;
[[Файл:Chameleo.png|300px]]&lt;br /&gt;
&lt;br /&gt;
На приведенном графике видна зависимость эффективности от объема данных и числа процессоров для реализации алгоритма, описанной в &amp;lt;ref name=&amp;quot;real&amp;quot;&amp;gt;http://research.ijcaonline.org/volume79/number8/pxc3891600.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Динамические характеристики и эффективность реализации алгоритма===&lt;br /&gt;
===Выводы для классов архитектур===&lt;br /&gt;
===Существующие реализации алгоритма===&lt;br /&gt;
Одна из последовательных реализаций алгоритма находится по ссылке [http://codeforge.com/article/192925]&lt;br /&gt;
Параллельных реализаций алгоритма найдено не было&lt;br /&gt;
==Литература==&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21756</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21756"/>
		<updated>2017-01-25T13:39:47Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* Программная реализация алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В инкубаторе}}&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В рамках первого этапа макрооперацияй считается построение графа k-ближайших соседей&lt;br /&gt;
&lt;br /&gt;
В рамках второго этапа макрооперациями считаются операции разбиения подграфа.&lt;br /&gt;
&lt;br /&gt;
В рамках третьего этапа макрооперациями считаются вычисления метрики, на основании которой делается вывод о том, какие подграфы нужно объединять.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:Инфограф.png]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
На первом этапе вычисление &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших вершин для &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й вершины можно распараллелить между &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; процессами (это вычисление независимо для каждой вершины).&lt;br /&gt;
На втором и третьем этапах процессы разбиения и объединения подграфов происходят последовательно.&lt;br /&gt;
Получаем оценку параллельной сложности алгоритма &amp;lt;math&amp;gt;O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
На вход алгоритму подается множество из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов длины &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt;, описывающих объекты для кластеризации.&lt;br /&gt;
Также передаются параметры &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (для построения графа k ближайших соседей на первом этапе) и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; (используется на втором этапе для определения критерия прекращения итерационного процесса).&lt;br /&gt;
На выходе алгоритм выдает массив длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, заполненный числами от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, показывающими, в какой кластер попал соответствующий объект.&lt;br /&gt;
&lt;br /&gt;
==Программная реализация алгоритма==&lt;br /&gt;
===Особенности реализации последовательного алгоритма===&lt;br /&gt;
===Локальность данных и вычислений===&lt;br /&gt;
===Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
===Масштабируемость алгоритма и его реализации===&lt;br /&gt;
[[Файл:Chameleo.png|300px]]&lt;br /&gt;
&lt;br /&gt;
На приведенном графике видна зависимость эффективности от объема данных и числа процессоров для реализации алгоритма, описанной в &amp;lt;ref name=&amp;quot;real&amp;quot;&amp;gt;http://research.ijcaonline.org/volume79/number8/pxc3891600.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Динамические характеристики и эффективность реализации алгоритма===&lt;br /&gt;
===Выводы для классов архитектур===&lt;br /&gt;
===Существующие реализации алгоритма===&lt;br /&gt;
Одна из последовательных реализаций алгоритма находится по ссылке [http://codeforge.com/article/192925]&lt;br /&gt;
Параллельных реализаций алгоритма найдено не было&lt;br /&gt;
==Литература==&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21755</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21755"/>
		<updated>2017-01-25T13:38:46Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* Существующие реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В инкубаторе}}&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В рамках первого этапа макрооперацияй считается построение графа k-ближайших соседей&lt;br /&gt;
&lt;br /&gt;
В рамках второго этапа макрооперациями считаются операции разбиения подграфа.&lt;br /&gt;
&lt;br /&gt;
В рамках третьего этапа макрооперациями считаются вычисления метрики, на основании которой делается вывод о том, какие подграфы нужно объединять.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:Инфограф.png]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
На первом этапе вычисление &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших вершин для &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й вершины можно распараллелить между &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; процессами (это вычисление независимо для каждой вершины).&lt;br /&gt;
На втором и третьем этапах процессы разбиения и объединения подграфов происходят последовательно.&lt;br /&gt;
Получаем оценку параллельной сложности алгоритма &amp;lt;math&amp;gt;O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
На вход алгоритму подается множество из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов длины &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt;, описывающих объекты для кластеризации.&lt;br /&gt;
Также передаются параметры &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (для построения графа k ближайших соседей на первом этапе) и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; (используется на втором этапе для определения критерия прекращения итерационного процесса).&lt;br /&gt;
На выходе алгоритм выдает массив длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, заполненный числами от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, показывающими, в какой кластер попал соответствующий объект.&lt;br /&gt;
&lt;br /&gt;
==Программная реализация алгоритма==&lt;br /&gt;
===Особенности реализации последовательного алгоритма===&lt;br /&gt;
===Локальность данных и вычислений===&lt;br /&gt;
===Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
===Масштабируемость алгоритма и его реализации===&lt;br /&gt;
[[Файл:Chameleo.png|300px]]&lt;br /&gt;
&lt;br /&gt;
На приведенном графике видна зависимость эффективности от объема данных и числа процессоров для реализации алгоритма, описанной в &amp;lt;ref name=&amp;quot;real&amp;quot;&amp;gt;http://research.ijcaonline.org/volume79/number8/pxc3891600.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Динамические характеристики и эффективность реализации алгоритма===&lt;br /&gt;
===Выводы для классов архитектур===&lt;br /&gt;
===Существующие реализации алгоритма===&lt;br /&gt;
Одна из последовательных реализаций алгоритма находится по ссылке [http://codeforge.com/article/192925]&lt;br /&gt;
Параллельных реализаций алгоритма найдено не было&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21754</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21754"/>
		<updated>2017-01-25T13:33:21Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В инкубаторе}}&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В рамках первого этапа макрооперацияй считается построение графа k-ближайших соседей&lt;br /&gt;
&lt;br /&gt;
В рамках второго этапа макрооперациями считаются операции разбиения подграфа.&lt;br /&gt;
&lt;br /&gt;
В рамках третьего этапа макрооперациями считаются вычисления метрики, на основании которой делается вывод о том, какие подграфы нужно объединять.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:Инфограф.png]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
На первом этапе вычисление &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших вершин для &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й вершины можно распараллелить между &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; процессами (это вычисление независимо для каждой вершины).&lt;br /&gt;
На втором и третьем этапах процессы разбиения и объединения подграфов происходят последовательно.&lt;br /&gt;
Получаем оценку параллельной сложности алгоритма &amp;lt;math&amp;gt;O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
На вход алгоритму подается множество из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов длины &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt;, описывающих объекты для кластеризации.&lt;br /&gt;
Также передаются параметры &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (для построения графа k ближайших соседей на первом этапе) и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; (используется на втором этапе для определения критерия прекращения итерационного процесса).&lt;br /&gt;
На выходе алгоритм выдает массив длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, заполненный числами от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, показывающими, в какой кластер попал соответствующий объект.&lt;br /&gt;
&lt;br /&gt;
==Программная реализация алгоритма==&lt;br /&gt;
===Особенности реализации последовательного алгоритма===&lt;br /&gt;
===Локальность данных и вычислений===&lt;br /&gt;
===Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
===Масштабируемость алгоритма и его реализации===&lt;br /&gt;
[[Файл:Chameleo.png|300px]]&lt;br /&gt;
&lt;br /&gt;
На приведенном графике видна зависимость эффективности от объема данных и числа процессоров для реализации алгоритма, описанной в &amp;lt;ref name=&amp;quot;real&amp;quot;&amp;gt;http://research.ijcaonline.org/volume79/number8/pxc3891600.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Динамические характеристики и эффективность реализации алгоритма===&lt;br /&gt;
===Выводы для классов архитектур===&lt;br /&gt;
===Существующие реализации алгоритма===&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21753</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21753"/>
		<updated>2017-01-25T13:33:13Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В инкубаторе}}&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В рамках первого этапа макрооперацияй считается построение графа k-ближайших соседей&lt;br /&gt;
&lt;br /&gt;
В рамках второго этапа макрооперациями считаются операции разбиения подграфа.&lt;br /&gt;
&lt;br /&gt;
В рамках третьего этапа макрооперациями считаются вычисления метрики, на основании которой делается вывод о том, какие подграфы нужно объединять.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:Инфограф.png]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
На первом этапе вычисление &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших вершин для &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й вершины можно распараллелить между &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; процессами (это вычисление независимо для каждой вершины).&lt;br /&gt;
На втором и третьем этапах процессы разбиения и объединения подграфов происходят последовательно.&lt;br /&gt;
Получаем оценку параллельной сложности алгоритма &amp;lt;math&amp;gt;O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
На вход алгоритму подается множество из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов длины &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt;, описывающих объекты для кластеризации.&lt;br /&gt;
Также передаются параметры &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (для построения графа k ближайших соседей на первом этапе) и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; (используется на втором этапе для определения критерия прекращения итерационного процесса).&lt;br /&gt;
На выходе алгоритм выдает массив длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, заполненный числами от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, показывающими, в какой кластер попал соответствующий объект.&lt;br /&gt;
&lt;br /&gt;
==Программная реализация алгоритма==&lt;br /&gt;
===Особенности реализации последовательного алгоритма===&lt;br /&gt;
===Локальность данных и вычислений===&lt;br /&gt;
===Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
===Масштабируемость алгоритма и его реализации===&lt;br /&gt;
[[Файл:Chameleo.png|300px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На приведенном графике видна зависимость эффективности от объема данных и числа процессоров для реализации алгоритма, описанной в &amp;lt;ref name=&amp;quot;real&amp;quot;&amp;gt;http://research.ijcaonline.org/volume79/number8/pxc3891600.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Динамические характеристики и эффективность реализации алгоритма===&lt;br /&gt;
===Выводы для классов архитектур===&lt;br /&gt;
===Существующие реализации алгоритма===&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21752</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21752"/>
		<updated>2017-01-25T13:33:03Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В инкубаторе}}&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В рамках первого этапа макрооперацияй считается построение графа k-ближайших соседей&lt;br /&gt;
&lt;br /&gt;
В рамках второго этапа макрооперациями считаются операции разбиения подграфа.&lt;br /&gt;
&lt;br /&gt;
В рамках третьего этапа макрооперациями считаются вычисления метрики, на основании которой делается вывод о том, какие подграфы нужно объединять.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:Инфограф.png]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
На первом этапе вычисление &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших вершин для &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й вершины можно распараллелить между &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; процессами (это вычисление независимо для каждой вершины).&lt;br /&gt;
На втором и третьем этапах процессы разбиения и объединения подграфов происходят последовательно.&lt;br /&gt;
Получаем оценку параллельной сложности алгоритма &amp;lt;math&amp;gt;O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
На вход алгоритму подается множество из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов длины &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt;, описывающих объекты для кластеризации.&lt;br /&gt;
Также передаются параметры &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (для построения графа k ближайших соседей на первом этапе) и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; (используется на втором этапе для определения критерия прекращения итерационного процесса).&lt;br /&gt;
На выходе алгоритм выдает массив длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, заполненный числами от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, показывающими, в какой кластер попал соответствующий объект.&lt;br /&gt;
&lt;br /&gt;
==Программная реализация алгоритма==&lt;br /&gt;
===Особенности реализации последовательного алгоритма===&lt;br /&gt;
===Локальность данных и вычислений===&lt;br /&gt;
===Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
===Масштабируемость алгоритма и его реализации===&lt;br /&gt;
[[Файл:Chameleo.png|300px]]&lt;br /&gt;
На приведенном графике видна зависимость эффективности от объема данных и числа процессоров для реализации алгоритма, описанной в &amp;lt;ref name=&amp;quot;real&amp;quot;&amp;gt;http://research.ijcaonline.org/volume79/number8/pxc3891600.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Динамические характеристики и эффективность реализации алгоритма===&lt;br /&gt;
===Выводы для классов архитектур===&lt;br /&gt;
===Существующие реализации алгоритма===&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21751</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21751"/>
		<updated>2017-01-25T13:32:52Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В инкубаторе}}&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В рамках первого этапа макрооперацияй считается построение графа k-ближайших соседей&lt;br /&gt;
&lt;br /&gt;
В рамках второго этапа макрооперациями считаются операции разбиения подграфа.&lt;br /&gt;
&lt;br /&gt;
В рамках третьего этапа макрооперациями считаются вычисления метрики, на основании которой делается вывод о том, какие подграфы нужно объединять.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:Инфограф.png]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
На первом этапе вычисление &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших вершин для &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й вершины можно распараллелить между &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; процессами (это вычисление независимо для каждой вершины).&lt;br /&gt;
На втором и третьем этапах процессы разбиения и объединения подграфов происходят последовательно.&lt;br /&gt;
Получаем оценку параллельной сложности алгоритма &amp;lt;math&amp;gt;O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
На вход алгоритму подается множество из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов длины &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt;, описывающих объекты для кластеризации.&lt;br /&gt;
Также передаются параметры &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (для построения графа k ближайших соседей на первом этапе) и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; (используется на втором этапе для определения критерия прекращения итерационного процесса).&lt;br /&gt;
На выходе алгоритм выдает массив длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, заполненный числами от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, показывающими, в какой кластер попал соответствующий объект.&lt;br /&gt;
&lt;br /&gt;
==Программная реализация алгоритма==&lt;br /&gt;
===Особенности реализации последовательного алгоритма===&lt;br /&gt;
===Локальность данных и вычислений===&lt;br /&gt;
===Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
===Масштабируемость алгоритма и его реализации===&lt;br /&gt;
[[Файл:Chameleo.png|200px|thumb|300px]]&lt;br /&gt;
На приведенном графике видна зависимость эффективности от объема данных и числа процессоров для реализации алгоритма, описанной в &amp;lt;ref name=&amp;quot;real&amp;quot;&amp;gt;http://research.ijcaonline.org/volume79/number8/pxc3891600.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Динамические характеристики и эффективность реализации алгоритма===&lt;br /&gt;
===Выводы для классов архитектур===&lt;br /&gt;
===Существующие реализации алгоритма===&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21750</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21750"/>
		<updated>2017-01-25T13:32:45Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В инкубаторе}}&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В рамках первого этапа макрооперацияй считается построение графа k-ближайших соседей&lt;br /&gt;
&lt;br /&gt;
В рамках второго этапа макрооперациями считаются операции разбиения подграфа.&lt;br /&gt;
&lt;br /&gt;
В рамках третьего этапа макрооперациями считаются вычисления метрики, на основании которой делается вывод о том, какие подграфы нужно объединять.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:Инфограф.png]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
На первом этапе вычисление &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших вершин для &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й вершины можно распараллелить между &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; процессами (это вычисление независимо для каждой вершины).&lt;br /&gt;
На втором и третьем этапах процессы разбиения и объединения подграфов происходят последовательно.&lt;br /&gt;
Получаем оценку параллельной сложности алгоритма &amp;lt;math&amp;gt;O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
На вход алгоритму подается множество из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов длины &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt;, описывающих объекты для кластеризации.&lt;br /&gt;
Также передаются параметры &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (для построения графа k ближайших соседей на первом этапе) и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; (используется на втором этапе для определения критерия прекращения итерационного процесса).&lt;br /&gt;
На выходе алгоритм выдает массив длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, заполненный числами от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, показывающими, в какой кластер попал соответствующий объект.&lt;br /&gt;
&lt;br /&gt;
==Программная реализация алгоритма==&lt;br /&gt;
===Особенности реализации последовательного алгоритма===&lt;br /&gt;
===Локальность данных и вычислений===&lt;br /&gt;
===Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
===Масштабируемость алгоритма и его реализации===&lt;br /&gt;
[[Файл:Chameleo.png|200px|thumb|300px]&lt;br /&gt;
На приведенном графике видна зависимость эффективности от объема данных и числа процессоров для реализации алгоритма, описанной в &amp;lt;ref name=&amp;quot;real&amp;quot;&amp;gt;http://research.ijcaonline.org/volume79/number8/pxc3891600.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Динамические характеристики и эффективность реализации алгоритма===&lt;br /&gt;
===Выводы для классов архитектур===&lt;br /&gt;
===Существующие реализации алгоритма===&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21749</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21749"/>
		<updated>2017-01-25T13:32:35Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В инкубаторе}}&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В рамках первого этапа макрооперацияй считается построение графа k-ближайших соседей&lt;br /&gt;
&lt;br /&gt;
В рамках второго этапа макрооперациями считаются операции разбиения подграфа.&lt;br /&gt;
&lt;br /&gt;
В рамках третьего этапа макрооперациями считаются вычисления метрики, на основании которой делается вывод о том, какие подграфы нужно объединять.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:Инфограф.png]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
На первом этапе вычисление &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших вершин для &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й вершины можно распараллелить между &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; процессами (это вычисление независимо для каждой вершины).&lt;br /&gt;
На втором и третьем этапах процессы разбиения и объединения подграфов происходят последовательно.&lt;br /&gt;
Получаем оценку параллельной сложности алгоритма &amp;lt;math&amp;gt;O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
На вход алгоритму подается множество из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов длины &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt;, описывающих объекты для кластеризации.&lt;br /&gt;
Также передаются параметры &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (для построения графа k ближайших соседей на первом этапе) и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; (используется на втором этапе для определения критерия прекращения итерационного процесса).&lt;br /&gt;
На выходе алгоритм выдает массив длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, заполненный числами от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, показывающими, в какой кластер попал соответствующий объект.&lt;br /&gt;
&lt;br /&gt;
==Программная реализация алгоритма==&lt;br /&gt;
===Особенности реализации последовательного алгоритма===&lt;br /&gt;
===Локальность данных и вычислений===&lt;br /&gt;
===Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
===Масштабируемость алгоритма и его реализации===&lt;br /&gt;
[[Файл:Chameleo.png|200px|thumb]&lt;br /&gt;
На приведенном графике видна зависимость эффективности от объема данных и числа процессоров для реализации алгоритма, описанной в &amp;lt;ref name=&amp;quot;real&amp;quot;&amp;gt;http://research.ijcaonline.org/volume79/number8/pxc3891600.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Динамические характеристики и эффективность реализации алгоритма===&lt;br /&gt;
===Выводы для классов архитектур===&lt;br /&gt;
===Существующие реализации алгоритма===&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21748</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21748"/>
		<updated>2017-01-25T13:32:23Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В инкубаторе}}&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В рамках первого этапа макрооперацияй считается построение графа k-ближайших соседей&lt;br /&gt;
&lt;br /&gt;
В рамках второго этапа макрооперациями считаются операции разбиения подграфа.&lt;br /&gt;
&lt;br /&gt;
В рамках третьего этапа макрооперациями считаются вычисления метрики, на основании которой делается вывод о том, какие подграфы нужно объединять.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:Инфограф.png]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
На первом этапе вычисление &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших вершин для &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й вершины можно распараллелить между &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; процессами (это вычисление независимо для каждой вершины).&lt;br /&gt;
На втором и третьем этапах процессы разбиения и объединения подграфов происходят последовательно.&lt;br /&gt;
Получаем оценку параллельной сложности алгоритма &amp;lt;math&amp;gt;O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
На вход алгоритму подается множество из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов длины &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt;, описывающих объекты для кластеризации.&lt;br /&gt;
Также передаются параметры &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (для построения графа k ближайших соседей на первом этапе) и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; (используется на втором этапе для определения критерия прекращения итерационного процесса).&lt;br /&gt;
На выходе алгоритм выдает массив длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, заполненный числами от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, показывающими, в какой кластер попал соответствующий объект.&lt;br /&gt;
&lt;br /&gt;
==Программная реализация алгоритма==&lt;br /&gt;
===Особенности реализации последовательного алгоритма===&lt;br /&gt;
===Локальность данных и вычислений===&lt;br /&gt;
===Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
===Масштабируемость алгоритма и его реализации===&lt;br /&gt;
[[Файл:Chameleo.png|200px]&lt;br /&gt;
На приведенном графике видна зависимость эффективности от объема данных и числа процессоров для реализации алгоритма, описанной в &amp;lt;ref name=&amp;quot;real&amp;quot;&amp;gt;http://research.ijcaonline.org/volume79/number8/pxc3891600.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Динамические характеристики и эффективность реализации алгоритма===&lt;br /&gt;
===Выводы для классов архитектур===&lt;br /&gt;
===Существующие реализации алгоритма===&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21747</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21747"/>
		<updated>2017-01-25T13:32:12Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* Программная реализация алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В инкубаторе}}&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В рамках первого этапа макрооперацияй считается построение графа k-ближайших соседей&lt;br /&gt;
&lt;br /&gt;
В рамках второго этапа макрооперациями считаются операции разбиения подграфа.&lt;br /&gt;
&lt;br /&gt;
В рамках третьего этапа макрооперациями считаются вычисления метрики, на основании которой делается вывод о том, какие подграфы нужно объединять.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:Инфограф.png]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
На первом этапе вычисление &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших вершин для &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й вершины можно распараллелить между &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; процессами (это вычисление независимо для каждой вершины).&lt;br /&gt;
На втором и третьем этапах процессы разбиения и объединения подграфов происходят последовательно.&lt;br /&gt;
Получаем оценку параллельной сложности алгоритма &amp;lt;math&amp;gt;O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
На вход алгоритму подается множество из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов длины &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt;, описывающих объекты для кластеризации.&lt;br /&gt;
Также передаются параметры &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (для построения графа k ближайших соседей на первом этапе) и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; (используется на втором этапе для определения критерия прекращения итерационного процесса).&lt;br /&gt;
На выходе алгоритм выдает массив длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, заполненный числами от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, показывающими, в какой кластер попал соответствующий объект.&lt;br /&gt;
&lt;br /&gt;
==Программная реализация алгоритма==&lt;br /&gt;
===Особенности реализации последовательного алгоритма===&lt;br /&gt;
===Локальность данных и вычислений===&lt;br /&gt;
===Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
===Масштабируемость алгоритма и его реализации===&lt;br /&gt;
[[Файл:Chameleo.png|200px|thumb|left]]&lt;br /&gt;
На приведенном графике видна зависимость эффективности от объема данных и числа процессоров для реализации алгоритма, описанной в &amp;lt;ref name=&amp;quot;real&amp;quot;&amp;gt;http://research.ijcaonline.org/volume79/number8/pxc3891600.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Динамические характеристики и эффективность реализации алгоритма===&lt;br /&gt;
===Выводы для классов архитектур===&lt;br /&gt;
===Существующие реализации алгоритма===&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21746</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21746"/>
		<updated>2017-01-25T13:31:52Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В инкубаторе}}&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В рамках первого этапа макрооперацияй считается построение графа k-ближайших соседей&lt;br /&gt;
&lt;br /&gt;
В рамках второго этапа макрооперациями считаются операции разбиения подграфа.&lt;br /&gt;
&lt;br /&gt;
В рамках третьего этапа макрооперациями считаются вычисления метрики, на основании которой делается вывод о том, какие подграфы нужно объединять.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:Инфограф.png]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
На первом этапе вычисление &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших вершин для &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й вершины можно распараллелить между &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; процессами (это вычисление независимо для каждой вершины).&lt;br /&gt;
На втором и третьем этапах процессы разбиения и объединения подграфов происходят последовательно.&lt;br /&gt;
Получаем оценку параллельной сложности алгоритма &amp;lt;math&amp;gt;O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
На вход алгоритму подается множество из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов длины &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt;, описывающих объекты для кластеризации.&lt;br /&gt;
Также передаются параметры &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (для построения графа k ближайших соседей на первом этапе) и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; (используется на втором этапе для определения критерия прекращения итерационного процесса).&lt;br /&gt;
На выходе алгоритм выдает массив длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, заполненный числами от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, показывающими, в какой кластер попал соответствующий объект.&lt;br /&gt;
&lt;br /&gt;
==Программная реализация алгоритма==&lt;br /&gt;
===Особенности реализации последовательного алгоритма===&lt;br /&gt;
===Локальность данных и вычислений===&lt;br /&gt;
===Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
===Масштабируемость алгоритма и его реализации===&lt;br /&gt;
[[Файл:Chameleo.png|200px|thumb|left]]&lt;br /&gt;
На приведенном графике видна зависимость эффективности от объема данных и числа процессоров для реализации алгоритма, описанной в &amp;lt;ref name=&amp;quot;real&amp;quot;&amp;gt;http://research.ijcaonline.org/volume79/number8/pxc3891600.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Динамические характеристики и эффективность реализации алгоритма===&lt;br /&gt;
===Выводы для классов архитектур===&lt;br /&gt;
===Существующие реализации алгоритма===&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21745</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21745"/>
		<updated>2017-01-25T13:30:20Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В инкубаторе}}&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В рамках первого этапа макрооперацияй считается построение графа k-ближайших соседей&lt;br /&gt;
&lt;br /&gt;
В рамках второго этапа макрооперациями считаются операции разбиения подграфа.&lt;br /&gt;
&lt;br /&gt;
В рамках третьего этапа макрооперациями считаются вычисления метрики, на основании которой делается вывод о том, какие подграфы нужно объединять.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:Инфограф.png]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
На первом этапе вычисление &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших вершин для &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й вершины можно распараллелить между &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; процессами (это вычисление независимо для каждой вершины).&lt;br /&gt;
На втором и третьем этапах процессы разбиения и объединения подграфов происходят последовательно.&lt;br /&gt;
Получаем оценку параллельной сложности алгоритма &amp;lt;math&amp;gt;O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
На вход алгоритму подается множество из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов длины &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt;, описывающих объекты для кластеризации.&lt;br /&gt;
Также передаются параметры &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (для построения графа k ближайших соседей на первом этапе) и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; (используется на втором этапе для определения критерия прекращения итерационного процесса).&lt;br /&gt;
На выходе алгоритм выдает массив длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, заполненный числами от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, показывающими, в какой кластер попал соответствующий объект.&lt;br /&gt;
&lt;br /&gt;
==Программная реализация алгоритма==&lt;br /&gt;
===Особенности реализации последовательного алгоритма===&lt;br /&gt;
===Локальность данных и вычислений===&lt;br /&gt;
===Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
===Масштабируемость алгоритма и его реализации===&lt;br /&gt;
[[Файл:Chameleo.png|200px|thumb|left]]&lt;br /&gt;
На приведенном графике видна зависимость эффективности от объема данных и числа процессоров для реализации алгоритма, описанной в [[2]]&lt;br /&gt;
&lt;br /&gt;
===Динамические характеристики и эффективность реализации алгоритма===&lt;br /&gt;
===Выводы для классов архитектур===&lt;br /&gt;
===Существующие реализации алгоритма===&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21744</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21744"/>
		<updated>2017-01-25T12:55:28Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В инкубаторе}}&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В рамках первого этапа макрооперацияй считается построение графа k-ближайших соседей&lt;br /&gt;
&lt;br /&gt;
В рамках второго этапа макрооперациями считаются операции разбиения подграфа.&lt;br /&gt;
&lt;br /&gt;
В рамках третьего этапа макрооперациями считаются вычисления метрики, на основании которой делается вывод о том, какие подграфы нужно объединять.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:Инфограф.png]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
На первом этапе вычисление &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших вершин для &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й вершины можно распараллелить между &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; процессами (это вычисление независимо для каждой вершины).&lt;br /&gt;
На втором и третьем этапах процессы разбиения и объединения подграфов происходят последовательно.&lt;br /&gt;
Получаем оценку параллельной сложности алгоритма &amp;lt;math&amp;gt;O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
На вход алгоритму подается множество из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов длины &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt;, описывающих объекты для кластеризации.&lt;br /&gt;
Также передаются параметры &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (для построения графа k ближайших соседей на первом этапе) и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; (используется на втором этапе для определения критерия прекращения итерационного процесса).&lt;br /&gt;
На выходе алгоритм выдает массив длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, заполненный числами от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, показывающими, в какой кластер попал соответствующий объект.&lt;br /&gt;
&lt;br /&gt;
==Программная реализация алгоритма==&lt;br /&gt;
===Особенности реализации последовательного алгоритма===&lt;br /&gt;
===Локальность данных и вычислений===&lt;br /&gt;
===Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
===Масштабируемость алгоритма и его реализации===&lt;br /&gt;
[[Файл:Chameleo.png|200px|thumb|left]]&lt;br /&gt;
&lt;br /&gt;
===Динамические характеристики и эффективность реализации алгоритма===&lt;br /&gt;
===Выводы для классов архитектур===&lt;br /&gt;
===Существующие реализации алгоритма===&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21743</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21743"/>
		<updated>2017-01-25T12:27:19Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В инкубаторе}}&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В рамках первого этапа макрооперацияй считается построение графа k-ближайших соседей&lt;br /&gt;
&lt;br /&gt;
В рамках второго этапа макрооперациями считаются операции разбиения подграфа.&lt;br /&gt;
&lt;br /&gt;
В рамках третьего этапа макрооперациями считаются вычисления метрики, на основании которой делается вывод о том, какие подграфы нужно объединять.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:Инфограф.png]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
На первом этапе вычисление &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших вершин для &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й вершины можно распараллелить между &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; процессами (это вычисление независимо для каждой вершины).&lt;br /&gt;
На втором и третьем этапах процессы разбиения и объединения подграфов происходят последовательно.&lt;br /&gt;
Получаем оценку параллельной сложности алгоритма &amp;lt;math&amp;gt;O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
На вход алгоритму подается множество из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов длины &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt;, описывающих объекты для кластеризации.&lt;br /&gt;
Также передаются параметры &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (для построения графа k ближайших соседей на первом этапе) и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; (используется на втором этапе для определения критерия прекращения итерационного процесса).&lt;br /&gt;
На выходе алгоритм выдает массив длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, заполненный числами от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, показывающими, в какой кластер попал соответствующий объект.&lt;br /&gt;
&lt;br /&gt;
==Программная реализация алгоритма==&lt;br /&gt;
===Особенности реализации последовательного алгоритма===&lt;br /&gt;
===Локальность данных и вычислений===&lt;br /&gt;
===Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
===Масштабируемость алгоритма и его реализации===&lt;br /&gt;
[[Файл:Chameleo.png]]&lt;br /&gt;
&lt;br /&gt;
===Динамические характеристики и эффективность реализации алгоритма===&lt;br /&gt;
===Выводы для классов архитектур===&lt;br /&gt;
===Существующие реализации алгоритма===&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21742</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21742"/>
		<updated>2017-01-25T12:20:58Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* Свойства и структура алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В инкубаторе}}&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В рамках первого этапа макрооперацияй считается построение графа k-ближайших соседей&lt;br /&gt;
&lt;br /&gt;
В рамках второго этапа макрооперациями считаются операции разбиения подграфа.&lt;br /&gt;
&lt;br /&gt;
В рамках третьего этапа макрооперациями считаются вычисления метрики, на основании которой делается вывод о том, какие подграфы нужно объединять.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:Инфограф.png]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
На первом этапе вычисление &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших вершин для &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й вершины можно распараллелить между &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; процессами (это вычисление независимо для каждой вершины).&lt;br /&gt;
На втором и третьем этапах процессы разбиения и объединения подграфов происходят последовательно.&lt;br /&gt;
Получаем оценку параллельной сложности алгоритма &amp;lt;math&amp;gt;O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
На вход алгоритму подается множество из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов длины &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt;, описывающих объекты для кластеризации.&lt;br /&gt;
Также передаются параметры &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (для построения графа k ближайших соседей на первом этапе) и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; (используется на втором этапе для определения критерия прекращения итерационного процесса).&lt;br /&gt;
На выходе алгоритм выдает массив длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, заполненный числами от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, показывающими, в какой кластер попал соответствующий объект.&lt;br /&gt;
&lt;br /&gt;
==Программная реализация алгоритма==&lt;br /&gt;
===Особенности реализации последовательного алгоритма===&lt;br /&gt;
===Локальность данных и вычислений===&lt;br /&gt;
===Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
===Масштабируемость алгоритма и его реализации===&lt;br /&gt;
===Динамические характеристики и эффективность реализации алгоритма===&lt;br /&gt;
===Выводы для классов архитектур===&lt;br /&gt;
===Существующие реализации алгоритма===&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Ruslanlazovskiy/CHAMELEON&amp;diff=21741</id>
		<title>Участник:Ruslanlazovskiy/CHAMELEON</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:Ruslanlazovskiy/CHAMELEON&amp;diff=21741"/>
		<updated>2017-01-25T12:19:57Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: Отмена правки 21740, сделанной участником Hromovalexander (обс.)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Algoman|Kronberg}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = CHAMELEON&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n*m + n*log{n} + m*log{m})&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; - этап 1. &amp;lt;math&amp;gt;O(q)&amp;lt;/math&amp;gt; - отдельная итерация этапа 3.&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; - этап 1. &amp;lt;math&amp;gt;O(q)&amp;lt;/math&amp;gt; - отдельная итерация этапа 3.&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n^2 / 2&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы статьи: &lt;br /&gt;
[https://algowiki-project.org/ru/%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Ruslanlazovskiy &amp;lt;b&amp;gt;Лазовский Р. А.&amp;lt;/b&amp;gt;] (разделы 1.1 - 1.4 , 1.7 , 1.8),&lt;br /&gt;
[https://algowiki-project.org/ru/%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9C%D1%83%D1%81%D1%82%D0%B0%D1%84%D0%B0%D0%B5%D0%B2_%D0%AD%D0%BB%D1%8C%D0%B2%D0%B8%D0%BD_%D0%AD%D0%BB%D1%8C%D0%BC%D0%B0%D0%BD%D0%BE%D0%B2%D0%B8%D1%87 &amp;lt;b&amp;gt;Мустафаев Э. Э.&amp;lt;/b&amp;gt;] (разделы 1.5 , 1.6 , 1.9 , 1.10 , 2.2)&lt;br /&gt;
&lt;br /&gt;
==Свойства и структура алгоритма==&lt;br /&gt;
===Общее описание алгоритма===&lt;br /&gt;
CHAMELEON – алгоритм динамической иерархической кластеризации графа, то есть процесса разбиения графа на несколько подграфов-кластеров таким образом, что данные внутри одного кластера имеют максимально схожи, а данные в разных кластерах — максимально различны. В классических алгоритмах кластеризации схожесть объектов определяется с помощью некоторой метрики (простейший пример — евклидова метрика). Не следует путать задачу кластеризации с задачей классификации: в последней характеристики объекта, необходимые для попадания в тот или иной класс, известны заранее, в рассматриваемой же задаче они становятся известны в процессе решения. Первоначально алгоритм был описан в статье&amp;lt;ref&amp;gt;CHAMELEON: A Hierarchical Clustering Algorithm Using Dynamic Modeling. George Karypis, Eui-Hong Han, Vipin Kumar. IEEE Computer 32(8): 68-75, 1999&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм CHAMELEON работает в 3 этапа. На первом этапе исходное множество объектов организуется в граф по принципу k ближайших соседей. На втором этапе этого граф разбивается на достаточно малые подграфы-кластеры. На третьем этапе происходит агломеративная иерархическая кластеризация полученных подграфов в соответствии с одной из выбранных метрик (возможные метрики будут подробно описаны далее). Число получаемых в итоге кластеров в явном виде не задаётся.&lt;br /&gt;
&lt;br /&gt;
===Математическое описание алгоритма===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Исходные данные:&amp;lt;/b&amp;gt; Первоначально исходными данными алгоритма являются &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов длины &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, каждый из которых соответствует одному объекту. На основании значений элементов этих векторов строится матрица смежности размера &amp;lt;math&amp;gt;n * n&amp;lt;/math&amp;gt;, возможно сокращение требуемого объема памяти до &amp;lt;math&amp;gt;(n*(n - 1))/ 2&amp;lt;/math&amp;gt; в соответствии с выбранной метрикой. К исходным данным также относится набор параметров. Это &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - количество ближайших соседей на первом этапе алгоритма, &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - отношение количества вершин в наибольшем подграфе по отношению к общему числу объектов на втором этапе алгоритма, а также параметры &amp;lt;math&amp;gt;T_{RI}, T_{RI}&amp;lt;/math&amp;gt; - пороговые значения, после которых прекращается агломеративная кластеризация на третьем этапе. Следует особо отметить, что число получаемых в итоге кластеров заранее не известно, хотя на него и можно повлиять изменением значений перечисленных параметров.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Первый этап алгоритма:&amp;lt;/b&amp;gt; На первом этапе на основании матрицы смежности строится граф &amp;lt;math&amp;gt;G = (V, E)&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших соседей, где &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин графа (т.е. объекты), а &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер графа (т.е. построенные связи между ближайшими соседями). Указанный граф не обязательно является связным.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Второй этап алгоритма:&amp;lt;/b&amp;gt; Граф &amp;lt;math&amp;gt;G = (V, E)&amp;lt;/math&amp;gt; итеративно разбивается на множество подграфов &amp;lt;math&amp;gt;G_{i} = (V_{i}, E_{i}), i = 1 .. m&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; \cup V_{i} = V, i = 1 .. m&amp;lt;/math&amp;gt;. Параметр &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; явно не задаётся, выполнение этого этапа алгоритма прекращается по выполнении описанных далее условий. На каждой итерации выбирается &amp;lt;math&amp;gt;G_{b}&amp;lt;/math&amp;gt; с числом вершин, наибольшим среди всех подграфов, имеющихся на данной итерации. Этот граф разбивается на 2 подграфа &amp;lt;math&amp;gt;G_{bi}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_{bj}&amp;lt;/math&amp;gt; таких, что 1) &amp;lt;math&amp;gt;min(V_{bi},V_{bj}) &amp;gt;= 0.25 * V_{b}&amp;lt;/math&amp;gt; (имеется ввиду количество вершин) и 2) &amp;lt;math&amp;gt;\sum{E_{kl}}, E_{kl} = (v_{k}, v_{l}), v_{k} \in V_{bi} , v_{l} \in V_{bj} &amp;lt;/math&amp;gt; минимальна среди всех разбиений, удовлетворяющих 1). Итеративный процесс прекращается, когда &amp;lt;math&amp;gt;\sum{v_{b}} &amp;lt;= q * \sum{v} , v_{b} \in V_{b} , e \in E&amp;lt;/math&amp;gt; (имеется ввиду количество вершин). Здесь &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - задаваемый параметр, на практике он варьируется от &amp;lt;math&amp;gt;0.01&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;0.05&amp;lt;/math&amp;gt;. Полученные подграфы называются малыми кластерами.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Третий этап алгоритма:&amp;lt;/b&amp;gt; Множество кластеров &amp;lt;math&amp;gt;G_{i} = (V_{i}, E_{i}), i = 1 .. m&amp;lt;/math&amp;gt; итеративно преобразуется в множество кластеров &amp;lt;math&amp;gt;G_{j} = (V_{j}, E_{j}), j = 1 .. l&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;l &amp;lt;= m&amp;lt;/math&amp;gt;. Для этого вводятся следующие понятия:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;EC_{(C_{i},C_{j})}&amp;lt;/math&amp;gt; - абсолютная взаимная связность пары кластеров &amp;lt;math&amp;gt;C_{i}, C{j}&amp;lt;/math&amp;gt;. Это суть сумма весов ребер, соединяющих вершины, принадлежащие &amp;lt;math&amp;gt;C{i}&amp;lt;/math&amp;gt; c вершинами из &amp;lt;math&amp;gt;C{j}&amp;lt;/math&amp;gt;. &amp;lt;math&amp;gt;EC_{(C_{i},C_{i})}&amp;lt;/math&amp;gt; вычисляется как сумма ребер, входящих в разделитель, разбивающий &amp;lt;math&amp;gt;C{i}&amp;lt;/math&amp;gt; на два равных подграфа.&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;S_{EC_{(C_{i},C_{j})}}&amp;lt;/math&amp;gt; - абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;C_{i}, C{j}&amp;lt;/math&amp;gt;. Это суть среднее сходство между соединенными вершинами, принадлежащими &amp;lt;math&amp;gt;C{i}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C{j}&amp;lt;/math&amp;gt; соответственно. Соединения обусловлены разбиением общего графа, полученного на первом этапе алгоритма.&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;RI_{(C_{i},C_{j})} = \frac{2*|EC_{(C_{i},C_{j})}|}{|EC_{C_{i}}|+|EC_{C_{j}}|}&amp;lt;/math&amp;gt; - относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;C_{i}, C{j}&amp;lt;/math&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt; RC_{(C_{i},C_{j})}= \frac{S_{EC_{(C_{i},C_{j})}}}{\frac{|C_{i}|}{|C_{i}+C_{j}|}*S_{EC_{(C_{i})}}+\frac{|C_{i}|}{|C_{i}+C_{j}|}*S_{EC_{(C_{j})}}}&amp;lt;/math&amp;gt; - относительное взаимное сходство пары кластеров &amp;lt;math&amp;gt;C_{i}, C{j}&amp;lt;/math&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На основании этих показателей осуществляется агломеративная иерерхическая кластеризация. Существует две стратегии анализа показателей сходства. В первом случае для каждой пары кластеров &amp;lt;math&amp;gt;C{i}, C{j}&amp;lt;/math&amp;gt; проверяется истинность выражений &amp;lt;math&amp;gt;RI_{(C_{i},C_{j})} &amp;gt;= T_{RI}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})} &amp;gt;= T_{RC}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;T_{RI}, T_{RI}&amp;lt;/math&amp;gt; - заранее заданные пороговые значения. Если для некоторого &amp;lt;math&amp;gt;C_{i}&amp;lt;/math&amp;gt; таких &amp;lt;math&amp;gt;C_{j}&amp;lt;/math&amp;gt; несколько, то конкретная пара определяется по максимуму значения &amp;lt;math&amp;gt;EC_{(C_{i},C_{j})}&amp;lt;/math&amp;gt;. Во втором случае выбираются пары кластеров, максимизирующие функцию вида &amp;lt;math&amp;gt;RI_{(C_{i},C_{j})}*RC_{(C_{i},C_{j})}^\alpha&amp;lt;/math&amp;gt;. Здесь &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный пользователем параметр. В обоих случаях процесс останавливается либо когда на очередной итерации не находится подходящих пар кластеров, либо когда остаётся только один кластер.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Вычисляемые данные:&amp;lt;/b&amp;gt; В процессе агломеративной кластеризации для всех объектов, т.е. всех вершин всех кластеров указывается индекс &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; кластера, к которому они принадлежат. После завершения алгоритма возможно перенумеровать кластеры. В любом случае на выходе будет иметься &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; значений, так как число объектов в процессе работы алгоритма не изменялось.&lt;br /&gt;
&lt;br /&gt;
===Вычислительное ядро алгоритма===&lt;br /&gt;
В алгоритме 3 основных вычислительных ядра, по одному на каждый этап алгоритма.&lt;br /&gt;
&lt;br /&gt;
На первом этапе алгоритма основная вычислительная нагрузка приходится на анализ матрицы смежности, необходимого для построения первоначального графа &amp;lt;math&amp;gt;G = (V, E)&amp;lt;/math&amp;gt;, так как для каждого объекта необходимо перебрать всех его соседей и выделить &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших по заданной метрике.&lt;br /&gt;
&lt;br /&gt;
На втором этапе наибольшее время занимает поиск подходящего разбиения очередного подграфа. В элементарном варианте этой процедуры необходимо перебрать все комбинации вершин в этом подграфе, удовлетворяющие условию 1) из математического описания алгоритма, и для каждой из них подсчитать значение, используемое в 2). &lt;br /&gt;
&lt;br /&gt;
На третьем этапе алгоритма вычислительное ядро полностью совпадает с самим этапом, то есть итерационным процессов агломеративной иерархической кластеризации, включающем в себя подсчёт выбранной метрики для каждой пары кластеров, имеющихся на очередной итерации.&lt;br /&gt;
&lt;br /&gt;
===Макроструктура алгоритма===&lt;br /&gt;
Как уже понятно из предыдущих разделов описания, алгоритм CHAMELEON выполняется в 3 этапа, последовательных относительно друг друга. Каждый этап, строго говоря, соответствует отдельному алгоритму. В рамках этого описания макрооперациями будут считаться процедуры разбиения наибольшего подграфа на каждой итерации второго этапа алгоритма, а также процедура вычисления метрики для принятия решения об объединении кластеров на каждой итерации третьего этапа.&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;
 // First stage.&lt;br /&gt;
 int k // Number of neighbors.&lt;br /&gt;
 float v[n][p] // Initial vectors.&lt;br /&gt;
 float M[n][n] // Adjacency matrix.&lt;br /&gt;
 for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
  for (int l = 0; l &amp;lt; n; ++l) {&lt;br /&gt;
   M[i][l] = Compute_metric(v[i],v[l]);&lt;br /&gt;
  }&lt;br /&gt;
 }&lt;br /&gt;
 Graph max_graph // Structure/class that represents a graph.&lt;br /&gt;
 Neighbor_list list // Here neighbors are initially stored.&lt;br /&gt;
 max_graph.add_vertices // Vertices ~ initial vectors.&lt;br /&gt;
 for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
  for (int l = i + 1; i &amp;lt; n; ++i) { // &amp;quot;Smart&amp;quot; version - we do not repeat same vertex combinations.&lt;br /&gt;
   if (neighbor_number &amp;lt; k) {&lt;br /&gt;
     add_neighbor(v[i],v[l]) // Just add.&lt;br /&gt;
   }else{&lt;br /&gt;
     substitute_neighbor(v[i],v[l]) // Check whether a new element is closer than some of the oldies.&lt;br /&gt;
   }&lt;br /&gt;
  }&lt;br /&gt;
  max_graph.add_neighbors // Looks at neighbor lists of current vector and adds them&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
 // Second stage. &lt;br /&gt;
 float percent // Determines when to stop splitting graphs. &lt;br /&gt;
 Graph graphs[n] // GRAPHS WILL MOST LIKELY TAKE LESS SPACE, IT&#039;S JUST THE UPPER LIMIT. &lt;br /&gt;
 max_graph = find_max_graph() // Biggest graph by number of vertices available. &lt;br /&gt;
 while (graph_size(max_graph) &amp;gt; n * percent) {&lt;br /&gt;
   Split_graph(max_graph); // Split the graph - a macro operation that represents the second phase.&lt;br /&gt;
 } &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
 // Third stage. &lt;br /&gt;
 Graph graphs[m] // That&#039;s how many graphs we got. m &amp;lt;= n. &lt;br /&gt;
 bool pairs_exist // Check if the&#039;re pairs of clusters to unite.&lt;br /&gt;
 while (num_graphs &amp;gt; 1 &amp;amp;&amp;amp; pairs_exist){&lt;br /&gt;
  pairs_exist = false // So we don&#039;t repeat if it fails.&lt;br /&gt;
  for (int i = 0; i &amp;lt; m; ++i) {&lt;br /&gt;
   for (int l = i + 1; l &amp;lt; m; ++l) { // Also a &amp;quot;Smart&amp;quot; version.&lt;br /&gt;
     check_pair(pairs_exist, graphs[i], graphs[l]); // Check whether graphs are similar enough by some metrics.&lt;br /&gt;
     if (pairs_exist) { Unite_graphs(graphs[i], graphs[l]) }; // Pairs_exist is set to true if something&#039;s found.&lt;br /&gt;
   }&lt;br /&gt;
  }&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Последовательная сложность алгоритма===&lt;br /&gt;
&lt;br /&gt;
Общая временная сложность последовательного варианта алгоритма CHAMELEON определяется как &amp;lt;math&amp;gt;O(nm + nlog{n} + mlog{m})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число исходных объектов, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - число малых кластеров, полученных после первого этапа работы. В случае &amp;quot;предельного&amp;quot; разбиения &amp;lt;math&amp;gt;m = n&amp;lt;/math&amp;gt; эта оценка превращается в &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;. В любом случае эта оценка не учитывает необходимости построения матрицы смежности по исходному набору векторов (авторы оригинальной статьи в своих исследованиях подразумевают, что матрица смежности уже построена), что означает дополнительные &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Тогда оценка будет составлять &amp;lt;math&amp;gt;O(n^2 + nm + nlog{n} + mlog{m})&amp;lt;/math&amp;gt; операций или &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; в случае &amp;quot;предельного&amp;quot; разбиения.&lt;br /&gt;
Следует также обратить внимание, что это оценка по числу не сложений и умножений, а достаточно крупных операций. Например, вычисление метрики между двумя векторами рассматривается как одна операция, а она включает в себя &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений (для вычисления квадратичной нормы разности векторов).&lt;br /&gt;
&lt;br /&gt;
===Информационный граф===&lt;br /&gt;
&lt;br /&gt;
Информационный граф дан в соответствии с макроструктурой алгоритма. Следует отметить, что имеются успешные попытки распараллелить 2 и 3 этапы алгоритма CHAMELEON (см. раздел &amp;quot;Существующие реализации&amp;quot;). Однако они включают в себя модификацию исходного алгоритма. Также возможно распараллеливание выборки пар кластеров и подсчёта их метрик внутри каждой из вершин stage_3_iter. Структура информационного графа внутри этих итераций аналогична структуре информационного графа первого этапа алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[File:CHAMELEON ruslanlazovskiy.png]]&lt;br /&gt;
&lt;br /&gt;
===Ресурс параллелизма алгоритма===&lt;br /&gt;
&lt;br /&gt;
Параллельную сложность алгоритма CHAMELEON следует оценивать отдельно для каждого этапа.&lt;br /&gt;
На первом этапе алгоритм поиска &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших соседей может быть выполнен за &amp;lt;math&amp;gt;n - 1&amp;lt;/math&amp;gt; вычислений значения метрики между двумя векторами.&lt;br /&gt;
На втором этапе итерации алгоритма выполняются строго последовательно, а распараллеливание алгоритма внутри итерации не относится к теме статьи.&lt;br /&gt;
На третьем этапе итерации также выполняются последовательно, однако возможно распараллеливание обработки пар кластеров внутри итерации. Каждая итерация может быть выполнена за &amp;lt;math&amp;gt;q - 1&amp;lt;/math&amp;gt; вычислений значения метрики между двумя кластерами, где q - количество кластеров на этой итерации.&lt;br /&gt;
&lt;br /&gt;
===Входные и выходные данные алгоритма===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;O&amp;lt;/math&amp;gt; - набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов длины &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;. &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - число, определяющиее количество ближайших соседей, по которым строится первоначальный граф. &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; - вектор длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, значение &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го элемента указывает на принадлежность соответствующего вектора одному из кластеров.&lt;br /&gt;
&lt;br /&gt;
===Свойства алгоритма===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности:&amp;lt;/b&amp;gt; Различные этапы алгоритма строго последовательны относительно друг друга. На первом этапе отношение последовательной сложности алгоритма к параллельной есть &amp;lt;math&amp;gt;n/2&amp;lt;/math&amp;gt;. На втором и третьем этапах различные итерации последовательны относительно друг друга. Однако внутри итераций допускается некоторый параллелизм. Например, для итераций третьего этапа в наилучшем случае отношение сложности последовательной реализации к параллельной есть &amp;lt;math&amp;gt;q/2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - число кластеров на конкретной итерации.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Вычислительная мощность:&amp;lt;/b&amp;gt; графовые алгоритмы, вообще говоря, обладают низкой вычислительной мощностью. В случае CHAMELEON вычислительная мощность первого этапа равна &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;. Для второго и третьего этапов оценка вычислительной мощности по сложениям и умножениям затруднительна, однако в терминах макроопераций можно дать грубую оценку. Вычислительная мощность каждой итерации второго этапа - &amp;lt;math&amp;gt;1 / \sum C_n^k&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число вершин в выбранном подграфе, а &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; варьируется от &amp;lt;math&amp;gt;0.25 * n&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;0.5 * n&amp;lt;/math&amp;gt;. Вычислительная мощность каждой итерации третьего этапа в этих терминах - &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Детерминированность:&amp;lt;/b&amp;gt; Важной особенностью описываемого алгоритма является его недетерминированность. Условия завершения как 2-го, так и 3-го этапа позволяют обозначить CHAMELEON как итерационный алгоритм с выходом по точности. При этом детерминированность 2-го этапа алгоритма можно обеспечить указанием вырожденных условий кластеризации (такая кластеризация, очевидно, не будет иметь практического смысла), в то время как 2-ый этап является недетерминированным всегда.&lt;br /&gt;
&lt;br /&gt;
==Программная реализация алгоритма==&lt;br /&gt;
===Особенности реализации последовательного алгоритма===&lt;br /&gt;
===Локальность данных и вычислений===&lt;br /&gt;
===Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
===Масштабируемость алгоритма и его реализации===&lt;br /&gt;
&lt;br /&gt;
Как можно увидеть из раздела &amp;quot;существующие реализации&amp;quot;, параллельной реализации алгоритма CHAMELEON на система с распределенной памятью найдено не было. Однако в &amp;lt;ref name = &amp;quot;exp&amp;quot;&amp;gt;Parallel Algorithm for the Chameleon Clustering Algorithm using Dynamic Modeling.  Rajnish Dashora, Harsh Bajaj, Akshat Dube, Geetha Mary .A. VIT University,Vellore. International Journal of Computer Applications (0975 – 8887) Volume 79 – No8, October 2013 &amp;lt;/ref&amp;gt;. приводится экспериментальный вариант параллельной реализации посредством OpenMP для систем с общей памятью, включающий в себя значительную модификацию исходного алгоритма, но не приводится рабочая реализация.&lt;br /&gt;
&lt;br /&gt;
В силу вышескасновного основное внимание будет уделено исследованию масштабируемости алгоритма по размеру задачи, в пределах одного узла. Далее приводятся графики производительности в Гфлопс для различных размеров задачи. Эффективность работы алгоритма убывает на всей рассматриваемой области. Темпы убывания эффективности снижаются с ростом размера задачи.&lt;br /&gt;
&lt;br /&gt;
Для исследования такой масштабируемости вширь использовалась референсная последовательная реализация алгоритма (cм. раздел &amp;quot;Существующие реализации&amp;quot;). Соответствующая программа запускалась на системе BG/P на одном вычислительном узле. Характеристики вычислительного узла, а также микропроцессорного ядра - элемента такого узла, приводятся в &amp;lt;ref&amp;gt;http://hpc.cmc.msu.ru/bgp&amp;lt;/ref&amp;gt; Таким образом, удостоверенными экспериментальными данными являются только значения, полученные для случая 1 процесса. Значения для случаев 2 и 4 процессов являются ОЦЕНОЧНЫМИ и выводятся из результатов работы модифицированной версии алгоритма, исследуемой в &amp;lt;ref name = &amp;quot;exp&amp;quot;&amp;gt;Parallel Algorithm for the Chameleon Clustering Algorithm using Dynamic Modeling.  Rajnish Dashora, Harsh Bajaj, Akshat Dube, Geetha Mary .A. VIT University,Vellore. International Journal of Computer Applications (0975 – 8887) Volume 79 – No8, October 2013 &amp;lt;/ref&amp;gt;. К сожалению, указанной реализации авторы не предоставляют. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:CHAMELEON performance.png|800px]]&lt;br /&gt;
&lt;br /&gt;
===Динамические характеристики и эффективность реализации алгоритма===&lt;br /&gt;
===Выводы для классов архитектур===&lt;br /&gt;
===Существующие реализации алгоритма===&lt;br /&gt;
С копией референсной реализации иерархической кластеризации, взятой с данного ресурса [http://us.codeforge.com/article/192925 Sequental], в случае неработоспособности последнего, можно ознакомиться здесь [http://pastebin.com/PhC4X0Cy Copy]&amp;lt;br/&amp;gt;&lt;br /&gt;
Последовательная реализация алгоритма CHAMELEON использовалась в статье &amp;lt;ref&amp;gt;Clustering Of Web Usage Data Using&lt;br /&gt;
Chameleon Algorithm, T.Vijaya Kumar, Dr. H.S.Guruprasad, International Journal of Innovative Research in Computer&lt;br /&gt;
and Communication Engineering, Vol. 2, Issue 6, June 2014&amp;lt;/ref&amp;gt;&lt;br /&gt;
Теоретически возможна реализация алгоритма CHAMELEON с использованием графовых библиотек, например [http://glaros.dtc.umn.edu/gkhome/metis/metis/overview METIS ], [http://glaros.dtc.umn.edu/gkhome/metis/hmetis/overview hMETIS] и [https://cran.r-project.org/web/packages/RANN/index.html RANN].&amp;lt;br/&amp;gt;&lt;br /&gt;
Параллельных реализаций алгоритма CHAMELEON в графовых библиотеках мною найдено не было. Однако существует исследование, связанное с реализацией CHAMELEON посредством технологии OpenMP, с которым можно ознакомиться здесь [http://research.ijcaonline.org/volume79/number8/pxc3891600.pdf параллельная реализация].&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Краткий обзор алгоритма [http://studopedia.ru/7_41934_algoritm-dinamicheskoy-ierarhicheskoy-klasterizatsii-CHAMELEON.html|]&amp;lt;br/&amp;gt;&lt;br /&gt;
Первоначальная статья от авторов алгоритма [http://www-users.cs.umn.edu/~han/dmclass/chameleon.pdf|]&amp;lt;br/&amp;gt;&lt;br /&gt;
Исследования возможной параллелизации алгоритма[http://research.ijcaonline.org/volume79/number8/pxc3891600.pdf|]&amp;lt;br/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Ruslanlazovskiy/CHAMELEON&amp;diff=21740</id>
		<title>Участник:Ruslanlazovskiy/CHAMELEON</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:Ruslanlazovskiy/CHAMELEON&amp;diff=21740"/>
		<updated>2017-01-25T12:19:25Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* Программная реализация алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Algoman|Kronberg}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = CHAMELEON&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n*m + n*log{n} + m*log{m})&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; - этап 1. &amp;lt;math&amp;gt;O(q)&amp;lt;/math&amp;gt; - отдельная итерация этапа 3.&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; - этап 1. &amp;lt;math&amp;gt;O(q)&amp;lt;/math&amp;gt; - отдельная итерация этапа 3.&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n^2 / 2&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы статьи: &lt;br /&gt;
[https://algowiki-project.org/ru/%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Ruslanlazovskiy &amp;lt;b&amp;gt;Лазовский Р. А.&amp;lt;/b&amp;gt;] (разделы 1.1 - 1.4 , 1.7 , 1.8),&lt;br /&gt;
[https://algowiki-project.org/ru/%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%9C%D1%83%D1%81%D1%82%D0%B0%D1%84%D0%B0%D0%B5%D0%B2_%D0%AD%D0%BB%D1%8C%D0%B2%D0%B8%D0%BD_%D0%AD%D0%BB%D1%8C%D0%BC%D0%B0%D0%BD%D0%BE%D0%B2%D0%B8%D1%87 &amp;lt;b&amp;gt;Мустафаев Э. Э.&amp;lt;/b&amp;gt;] (разделы 1.5 , 1.6 , 1.9 , 1.10 , 2.2)&lt;br /&gt;
&lt;br /&gt;
==Свойства и структура алгоритма==&lt;br /&gt;
===Общее описание алгоритма===&lt;br /&gt;
CHAMELEON – алгоритм динамической иерархической кластеризации графа, то есть процесса разбиения графа на несколько подграфов-кластеров таким образом, что данные внутри одного кластера имеют максимально схожи, а данные в разных кластерах — максимально различны. В классических алгоритмах кластеризации схожесть объектов определяется с помощью некоторой метрики (простейший пример — евклидова метрика). Не следует путать задачу кластеризации с задачей классификации: в последней характеристики объекта, необходимые для попадания в тот или иной класс, известны заранее, в рассматриваемой же задаче они становятся известны в процессе решения. Первоначально алгоритм был описан в статье&amp;lt;ref&amp;gt;CHAMELEON: A Hierarchical Clustering Algorithm Using Dynamic Modeling. George Karypis, Eui-Hong Han, Vipin Kumar. IEEE Computer 32(8): 68-75, 1999&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм CHAMELEON работает в 3 этапа. На первом этапе исходное множество объектов организуется в граф по принципу k ближайших соседей. На втором этапе этого граф разбивается на достаточно малые подграфы-кластеры. На третьем этапе происходит агломеративная иерархическая кластеризация полученных подграфов в соответствии с одной из выбранных метрик (возможные метрики будут подробно описаны далее). Число получаемых в итоге кластеров в явном виде не задаётся.&lt;br /&gt;
&lt;br /&gt;
===Математическое описание алгоритма===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Исходные данные:&amp;lt;/b&amp;gt; Первоначально исходными данными алгоритма являются &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов длины &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, каждый из которых соответствует одному объекту. На основании значений элементов этих векторов строится матрица смежности размера &amp;lt;math&amp;gt;n * n&amp;lt;/math&amp;gt;, возможно сокращение требуемого объема памяти до &amp;lt;math&amp;gt;(n*(n - 1))/ 2&amp;lt;/math&amp;gt; в соответствии с выбранной метрикой. К исходным данным также относится набор параметров. Это &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - количество ближайших соседей на первом этапе алгоритма, &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - отношение количества вершин в наибольшем подграфе по отношению к общему числу объектов на втором этапе алгоритма, а также параметры &amp;lt;math&amp;gt;T_{RI}, T_{RI}&amp;lt;/math&amp;gt; - пороговые значения, после которых прекращается агломеративная кластеризация на третьем этапе. Следует особо отметить, что число получаемых в итоге кластеров заранее не известно, хотя на него и можно повлиять изменением значений перечисленных параметров.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Первый этап алгоритма:&amp;lt;/b&amp;gt; На первом этапе на основании матрицы смежности строится граф &amp;lt;math&amp;gt;G = (V, E)&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших соседей, где &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин графа (т.е. объекты), а &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер графа (т.е. построенные связи между ближайшими соседями). Указанный граф не обязательно является связным.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Второй этап алгоритма:&amp;lt;/b&amp;gt; Граф &amp;lt;math&amp;gt;G = (V, E)&amp;lt;/math&amp;gt; итеративно разбивается на множество подграфов &amp;lt;math&amp;gt;G_{i} = (V_{i}, E_{i}), i = 1 .. m&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; \cup V_{i} = V, i = 1 .. m&amp;lt;/math&amp;gt;. Параметр &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; явно не задаётся, выполнение этого этапа алгоритма прекращается по выполнении описанных далее условий. На каждой итерации выбирается &amp;lt;math&amp;gt;G_{b}&amp;lt;/math&amp;gt; с числом вершин, наибольшим среди всех подграфов, имеющихся на данной итерации. Этот граф разбивается на 2 подграфа &amp;lt;math&amp;gt;G_{bi}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_{bj}&amp;lt;/math&amp;gt; таких, что 1) &amp;lt;math&amp;gt;min(V_{bi},V_{bj}) &amp;gt;= 0.25 * V_{b}&amp;lt;/math&amp;gt; (имеется ввиду количество вершин) и 2) &amp;lt;math&amp;gt;\sum{E_{kl}}, E_{kl} = (v_{k}, v_{l}), v_{k} \in V_{bi} , v_{l} \in V_{bj} &amp;lt;/math&amp;gt; минимальна среди всех разбиений, удовлетворяющих 1). Итеративный процесс прекращается, когда &amp;lt;math&amp;gt;\sum{v_{b}} &amp;lt;= q * \sum{v} , v_{b} \in V_{b} , e \in E&amp;lt;/math&amp;gt; (имеется ввиду количество вершин). Здесь &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - задаваемый параметр, на практике он варьируется от &amp;lt;math&amp;gt;0.01&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;0.05&amp;lt;/math&amp;gt;. Полученные подграфы называются малыми кластерами.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Третий этап алгоритма:&amp;lt;/b&amp;gt; Множество кластеров &amp;lt;math&amp;gt;G_{i} = (V_{i}, E_{i}), i = 1 .. m&amp;lt;/math&amp;gt; итеративно преобразуется в множество кластеров &amp;lt;math&amp;gt;G_{j} = (V_{j}, E_{j}), j = 1 .. l&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;l &amp;lt;= m&amp;lt;/math&amp;gt;. Для этого вводятся следующие понятия:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;EC_{(C_{i},C_{j})}&amp;lt;/math&amp;gt; - абсолютная взаимная связность пары кластеров &amp;lt;math&amp;gt;C_{i}, C{j}&amp;lt;/math&amp;gt;. Это суть сумма весов ребер, соединяющих вершины, принадлежащие &amp;lt;math&amp;gt;C{i}&amp;lt;/math&amp;gt; c вершинами из &amp;lt;math&amp;gt;C{j}&amp;lt;/math&amp;gt;. &amp;lt;math&amp;gt;EC_{(C_{i},C_{i})}&amp;lt;/math&amp;gt; вычисляется как сумма ребер, входящих в разделитель, разбивающий &amp;lt;math&amp;gt;C{i}&amp;lt;/math&amp;gt; на два равных подграфа.&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;S_{EC_{(C_{i},C_{j})}}&amp;lt;/math&amp;gt; - абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;C_{i}, C{j}&amp;lt;/math&amp;gt;. Это суть среднее сходство между соединенными вершинами, принадлежащими &amp;lt;math&amp;gt;C{i}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C{j}&amp;lt;/math&amp;gt; соответственно. Соединения обусловлены разбиением общего графа, полученного на первом этапе алгоритма.&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;RI_{(C_{i},C_{j})} = \frac{2*|EC_{(C_{i},C_{j})}|}{|EC_{C_{i}}|+|EC_{C_{j}}|}&amp;lt;/math&amp;gt; - относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;C_{i}, C{j}&amp;lt;/math&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt; RC_{(C_{i},C_{j})}= \frac{S_{EC_{(C_{i},C_{j})}}}{\frac{|C_{i}|}{|C_{i}+C_{j}|}*S_{EC_{(C_{i})}}+\frac{|C_{i}|}{|C_{i}+C_{j}|}*S_{EC_{(C_{j})}}}&amp;lt;/math&amp;gt; - относительное взаимное сходство пары кластеров &amp;lt;math&amp;gt;C_{i}, C{j}&amp;lt;/math&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На основании этих показателей осуществляется агломеративная иерерхическая кластеризация. Существует две стратегии анализа показателей сходства. В первом случае для каждой пары кластеров &amp;lt;math&amp;gt;C{i}, C{j}&amp;lt;/math&amp;gt; проверяется истинность выражений &amp;lt;math&amp;gt;RI_{(C_{i},C_{j})} &amp;gt;= T_{RI}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})} &amp;gt;= T_{RC}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;T_{RI}, T_{RI}&amp;lt;/math&amp;gt; - заранее заданные пороговые значения. Если для некоторого &amp;lt;math&amp;gt;C_{i}&amp;lt;/math&amp;gt; таких &amp;lt;math&amp;gt;C_{j}&amp;lt;/math&amp;gt; несколько, то конкретная пара определяется по максимуму значения &amp;lt;math&amp;gt;EC_{(C_{i},C_{j})}&amp;lt;/math&amp;gt;. Во втором случае выбираются пары кластеров, максимизирующие функцию вида &amp;lt;math&amp;gt;RI_{(C_{i},C_{j})}*RC_{(C_{i},C_{j})}^\alpha&amp;lt;/math&amp;gt;. Здесь &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный пользователем параметр. В обоих случаях процесс останавливается либо когда на очередной итерации не находится подходящих пар кластеров, либо когда остаётся только один кластер.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Вычисляемые данные:&amp;lt;/b&amp;gt; В процессе агломеративной кластеризации для всех объектов, т.е. всех вершин всех кластеров указывается индекс &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; кластера, к которому они принадлежат. После завершения алгоритма возможно перенумеровать кластеры. В любом случае на выходе будет иметься &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; значений, так как число объектов в процессе работы алгоритма не изменялось.&lt;br /&gt;
&lt;br /&gt;
===Вычислительное ядро алгоритма===&lt;br /&gt;
В алгоритме 3 основных вычислительных ядра, по одному на каждый этап алгоритма.&lt;br /&gt;
&lt;br /&gt;
На первом этапе алгоритма основная вычислительная нагрузка приходится на анализ матрицы смежности, необходимого для построения первоначального графа &amp;lt;math&amp;gt;G = (V, E)&amp;lt;/math&amp;gt;, так как для каждого объекта необходимо перебрать всех его соседей и выделить &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших по заданной метрике.&lt;br /&gt;
&lt;br /&gt;
На втором этапе наибольшее время занимает поиск подходящего разбиения очередного подграфа. В элементарном варианте этой процедуры необходимо перебрать все комбинации вершин в этом подграфе, удовлетворяющие условию 1) из математического описания алгоритма, и для каждой из них подсчитать значение, используемое в 2). &lt;br /&gt;
&lt;br /&gt;
На третьем этапе алгоритма вычислительное ядро полностью совпадает с самим этапом, то есть итерационным процессов агломеративной иерархической кластеризации, включающем в себя подсчёт выбранной метрики для каждой пары кластеров, имеющихся на очередной итерации.&lt;br /&gt;
&lt;br /&gt;
===Макроструктура алгоритма===&lt;br /&gt;
Как уже понятно из предыдущих разделов описания, алгоритм CHAMELEON выполняется в 3 этапа, последовательных относительно друг друга. Каждый этап, строго говоря, соответствует отдельному алгоритму. В рамках этого описания макрооперациями будут считаться процедуры разбиения наибольшего подграфа на каждой итерации второго этапа алгоритма, а также процедура вычисления метрики для принятия решения об объединении кластеров на каждой итерации третьего этапа.&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;
 // First stage.&lt;br /&gt;
 int k // Number of neighbors.&lt;br /&gt;
 float v[n][p] // Initial vectors.&lt;br /&gt;
 float M[n][n] // Adjacency matrix.&lt;br /&gt;
 for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
  for (int l = 0; l &amp;lt; n; ++l) {&lt;br /&gt;
   M[i][l] = Compute_metric(v[i],v[l]);&lt;br /&gt;
  }&lt;br /&gt;
 }&lt;br /&gt;
 Graph max_graph // Structure/class that represents a graph.&lt;br /&gt;
 Neighbor_list list // Here neighbors are initially stored.&lt;br /&gt;
 max_graph.add_vertices // Vertices ~ initial vectors.&lt;br /&gt;
 for (int i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;
  for (int l = i + 1; i &amp;lt; n; ++i) { // &amp;quot;Smart&amp;quot; version - we do not repeat same vertex combinations.&lt;br /&gt;
   if (neighbor_number &amp;lt; k) {&lt;br /&gt;
     add_neighbor(v[i],v[l]) // Just add.&lt;br /&gt;
   }else{&lt;br /&gt;
     substitute_neighbor(v[i],v[l]) // Check whether a new element is closer than some of the oldies.&lt;br /&gt;
   }&lt;br /&gt;
  }&lt;br /&gt;
  max_graph.add_neighbors // Looks at neighbor lists of current vector and adds them&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
 // Second stage. &lt;br /&gt;
 float percent // Determines when to stop splitting graphs. &lt;br /&gt;
 Graph graphs[n] // GRAPHS WILL MOST LIKELY TAKE LESS SPACE, IT&#039;S JUST THE UPPER LIMIT. &lt;br /&gt;
 max_graph = find_max_graph() // Biggest graph by number of vertices available. &lt;br /&gt;
 while (graph_size(max_graph) &amp;gt; n * percent) {&lt;br /&gt;
   Split_graph(max_graph); // Split the graph - a macro operation that represents the second phase.&lt;br /&gt;
 } &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
 // Third stage. &lt;br /&gt;
 Graph graphs[m] // That&#039;s how many graphs we got. m &amp;lt;= n. &lt;br /&gt;
 bool pairs_exist // Check if the&#039;re pairs of clusters to unite.&lt;br /&gt;
 while (num_graphs &amp;gt; 1 &amp;amp;&amp;amp; pairs_exist){&lt;br /&gt;
  pairs_exist = false // So we don&#039;t repeat if it fails.&lt;br /&gt;
  for (int i = 0; i &amp;lt; m; ++i) {&lt;br /&gt;
   for (int l = i + 1; l &amp;lt; m; ++l) { // Also a &amp;quot;Smart&amp;quot; version.&lt;br /&gt;
     check_pair(pairs_exist, graphs[i], graphs[l]); // Check whether graphs are similar enough by some metrics.&lt;br /&gt;
     if (pairs_exist) { Unite_graphs(graphs[i], graphs[l]) }; // Pairs_exist is set to true if something&#039;s found.&lt;br /&gt;
   }&lt;br /&gt;
  }&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Последовательная сложность алгоритма===&lt;br /&gt;
&lt;br /&gt;
Общая временная сложность последовательного варианта алгоритма CHAMELEON определяется как &amp;lt;math&amp;gt;O(nm + nlog{n} + mlog{m})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число исходных объектов, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - число малых кластеров, полученных после первого этапа работы. В случае &amp;quot;предельного&amp;quot; разбиения &amp;lt;math&amp;gt;m = n&amp;lt;/math&amp;gt; эта оценка превращается в &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;. В любом случае эта оценка не учитывает необходимости построения матрицы смежности по исходному набору векторов (авторы оригинальной статьи в своих исследованиях подразумевают, что матрица смежности уже построена), что означает дополнительные &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций. Тогда оценка будет составлять &amp;lt;math&amp;gt;O(n^2 + nm + nlog{n} + mlog{m})&amp;lt;/math&amp;gt; операций или &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; в случае &amp;quot;предельного&amp;quot; разбиения.&lt;br /&gt;
Следует также обратить внимание, что это оценка по числу не сложений и умножений, а достаточно крупных операций. Например, вычисление метрики между двумя векторами рассматривается как одна операция, а она включает в себя &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений (для вычисления квадратичной нормы разности векторов).&lt;br /&gt;
&lt;br /&gt;
===Информационный граф===&lt;br /&gt;
&lt;br /&gt;
Информационный граф дан в соответствии с макроструктурой алгоритма. Следует отметить, что имеются успешные попытки распараллелить 2 и 3 этапы алгоритма CHAMELEON (см. раздел &amp;quot;Существующие реализации&amp;quot;). Однако они включают в себя модификацию исходного алгоритма. Также возможно распараллеливание выборки пар кластеров и подсчёта их метрик внутри каждой из вершин stage_3_iter. Структура информационного графа внутри этих итераций аналогична структуре информационного графа первого этапа алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[File:CHAMELEON ruslanlazovskiy.png]]&lt;br /&gt;
&lt;br /&gt;
===Ресурс параллелизма алгоритма===&lt;br /&gt;
&lt;br /&gt;
Параллельную сложность алгоритма CHAMELEON следует оценивать отдельно для каждого этапа.&lt;br /&gt;
На первом этапе алгоритм поиска &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших соседей может быть выполнен за &amp;lt;math&amp;gt;n - 1&amp;lt;/math&amp;gt; вычислений значения метрики между двумя векторами.&lt;br /&gt;
На втором этапе итерации алгоритма выполняются строго последовательно, а распараллеливание алгоритма внутри итерации не относится к теме статьи.&lt;br /&gt;
На третьем этапе итерации также выполняются последовательно, однако возможно распараллеливание обработки пар кластеров внутри итерации. Каждая итерация может быть выполнена за &amp;lt;math&amp;gt;q - 1&amp;lt;/math&amp;gt; вычислений значения метрики между двумя кластерами, где q - количество кластеров на этой итерации.&lt;br /&gt;
&lt;br /&gt;
===Входные и выходные данные алгоритма===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Входные данные:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;O&amp;lt;/math&amp;gt; - набор из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов длины &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;. &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - число, определяющиее количество ближайших соседей, по которым строится первоначальный граф. &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Выходные данные:&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; - вектор длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, значение &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го элемента указывает на принадлежность соответствующего вектора одному из кластеров.&lt;br /&gt;
&lt;br /&gt;
===Свойства алгоритма===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Соотношение последовательной и параллельной сложности:&amp;lt;/b&amp;gt; Различные этапы алгоритма строго последовательны относительно друг друга. На первом этапе отношение последовательной сложности алгоритма к параллельной есть &amp;lt;math&amp;gt;n/2&amp;lt;/math&amp;gt;. На втором и третьем этапах различные итерации последовательны относительно друг друга. Однако внутри итераций допускается некоторый параллелизм. Например, для итераций третьего этапа в наилучшем случае отношение сложности последовательной реализации к параллельной есть &amp;lt;math&amp;gt;q/2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - число кластеров на конкретной итерации.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Вычислительная мощность:&amp;lt;/b&amp;gt; графовые алгоритмы, вообще говоря, обладают низкой вычислительной мощностью. В случае CHAMELEON вычислительная мощность первого этапа равна &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;. Для второго и третьего этапов оценка вычислительной мощности по сложениям и умножениям затруднительна, однако в терминах макроопераций можно дать грубую оценку. Вычислительная мощность каждой итерации второго этапа - &amp;lt;math&amp;gt;1 / \sum C_n^k&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число вершин в выбранном подграфе, а &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; варьируется от &amp;lt;math&amp;gt;0.25 * n&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;0.5 * n&amp;lt;/math&amp;gt;. Вычислительная мощность каждой итерации третьего этапа в этих терминах - &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Детерминированность:&amp;lt;/b&amp;gt; Важной особенностью описываемого алгоритма является его недетерминированность. Условия завершения как 2-го, так и 3-го этапа позволяют обозначить CHAMELEON как итерационный алгоритм с выходом по точности. При этом детерминированность 2-го этапа алгоритма можно обеспечить указанием вырожденных условий кластеризации (такая кластеризация, очевидно, не будет иметь практического смысла), в то время как 2-ый этап является недетерминированным всегда.&lt;br /&gt;
&lt;br /&gt;
==Программная реализация алгоритма==&lt;br /&gt;
===Особенности реализации последовательного алгоритма===&lt;br /&gt;
===Локальность данных и вычислений===&lt;br /&gt;
===Возможные способы и особенности параллельной реализации алгоритма===&lt;br /&gt;
===Масштабируемость алгоритма и его реализации===&lt;br /&gt;
===Динамические характеристики и эффективность реализации алгоритма===&lt;br /&gt;
===Выводы для классов архитектур===&lt;br /&gt;
===Существующие реализации алгоритма===&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Краткий обзор алгоритма [http://studopedia.ru/7_41934_algoritm-dinamicheskoy-ierarhicheskoy-klasterizatsii-CHAMELEON.html|]&amp;lt;br/&amp;gt;&lt;br /&gt;
Первоначальная статья от авторов алгоритма [http://www-users.cs.umn.edu/~han/dmclass/chameleon.pdf|]&amp;lt;br/&amp;gt;&lt;br /&gt;
Исследования возможной параллелизации алгоритма[http://research.ijcaonline.org/volume79/number8/pxc3891600.pdf|]&amp;lt;br/&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21738</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21738"/>
		<updated>2017-01-25T09:37:05Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* Входные и выходные данные алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В инкубаторе}}&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В рамках первого этапа макрооперацияй считается построение графа k-ближайших соседей&lt;br /&gt;
&lt;br /&gt;
В рамках второго этапа макрооперациями считаются операции разбиения подграфа.&lt;br /&gt;
&lt;br /&gt;
В рамках третьего этапа макрооперациями считаются вычисления метрики, на основании которой делается вывод о том, какие подграфы нужно объединять.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:Инфограф.png]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
На первом этапе вычисление &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших вершин для &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й вершины можно распараллелить между &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; процессами (это вычисление независимо для каждой вершины).&lt;br /&gt;
На втором и третьем этапах процессы разбиения и объединения подграфов происходят последовательно.&lt;br /&gt;
Получаем оценку параллельной сложности алгоритма &amp;lt;math&amp;gt;O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
На вход алгоритму подается множество из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов длины &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt;, описывающих объекты для кластеризации.&lt;br /&gt;
Также передаются параметры &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (для построения графа k ближайших соседей на первом этапе) и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; (используется на втором этапе для определения критерия прекращения итерационного процесса).&lt;br /&gt;
На выходе алгоритм выдает массив длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, заполненный числами от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, показывающими, в какой кластер попал соответствующий объект.&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21737</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21737"/>
		<updated>2017-01-25T09:36:32Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* Свойства и структура алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В инкубаторе}}&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В рамках первого этапа макрооперацияй считается построение графа k-ближайших соседей&lt;br /&gt;
&lt;br /&gt;
В рамках второго этапа макрооперациями считаются операции разбиения подграфа.&lt;br /&gt;
&lt;br /&gt;
В рамках третьего этапа макрооперациями считаются вычисления метрики, на основании которой делается вывод о том, какие подграфы нужно объединять.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:Инфограф.png]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
На первом этапе вычисление &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших вершин для &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й вершины можно распараллелить между &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; процессами (это вычисление независимо для каждой вершины).&lt;br /&gt;
На втором и третьем этапах процессы разбиения и объединения подграфов происходят последовательно.&lt;br /&gt;
Получаем оценку параллельной сложности алгоритма &amp;lt;math&amp;gt;O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
На вход алгоритму подается множество из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; векторов длины &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt;, описывающих объекты для кластеризации.&lt;br /&gt;
Также передаются параметры &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (для построения графа k ближайших соседей на первом этапе) и &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; (используется на втором этапе для определения критерия прекращения итерационного процесса).&lt;br /&gt;
На выходе алгоритм выдает массив длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, заполненный числами от &amp;lt;math&amp;gt;1&amp;lt;math/&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, показывающими, в какой кластер попал соответствующий объект.&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21736</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21736"/>
		<updated>2017-01-25T09:30:10Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* Свойства и структура алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В инкубаторе}}&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В рамках первого этапа макрооперацияй считается построение графа k-ближайших соседей&lt;br /&gt;
&lt;br /&gt;
В рамках второго этапа макрооперациями считаются операции разбиения подграфа.&lt;br /&gt;
&lt;br /&gt;
В рамках третьего этапа макрооперациями считаются вычисления метрики, на основании которой делается вывод о том, какие подграфы нужно объединять.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:Инфограф.png]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
На первом этапе вычисление &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ближайших вершин для &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й вершины можно распараллелить между &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; процессами (это вычисление независимо для каждой вершины).&lt;br /&gt;
На втором и третьем этапах процессы разбиения и объединения подграфов происходят последовательно.&lt;br /&gt;
Получаем оценку параллельной сложности алгоритма &amp;lt;math&amp;gt;O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21715</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21715"/>
		<updated>2017-01-24T15:20:35Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В инкубаторе}}&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В рамках первого этапа макрооперацияй считается построение графа k-ближайших соседей&lt;br /&gt;
&lt;br /&gt;
В рамках второго этапа макрооперациями считаются операции разбиения подграфа.&lt;br /&gt;
&lt;br /&gt;
В рамках третьего этапа макрооперациями считаются вычисления метрики, на основании которой делается вывод о том, какие подграфы нужно объединять.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:Инфограф.png]]&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21714</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21714"/>
		<updated>2017-01-24T15:18:19Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* Свойства и структура алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В инкубаторе}}&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В рамках первого этапа макрооперацияй считается построение графа k-ближайших соседей&lt;br /&gt;
&lt;br /&gt;
В рамках второго этапа макрооперациями считаются операции разбиения подграфа.&lt;br /&gt;
&lt;br /&gt;
В рамках третьего этапа макрооперациями считаются вычисления метрики, на основании которой делается вывод о том, какие подграфы нужно объединять.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:Инфограф.jpg]]&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21713</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21713"/>
		<updated>2017-01-24T15:18:11Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В инкубаторе}}&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В рамках первого этапа макрооперацияй считается построение графа k-ближайших соседей&lt;br /&gt;
&lt;br /&gt;
В рамках второго этапа макрооперациями считаются операции разбиения подграфа.&lt;br /&gt;
&lt;br /&gt;
В рамках третьего этапа макрооперациями считаются вычисления метрики, на основании которой делается вывод о том, какие подграфы нужно объединять.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:инфограф.jpg]]&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21712</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21712"/>
		<updated>2017-01-24T15:15:35Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* Свойства и структура алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В инкубаторе}}&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В рамках первого этапа макрооперацияй считается построение графа k-ближайших соседей&lt;br /&gt;
&lt;br /&gt;
В рамках второго этапа макрооперациями считаются операции разбиения подграфа.&lt;br /&gt;
&lt;br /&gt;
В рамках третьего этапа макрооперациями считаются вычисления метрики, на основании которой делается вывод о том, какие подграфы нужно объединять.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
[[Файл:infograph.jpg]]&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21711</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21711"/>
		<updated>2017-01-24T14:19:00Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* Свойства и структура алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В инкубаторе}}&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В рамках первого этапа макрооперацияй считается построение графа k-ближайших соседей&lt;br /&gt;
&lt;br /&gt;
В рамках второго этапа макрооперациями считаются операции разбиения подграфа.&lt;br /&gt;
&lt;br /&gt;
В рамках третьего этапа макрооперациями считаются вычисления метрики, на основании которой делается вывод о том, какие подграфы нужно объединять.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Схема представлена в виде C++-подобного псевдокода, макрооперации в алгоритме выделены в соответствии с предыдущим разделом описания.&lt;br /&gt;
  int n; // Количество точек.&lt;br /&gt;
 int k; // Параметр k&lt;br /&gt;
 int Dist[n][n]; // Матрица расстояний между точками.&lt;br /&gt;
  &lt;br /&gt;
 integer E[n][n]; // Матрица рёбер графа&lt;br /&gt;
 &lt;br /&gt;
 foreach (int i=0; i&amp;lt;n; i++) ) {&lt;br /&gt;
    integer KNeighbours[k]; // список, используемый для хранения ближайших соседей&lt;br /&gt;
    integer countN = 0;&lt;br /&gt;
    &lt;br /&gt;
    foreach (int j=i+1; j&amp;lt;n; j++ ) {&lt;br /&gt;
      //Заполняем список k ближайших соседей по матрице Dist&lt;br /&gt;
    }&lt;br /&gt;
  &lt;br /&gt;
    foreach (int j=0; j&amp;lt;k; j++) {&lt;br /&gt;
      E[i][KNeighbours[j]] = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return E;&lt;br /&gt;
&lt;br /&gt;
 double q; //Параметр, описание находится в соответствующем разделе. &lt;br /&gt;
 Graph g = getBiggestGraph(); //Находим граф максимального размера&lt;br /&gt;
 int maxSize = getSize(g); //Находим размер данного графа&lt;br /&gt;
 while (maxSize &amp;gt; n * q) { &lt;br /&gt;
    breakGraph(g); // Разбиваем граф&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 Graph graphs[m]; //Разбиение по кластерам&lt;br /&gt;
 while (count(graphs)&amp;gt;1){&lt;br /&gt;
    pairs_exist = false //Значение будет обновлено позже, если найдется подходящая пара для объединения&lt;br /&gt;
    for (int i = 0; i &amp;lt; m; i++) {&lt;br /&gt;
       for (int j = i + 1; j &amp;lt; m; j++) { &lt;br /&gt;
          if (checkSimilarity(graphs[i],graphs[j])) { //Проверяем, достаточно ли схожи графы для объединения&lt;br /&gt;
 			unite(graphs[i], graphs[l]) &lt;br /&gt;
 		 } else {&lt;br /&gt;
 			break;&lt;br /&gt;
 		 }&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
На первом этапе построение графа k-ближайших соседей требует &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
На втором этапе для итеративного разбиения требуется &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;операций, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин графа, а &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; - количество подграфов в итоговом разбиении.&lt;br /&gt;
&lt;br /&gt;
На третьем этапе требуется &amp;lt;math&amp;gt;O(m^2logm)&amp;lt;/math&amp;gt; операций, причем вычисление метрики считается за одну операцию.&lt;br /&gt;
&lt;br /&gt;
Итоговая оценка последовательной сложности &amp;lt;math&amp;gt;O(n^2)+O(nm)+O(m^2logm)&amp;lt;/math&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21710</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21710"/>
		<updated>2017-01-24T14:18:23Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* 1 Свойства и структура алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В инкубаторе}}&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В рамках первого этапа макрооперацияй считается построение графа k-ближайших соседей&lt;br /&gt;
&lt;br /&gt;
В рамках второго этапа макрооперациями считаются операции разбиения подграфа.&lt;br /&gt;
&lt;br /&gt;
В рамках третьего этапа макрооперациями считаются вычисления метрики, на основании которой делается вывод о том, какие подграфы нужно объединять.&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21709</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21709"/>
		<updated>2017-01-24T14:17:20Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* 1.3 Вычислительное ядро алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В инкубаторе}}&lt;br /&gt;
== 1 Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21708</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21708"/>
		<updated>2017-01-24T14:17:12Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* 1.2 Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В инкубаторе}}&lt;br /&gt;
== 1 Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
=== 1.3 Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21707</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21707"/>
		<updated>2017-01-24T14:16:49Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* 1.1 Общее описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В инкубаторе}}&lt;br /&gt;
== 1 Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== 1.2 Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
=== 1.3 Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21683</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21683"/>
		<updated>2017-01-23T12:22:09Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* 1.2 Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В инкубаторе}}&lt;br /&gt;
== 1 Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== 1.1 Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== 1.2 Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На третьем этапе происходит агломеративная иерархическая кластеризация.&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RI(Ci,Cj)\geq{T_{RI}} &amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;RC_{(C_{i},C_{j})}\geq{T_{RC}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; существует несколько кластеров &amp;lt;math&amp;gt;C_j&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;EC_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что &amp;lt;math&amp;gt;RI_{(C_i,C_j)}*RC^\alpha_{(C_i,C_j)}&amp;lt;/math&amp;gt; максимально, где &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
=== 1.3 Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;/div&gt;</summary>
		<author><name>Hromovalexander</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21682</id>
		<title>Участник:Hromovalexander/Алгоритм динамической иерархической кластеризации CHAMELEON</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:Hromovalexander/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%B8%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_CHAMELEON&amp;diff=21682"/>
		<updated>2017-01-23T12:05:09Z</updated>

		<summary type="html">&lt;p&gt;Hromovalexander: /* 1.2 Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В инкубаторе}}&lt;br /&gt;
== 1 Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== 1.1 Общее описание алгоритма ===&lt;br /&gt;
Алгоритм CHAMELEON - алгоритм динамической иерархической кластеризации графа.&lt;br /&gt;
&lt;br /&gt;
Кластеризация - разбиение графа на несколько подграфов таким образом, чтобы объекты внутри одного кластера были максимально близки (схожи), а данные двух различных кластеров максимально различались. Различие и схожесть объектов определяются некоей метрикой, известной заранее. Количество кластеров, на которые будет разбит граф, заранее неизвестно, и зависит от свойств объекта и выбранной метрики. Простейшей возможной метриков является расстояние между точками (если предполагать, что у каждой вершины графа есть координаты).&lt;br /&gt;
&lt;br /&gt;
Алгоритм состоит из 3-х основных этапов:&lt;br /&gt;
&lt;br /&gt;
1-й этап заключается в построении изначального графа по множеству объектов и метрике схожести по принципу k ближайших соседей (вершина графа, соответствующая некому объекту соединяется с k вершинами, расстояние до которых минимально)&lt;br /&gt;
&lt;br /&gt;
2-й этап заключается в разбиении построенного графа на небольшие кластеры (связные подграфы)&lt;br /&gt;
&lt;br /&gt;
3-й этап состоит в формировании итогового множества кластеров&lt;br /&gt;
&lt;br /&gt;
=== 1.2 Математическое описание алгоритма ===&lt;br /&gt;
&#039;&#039;&#039;Исходные данные&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Множество из n объектов и заданные расстояния между объектами. Эта информация позволяет построить матрицу смежности, в которой будут указаны расстояния между соответствующими объектами по некой метрике. Матрица смежности симметрична, на главной диагонали стоят 0, поэтому достаточно хранить &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; элементов. Кроме того задаются параметры, влияющие на работу алгоритма - число k, по которому на первом этапе строится граф по принципу k ближайших соседей, и два параметра &amp;lt;math&amp;gt;{T_{ri}}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;{T_{rc}}&amp;lt;/math&amp;gt;, используемые на третьем этапе для того, что определить, что не нужно далее продолжать кластеризацию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первый этап&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
На первом этапе строится граф &amp;lt;math&amp;gt;G(V,E)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; - множество вершин, &amp;lt;math&amp;gt;E&amp;lt;/math&amp;gt; - множество ребер, по принципу k ближайших соседей. Изначально граф состоит из множества вершин и пустого множества ребер. Для каждой вершины графа мы выбираем k других вершин, расстояния до которых минимальны (то есть k первых вершин в списке вершин графа, упорядоченных по увеличению расстояния до данной) и добавляем в множество ребер соответствующие ребра, соединяющие данную вершину с каждой из выбранных k вершин.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Второй этап&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Состоит в итеративном разбиении графа на множество подграфов. Изначально (на первой итерации) разбиение состоит из единственного подграфа. Пусть &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - множество подграфов на текущей итерации. Каждая итерация выполняется следующим образом - выбирается максимальный подграф из имеющихся в разбиении по числу вершин (то есть такой подграф &amp;lt;math&amp;gt;G_1(V_1,E_1)\in{T}: \forall {G_2(V_2,E_2)\in{T}: G_2\neq G_1} =&amp;gt; |(V_1)|&amp;gt;|(V_2)|&amp;lt;/math&amp;gt; ). Выбранный подграф разбивается на 2 подграфа следующим образом - сначала выбираются все разбиения &amp;lt;math&amp;gt;G_2(V_2,E_2)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;G_3(V_3,E_3)&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;\min(|V_2|,|V_3|)\geq\frac{|V_1|}{4}&amp;lt;/math&amp;gt;. Далее среди всех таких разбиений выбирается такое, для которого величина &amp;lt;math&amp;gt;\sum{|E_1^*|},E_1^* &amp;lt;/math&amp;gt;- некое ребро, ведущее из вершины, попавшей в &amp;lt;math&amp;gt;G_2&amp;lt;/math&amp;gt; в вершину, попавшую в &amp;lt;math&amp;gt;G_3&amp;lt;/math&amp;gt;. В определенный момент, когда размер наибольшего кластера &amp;lt;math&amp;gt;|V_b|\leq{q*|V|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - количество вершин в изначальном графе, а &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; - предварительно заданный параметр, процесс дальнейшего разибения прекращается и алгоритм переходи на 3-й этап&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третий этап алгоритма:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Введем несколько определений:&lt;br /&gt;
&lt;br /&gt;
Абсолютной взаимной связностью пары кластеров называется величина &amp;lt;math&amp;gt;EC_{({C_i},{C_j})}&amp;lt;/math&amp;gt;, вычисляется как сумма весов ребер, соединяющих вершина 1-го кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; с вершинами второго кластера &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt;. Внутренняя связность кластера &amp;lt;math&amp;gt;E_{C_i}&amp;lt;/math&amp;gt;вычисляется как сумма весов ребер, входящих в разделитель, разбивающих &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt; на 2 равных подграфа. &lt;br /&gt;
&lt;br /&gt;
Относительная взаимная связность пары кластеров &amp;lt;math&amp;gt;RI_{(C_i,C_j)}&amp;lt;/math&amp;gt; вычисляется по формуле &amp;lt;math&amp;gt;RI_{(C_i,C_j)}=\frac{2*|EC_{(C_i,C_j)}|}{|EC_{C_i}|+|EC_{C_j}|}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Абсолютное взаимное сходство пары кластеров &amp;lt;math&amp;gt;S_{E_{(C_i,C_j)}}&amp;lt;/math&amp;gt;вычисляется как среднее сходство между связанными вершинами &amp;lt;math&amp;gt;C_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;C_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_j&amp;lt;/math&amp;gt; обозначается &amp;lt;math&amp;gt;RC_{(C_i,C_j)}&amp;lt;/math&amp;gt;и рассчитывается по формуле&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;RC_{(C_i,C_j)}=\frac{S_{EC_{(C_i,C_j)}}}{\frac{|C_i|}{|C_i|+|C_j|}*S_{EC_{(C_i)}}+{\frac{|C_j|}{|C_i|+|C_j|}*S_{EC_{(C_j)}}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Есть два различных подхода анализа сходства.&lt;br /&gt;
&lt;br /&gt;
Первый - для каждой пары кластеров проверяется истинность следующих высказываний&lt;br /&gt;
&lt;br /&gt;
{\displaystyle RI(Ci,Cj)\geq {T_{RI}}}  и {\displaystyle RC_{(C_{i},C_{j})}\geq {T_{RC}}} &lt;br /&gt;
&lt;br /&gt;
В случае, если для некоторого {\displaystyle C_{i}}  существует несколько кластеров {\displaystyle C_{j}} , удовлетворяющих этим условиям, выбирается такой {\displaystyle C_{j}} , что&lt;br /&gt;
&lt;br /&gt;
значение {\displaystyle EC_{(C_{i},C_{j})}}  максимально.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
Второй подход - выбирается такая пара кластеров, что {\displaystyle RI_{(C_{i},C_{j})}*RC_{(C_{i},C_{j})}^{\alpha }}  максимально, где {\displaystyle \alpha }  - заданный заранее параметр.&lt;br /&gt;
&lt;br /&gt;
Процесс останавливается, когда нет кластеров, удовлетворяющих указанным условиям (либо когда остался только 1 кластер)&lt;br /&gt;
&lt;br /&gt;
=== 1.3 Вычислительное ядро алгоритма ===&lt;br /&gt;
На первом этапе вычислительное ядро состоит из построения графа k ближайших соседей по исходной матрице смежности (требуется для каждой вершины перебрать всех соседей и выделить k ближайших)&lt;br /&gt;
&lt;br /&gt;
На втором этапе вычислительное ядро состоит из повторяющегося нахождения разбиения графа на два подграфа, удовлетворяющего ранее описанным условиям&lt;br /&gt;
&lt;br /&gt;
На третьем этапе вычислительное ядро состоит из вычисления на очередном этапе метрики схожести для двух кластеров, и их последующего объединения&lt;/div&gt;</summary>
		<author><name>Hromovalexander</name></author>
	</entry>
</feed>