<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0</id>
	<title>Алговики - Вклад [ru]</title>
	<link rel="self" type="application/atom+xml" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0"/>
	<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/ru/%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0"/>
	<updated>2026-10-22T20:02:57Z</updated>
	<subtitle>Вклад</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Bormas&amp;diff=23735</id>
		<title>Обсуждение участника:Bormas</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Bormas&amp;diff=23735"/>
		<updated>2017-11-03T18:30:25Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: Новая страница: «В самом начале добавьте название алгоритма и фамилию автора статьи.»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В самом начале добавьте название алгоритма и фамилию автора статьи.&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Sveta&amp;diff=23734</id>
		<title>Обсуждение участника:Sveta</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Sveta&amp;diff=23734"/>
		<updated>2017-11-03T18:27:59Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В начале перед содержанием добавьте название алгоритма и фамилию автора статьи.&lt;br /&gt;
&lt;br /&gt;
В разделе 1.2 там где вы пишите max (от функции)- максимум берется по всем стратегиям x из X и т.п.  Добавьте.&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Sveta&amp;diff=23733</id>
		<title>Обсуждение участника:Sveta</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Sveta&amp;diff=23733"/>
		<updated>2017-11-03T18:27:11Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В начале перед содержанием добавьте название алгоритма и фамилию автора статьи.&lt;br /&gt;
&lt;br /&gt;
В разделе 1.2 там где вы пишите max (от функции)- максимум берется по чему?&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Sveta&amp;diff=23732</id>
		<title>Обсуждение участника:Sveta</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Sveta&amp;diff=23732"/>
		<updated>2017-11-03T18:25:26Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: Новая страница: «В начале перед содержанием добавьте название алгоритма и фамилию автора статьи.»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В начале перед содержанием добавьте название алгоритма и фамилию автора статьи.&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Chist/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%9D%D1%8C%D1%8E%D1%82%D0%BE%D0%BD%D0%B0&amp;diff=23731</id>
		<title>Обсуждение участника:Chist/Метод Ньютона</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Chist/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%9D%D1%8C%D1%8E%D1%82%D0%BE%D0%BD%D0%B0&amp;diff=23731"/>
		<updated>2017-11-03T17:51:35Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: Новая страница: «Поправить предложение:  &amp;quot;При нас интересуют не только действительные корни, но и комплек…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Поправить предложение:  &amp;quot;При нас интересуют не только действительные корни, но и комплексные, будет производить перебор по некоторой сетке на комплексной плоскости.&amp;quot; &lt;br /&gt;
&lt;br /&gt;
В самом начале перед содержанием добавить название алгоритма и фамилию автора статьи.&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Valkyrie/%D0%90%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE%D0%B5_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5&amp;diff=23730</id>
		<title>Обсуждение участника:Valkyrie/Адаптивное интегрирование</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Valkyrie/%D0%90%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE%D0%B5_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5&amp;diff=23730"/>
		<updated>2017-11-03T17:34:52Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; &amp;quot;к характеру изменения функции -вводил разные значения шага &amp;quot; - поправьте тире.&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Valkyrie/%D0%90%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE%D0%B5_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5&amp;diff=23729</id>
		<title>Обсуждение участника:Valkyrie/Адаптивное интегрирование</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Valkyrie/%D0%90%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE%D0%B5_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5&amp;diff=23729"/>
		<updated>2017-11-03T17:34:36Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: Новая страница: « &amp;quot;к характеру изменения функции -вводил разные значения шага &amp;quot; -- поправьте тире.»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; &amp;quot;к характеру изменения функции -вводил разные значения шага &amp;quot; -- поправьте тире.&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Jhuighuy/%D0%AF%D0%B2%D0%BD%D0%B0%D1%8F_%D1%82%D0%B5%D1%85%D0%BD%D0%B8%D0%BA%D0%B0_%D1%80%D0%B0%D1%81%D1%89%D0%B5%D0%BF%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%82%D0%BE%D1%80%D0%BE%D0%B2_%D0%B4%D0%BB%D1%8F_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B_%D1%83%D1%80%D0%B0%D0%B2%D0%BD%D0%B5%D0%BD%D0%B8%D0%B9_%D0%9D%D0%B0%D0%B2%D1%8C%D0%B5-%D0%A1%D1%82%D0%BE%D0%BA%D1%81%D0%B0&amp;diff=23727</id>
		<title>Обсуждение участника:Jhuighuy/Явная техника расщепления операторов для системы уравнений Навье-Стокса</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Jhuighuy/%D0%AF%D0%B2%D0%BD%D0%B0%D1%8F_%D1%82%D0%B5%D1%85%D0%BD%D0%B8%D0%BA%D0%B0_%D1%80%D0%B0%D1%81%D1%89%D0%B5%D0%BF%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%82%D0%BE%D1%80%D0%BE%D0%B2_%D0%B4%D0%BB%D1%8F_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B_%D1%83%D1%80%D0%B0%D0%B2%D0%BD%D0%B5%D0%BD%D0%B8%D0%B9_%D0%9D%D0%B0%D0%B2%D1%8C%D0%B5-%D0%A1%D1%82%D0%BE%D0%BA%D1%81%D0%B0&amp;diff=23727"/>
		<updated>2017-11-03T14:08:55Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: Новая страница: «В начале перед содержанием добавьте название алгоритма и  фамилию автора статьи»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В начале перед содержанием добавьте название алгоритма и  фамилию автора статьи&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=18561</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=18561"/>
		<updated>2016-11-20T08:09:49Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&lt;br /&gt;
Авторы: Таратута Екатерина (1.1, 1.3, 1.4, 1.5, 1.6, 1.8, 2.7), Жайлауова Шынар (1.2, 1.7, 1.9, 1.10)&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Вычислительное ядро алгоритма==&lt;br /&gt;
:Основная вычислительная нагрузка в алгоритме приходится на умножение матриц при вычислении числа связей. Оно имеет квадратичную сложность. &lt;br /&gt;
:Также большую вычислительную нагрузку дает цикл, в котором обновляются локальная и глобальная кучи после объединения двух кластеров в один.&lt;br /&gt;
&lt;br /&gt;
==Макроструктура алгоритма==&lt;br /&gt;
Как написано и в описании ядра алгоритма, основную часть метода составляют вычисление связей между объектами и объединение кластеров.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:4.jpg]]&lt;br /&gt;
[[File:5.jpg]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Процедура &amp;lt;math&amp;gt;compute\_links()&amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе  &amp;lt;math&amp;gt;a[i,j] = 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В общем случае не у каждой пары точек будут связи. Поэтому ожидаемый объем данных может быть намного меньше, а именно &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимальное число соседей произвольного объекта, &amp;lt;math&amp;gt;m_a&amp;lt;/math&amp;gt; - среднее значение числа соседей произвольного объекта.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура кластеризации:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039;  &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. Ожидаемый объем: &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; массив объектов, в котором значением i-го объекта является номер кластера, к которому он был приписан. &lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
В алгоритме есть три параллельные области: &lt;br /&gt;
*построение матрицы связей;&lt;br /&gt;
*построение локальных куч;&lt;br /&gt;
*for-цикл, реализующий обновление всех куч при слиянии двух кластеров.&lt;br /&gt;
С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Программа тестировалась на IBM pSeries 690 HPC Regatta. Ниже в таблице представлены результаты работы программы на 1, 2, 4, 8, 16 потоках:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!данные/потоки||1||2||4||8||16 &lt;br /&gt;
|-&lt;br /&gt;
|128||0.84||0.54||0.46||0.38||0.30&lt;br /&gt;
|-&lt;br /&gt;
|256||7.10||3.77||2.07||1.87||0.95&lt;br /&gt;
|-&lt;br /&gt;
|512||67.09||34.66||17.35||10.50||5.54&lt;br /&gt;
|-&lt;br /&gt;
|1024||610.29||310.55||157.86||83.59||45.18&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File:graphi.jpg]]&lt;br /&gt;
&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA&amp;lt;ref&amp;gt;https://github.com/cran/cba/blob/master/R/rock.r&amp;lt;/ref&amp;gt; в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka&amp;lt;ref&amp;gt;https://sourceforge.net/projects/feed4weka/files/&amp;lt;/ref&amp;gt; - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=18560</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=18560"/>
		<updated>2016-11-20T08:07:57Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Авторы: Таратута Екатерина (1.1, 1.3, 1.4, 1.5, 1.6, 1.8, 2.7), Жайлауова Шынар (1.2, 1.7, 1.9, 1.10)&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Вычислительное ядро алгоритма==&lt;br /&gt;
:Основная вычислительная нагрузка в алгоритме приходится на умножение матриц при вычислении числа связей. Оно имеет квадратичную сложность. &lt;br /&gt;
:Также большую вычислительную нагрузку дает цикл, в котором обновляются локальная и глобальная кучи после объединения двух кластеров в один.&lt;br /&gt;
&lt;br /&gt;
==Макроструктура алгоритма==&lt;br /&gt;
Как написано и в описании ядра алгоритма, основную часть метода составляют вычисление связей между объектами и объединение кластеров.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:4.jpg]]&lt;br /&gt;
[[File:5.jpg]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Процедура &amp;lt;math&amp;gt;compute\_links()&amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе  &amp;lt;math&amp;gt;a[i,j] = 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В общем случае не у каждой пары точек будут связи. Поэтому ожидаемый объем данных может быть намного меньше, а именно &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимальное число соседей произвольного объекта, &amp;lt;math&amp;gt;m_a&amp;lt;/math&amp;gt; - среднее значение числа соседей произвольного объекта.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура кластеризации:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039;  &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. Ожидаемый объем: &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; массив объектов, в котором значением i-го объекта является номер кластера, к которому он был приписан. &lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
В алгоритме есть три параллельные области: &lt;br /&gt;
*построение матрицы связей;&lt;br /&gt;
*построение локальных куч;&lt;br /&gt;
*for-цикл, реализующий обновление всех куч при слиянии двух кластеров.&lt;br /&gt;
С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Программа тестировалась на IBM pSeries 690 HPC Regatta. Ниже в таблице представлены результаты работы программы на 1, 2, 4, 8, 16 потоках:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!данные/потоки||1||2||4||8||16 &lt;br /&gt;
|-&lt;br /&gt;
|128||0.84||0.54||0.46||0.38||0.30&lt;br /&gt;
|-&lt;br /&gt;
|256||7.10||3.77||2.07||1.87||0.95&lt;br /&gt;
|-&lt;br /&gt;
|512||67.09||34.66||17.35||10.50||5.54&lt;br /&gt;
|-&lt;br /&gt;
|1024||610.29||310.55||157.86||83.59||45.18&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File:graphi.jpg]]&lt;br /&gt;
&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA&amp;lt;ref&amp;gt;https://github.com/cran/cba/blob/master/R/rock.r&amp;lt;/ref&amp;gt; в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka&amp;lt;ref&amp;gt;https://sourceforge.net/projects/feed4weka/files/&amp;lt;/ref&amp;gt; - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=18559</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=18559"/>
		<updated>2016-11-20T08:05:33Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Авторы: Таратута Екатерина (1.1, 1.3, 1.4, 1.5, 1.6, 1.8, 2.7), Жайлауова Шынар (1.2, 1.7, 1.9, 1.10)&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Вычислительное ядро алгоритма==&lt;br /&gt;
:Основная вычислительная нагрузка в алгоритме приходится на умножение матриц при вычислении числа связей. Оно имеет квадратичную сложность. &lt;br /&gt;
:Также большую вычислительную нагрузку дает цикл, в котором обновляются локальная и глобальная кучи после объединения двух кластеров в один.&lt;br /&gt;
&lt;br /&gt;
==Макроструктура алгоритма==&lt;br /&gt;
Как написано и в описании ядра алгоритма, основную часть метода составляют вычисление связей между объектами и объединение кластеров.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:4.jpg]]&lt;br /&gt;
[[File:5.jpg]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Процедура &amp;lt;math&amp;gt;compute\_links()&amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе  &amp;lt;math&amp;gt;a[i,j] = 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В общем случае не у каждой пары точек будут связи. Поэтому ожидаемый объем данных может быть намного меньше, а именно &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимальное число соседей произвольного объекта, &amp;lt;math&amp;gt;m_a&amp;lt;/math&amp;gt; - среднее значение числа соседей произвольного объекта.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура кластеризации:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039;  &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. Ожидаемый объем: &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; массив объектов, в котором значением i-го объекта является номер кластера, к которому он был приписан. &lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
В алгоритме есть три параллельные области: &lt;br /&gt;
*построение матрицы связей;&lt;br /&gt;
*построение локальных куч;&lt;br /&gt;
*for-цикл, реализующий обновление всех куч при слиянии двух кластеров.&lt;br /&gt;
С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Программа тестировалась на IBM pSeries 690 HPC Regatta. Ниже в таблице представлены результаты работы программы на 1, 2, 4, 8, 16 потоках:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!данные/потоки||1||2||4||8||16 &lt;br /&gt;
|-&lt;br /&gt;
|128||0.84||0.54||0.46||0.38||0.30&lt;br /&gt;
|-&lt;br /&gt;
|256||7.10||3.77||2.07||1.87||0.95&lt;br /&gt;
|-&lt;br /&gt;
|512||67.09||34.66||17.35||10.50||5.54&lt;br /&gt;
|-&lt;br /&gt;
|1024||610.29||310.55||157.86||83.59||45.18&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA&amp;lt;ref&amp;gt;https://github.com/cran/cba/blob/master/R/rock.r&amp;lt;/ref&amp;gt; в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka&amp;lt;ref&amp;gt;https://sourceforge.net/projects/feed4weka/files/&amp;lt;/ref&amp;gt; - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=18558</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=18558"/>
		<updated>2016-11-20T08:01:29Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Авторы: Таратута Екатерина (1.1, 1.3, 1.4, 1.5, 1.6, 1.8, 2.7), Жайлауова Шынар (1.2, 1.7, 1.9, 1.10)&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Вычислительное ядро алгоритма==&lt;br /&gt;
:Основная вычислительная нагрузка в алгоритме приходится на умножение матриц при вычислении числа связей. Оно имеет квадратичную сложность. &lt;br /&gt;
:Также большую вычислительную нагрузку дает цикл, в котором обновляются локальная и глобальная кучи после объединения двух кластеров в один.&lt;br /&gt;
&lt;br /&gt;
==Макроструктура алгоритма==&lt;br /&gt;
Как написано и в описании ядра алгоритма, основную часть метода составляют вычисление связей между объектами и объединение кластеров.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:4.jpg]]&lt;br /&gt;
[[File:5.jpg]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Процедура &amp;lt;math&amp;gt;compute\_links()&amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе  &amp;lt;math&amp;gt;a[i,j] = 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В общем случае не у каждой пары точек будут связи. Поэтому ожидаемый объем данных может быть намного меньше, а именно &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимальное число соседей произвольного объекта, &amp;lt;math&amp;gt;m_a&amp;lt;/math&amp;gt; - среднее значение числа соседей произвольного объекта.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура кластеризации:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039;  &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. Ожидаемый объем: &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; массив объектов, в котором значением i-го объекта является номер кластера, к которому он был приписан. &lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
В алгоритме есть три параллельные области: &lt;br /&gt;
*построение матрицы связей;&lt;br /&gt;
*построение локальных куч;&lt;br /&gt;
*for-цикл, реализующий обновление всех куч при слиянии двух кластеров.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!данные/потоки||1||2||4||8||16 &lt;br /&gt;
|-&lt;br /&gt;
|128||0.84||0.54||0.46||0.38||0.30&lt;br /&gt;
|-&lt;br /&gt;
|256||7.10||3.77||2.07||1.87||0.95&lt;br /&gt;
|-&lt;br /&gt;
|512||67.09||34.66||17.35||10.50||5.54&lt;br /&gt;
|-&lt;br /&gt;
|1024||610.29||310.55||157.86||83.59||45.18&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA&amp;lt;ref&amp;gt;https://github.com/cran/cba/blob/master/R/rock.r&amp;lt;/ref&amp;gt; в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka&amp;lt;ref&amp;gt;https://sourceforge.net/projects/feed4weka/files/&amp;lt;/ref&amp;gt; - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=18557</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=18557"/>
		<updated>2016-11-20T08:00:52Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Авторы: Таратута Екатерина (1.1, 1.3, 1.4, 1.5, 1.6, 1.8, 2.7), Жайлауова Шынар (1.2, 1.7, 1.9, 1.10)&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Вычислительное ядро алгоритма==&lt;br /&gt;
:Основная вычислительная нагрузка в алгоритме приходится на умножение матриц при вычислении числа связей. Оно имеет квадратичную сложность. &lt;br /&gt;
:Также большую вычислительную нагрузку дает цикл, в котором обновляются локальная и глобальная кучи после объединения двух кластеров в один.&lt;br /&gt;
&lt;br /&gt;
==Макроструктура алгоритма==&lt;br /&gt;
Как написано и в описании ядра алгоритма, основную часть метода составляют вычисление связей между объектами и объединение кластеров.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:4.jpg]]&lt;br /&gt;
[[File:5.jpg]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Процедура &amp;lt;math&amp;gt;compute\_links()&amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе  &amp;lt;math&amp;gt;a[i,j] = 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В общем случае не у каждой пары точек будут связи. Поэтому ожидаемый объем данных может быть намного меньше, а именно &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимальное число соседей произвольного объекта, &amp;lt;math&amp;gt;m_a&amp;lt;/math&amp;gt; - среднее значение числа соседей произвольного объекта.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура кластеризации:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039;  &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. Ожидаемый объем: &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; массив объектов, в котором значением i-го объекта является номер кластера, к которому он был приписан. &lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
В алгоритме есть три параллельные области: &lt;br /&gt;
*построение матрицы связей,&lt;br /&gt;
*построение локальных куч и &lt;br /&gt;
*for-цикл, реализующий обновление всех куч при слиянии двух кластеров.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!данные/потоки||1||2||4||8||16 &lt;br /&gt;
|-&lt;br /&gt;
|128||0.84||0.54||0.46||0.38||0.30&lt;br /&gt;
|-&lt;br /&gt;
|256||7.10||3.77||2.07||1.87||0.95&lt;br /&gt;
|-&lt;br /&gt;
|512||67.09||34.66||17.35||10.50||5.54&lt;br /&gt;
|-&lt;br /&gt;
|1024||610.29||310.55||157.86||83.59||45.18&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA&amp;lt;ref&amp;gt;https://github.com/cran/cba/blob/master/R/rock.r&amp;lt;/ref&amp;gt; в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka&amp;lt;ref&amp;gt;https://sourceforge.net/projects/feed4weka/files/&amp;lt;/ref&amp;gt; - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=18556</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=18556"/>
		<updated>2016-11-20T07:52:06Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Авторы: Таратута Екатерина (1.1, 1.3, 1.4, 1.5, 1.6, 1.8, 2.7), Жайлауова Шынар (1.2, 1.7, 1.9, 1.10)&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Вычислительное ядро алгоритма==&lt;br /&gt;
:Основная вычислительная нагрузка в алгоритме приходится на умножение матриц при вычислении числа связей. Оно имеет квадратичную сложность. &lt;br /&gt;
:Также большую вычислительную нагрузку дает цикл, в котором обновляются локальная и глобальная кучи после объединения двух кластеров в один.&lt;br /&gt;
&lt;br /&gt;
==Макроструктура алгоритма==&lt;br /&gt;
Как написано и в описании ядра алгоритма, основную часть метода составляют вычисление связей между объектами и объединение кластеров.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:4.jpg]]&lt;br /&gt;
[[File:5.jpg]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Процедура &amp;lt;math&amp;gt;compute\_links()&amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе  &amp;lt;math&amp;gt;a[i,j] = 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В общем случае не у каждой пары точек будут связи. Поэтому ожидаемый объем данных может быть намного меньше, а именно &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимальное число соседей произвольного объекта, &amp;lt;math&amp;gt;m_a&amp;lt;/math&amp;gt; - среднее значение числа соседей произвольного объекта.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура кластеризации:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039;  &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. Ожидаемый объем: &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; массив объектов, в котором значением i-го объекта является номер кластера, к которому он был приписан. &lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!данные/потоки||1||2||4||8||16 &lt;br /&gt;
|-&lt;br /&gt;
|128||0.84||0.54||0.46||0.38||0.30&lt;br /&gt;
|-&lt;br /&gt;
|256||7.10||3.77||2.07||1.87||0.95&lt;br /&gt;
|-&lt;br /&gt;
|512||67.09||34.66||17.35||10.50||5.54&lt;br /&gt;
|-&lt;br /&gt;
|1024||610.29||310.55||157.86||83.59||45.18&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA&amp;lt;ref&amp;gt;https://github.com/cran/cba/blob/master/R/rock.r&amp;lt;/ref&amp;gt; в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka&amp;lt;ref&amp;gt;https://sourceforge.net/projects/feed4weka/files/&amp;lt;/ref&amp;gt; - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=18555</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=18555"/>
		<updated>2016-11-20T07:46:55Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Авторы: Таратута Екатерина (1.1, 1.3, 1.4, 1.5, 1.6, 1.8, 2.7), Жайлауова Шынар (1.2, 1.7, 1.9, 1.10)&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Вычислительное ядро алгоритма==&lt;br /&gt;
:Основная вычислительная нагрузка в алгоритме приходится на умножение матриц при вычислении числа связей. Оно имеет квадратичную сложность. &lt;br /&gt;
:Также большую вычислительную нагрузку дает цикл, в котором обновляются локальная и глобальная кучи после объединения двух кластеров в один.&lt;br /&gt;
&lt;br /&gt;
==Макроструктура алгоритма==&lt;br /&gt;
Как написано и в описании ядра алгоритма, основную часть метода составляют вычисление связей между объектами и объединение кластеров.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:4.jpg]]&lt;br /&gt;
[[File:5.jpg]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Процедура &amp;lt;math&amp;gt;compute\_links()&amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе  &amp;lt;math&amp;gt;a[i,j] = 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В общем случае не у каждой пары точек будут связи. Поэтому ожидаемый объем данных может быть намного меньше, а именно &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимальное число соседей произвольного объекта, &amp;lt;math&amp;gt;m_a&amp;lt;/math&amp;gt; - среднее значение числа соседей произвольного объекта.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура кластеризации:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039;  &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. Ожидаемый объем: &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; массив объектов, в котором значением i-го объекта является номер кластера, к которому он был приписан. &lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Заголовок 1||Заголовок 2 &lt;br /&gt;
|-&lt;br /&gt;
|Ячейка 1*1||Ячейка 2*1&lt;br /&gt;
|-&lt;br /&gt;
|Ячейка 1*2||Ячейка 2*2&lt;br /&gt;
|-&lt;br /&gt;
|Ячейка 1*3||Ячейка 2*3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA&amp;lt;ref&amp;gt;https://github.com/cran/cba/blob/master/R/rock.r&amp;lt;/ref&amp;gt; в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka&amp;lt;ref&amp;gt;https://sourceforge.net/projects/feed4weka/files/&amp;lt;/ref&amp;gt; - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=17506</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=17506"/>
		<updated>2016-11-15T22:48:02Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Авторы: Таратута Екатерина (1.1, 1.3, 1.4, 1.5, 1.6, 1.8, 2.7), Жайлауова Шынар (1.2, 1.7, 1.9, 1.10)&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Вычислительное ядро алгоритма==&lt;br /&gt;
:Основная вычислительная нагрузка в алгоритме приходится на умножение матриц при вычислении числа связей. Оно имеет квадратичную сложность. &lt;br /&gt;
:Также большую вычислительную нагрузку дает цикл, в котором обновляются локальная и глобальная кучи после объединения двух кластеров в один.&lt;br /&gt;
&lt;br /&gt;
==Макроструктура алгоритма==&lt;br /&gt;
Как написано и в описании ядра алгоритма, основную часть метода составляют вычисление связей между объектами и объединение кластеров.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:4.jpg]]&lt;br /&gt;
[[File:5.jpg]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Процедура &amp;lt;math&amp;gt;compute\_links()&amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе  &amp;lt;math&amp;gt;a[i,j] = 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В общем случае не у каждой пары точек будут связи. Поэтому ожидаемый объем данных может быть намного меньше, а именно &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимальное число соседей произвольного объекта, &amp;lt;math&amp;gt;m_a&amp;lt;/math&amp;gt; - среднее значение числа соседей произвольного объекта.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура кластеризации:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039;  &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. Ожидаемый объем: &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; массив объектов, в котором значением i-го объекта является номер кластера, к которому он был приписан. &lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA&amp;lt;ref&amp;gt;https://github.com/cran/cba/blob/master/R/rock.r&amp;lt;/ref&amp;gt; в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka&amp;lt;ref&amp;gt;https://sourceforge.net/projects/feed4weka/files/&amp;lt;/ref&amp;gt; - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=17502</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=17502"/>
		<updated>2016-11-15T22:09:56Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Авторы: Таратута Екатерина (1.1, 1.3, 1.4, 1.5, 1.6, 1.8, 2.7), Жайлауова Шынар (1.2, 1.7, 1.9, 1.10)&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Вычислительное ядро алгоритма==&lt;br /&gt;
:Основная вычислительная нагрузка в алгоритме приходится на умножение матриц при вычислении числа связей. Оно имеет квадратичную сложность. &lt;br /&gt;
:Также большую вычислительную нагрузку дает цикл, в котором обновляются локальная и глобальная кучи после объединения двух кластеров в один.&lt;br /&gt;
&lt;br /&gt;
==Макроструктура алгоритма==&lt;br /&gt;
Как написано и в описании ядра алгоритма, основную часть метода составляют вычисление связей между объектами и объединение кластеров.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:4.jpg]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Процедура &amp;lt;math&amp;gt;compute\_links()&amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе  &amp;lt;math&amp;gt;a[i,j] = 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В общем случае не у каждой пары точек будут связи. Поэтому ожидаемый объем данных может быть намного меньше, а именно &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимальное число соседей произвольного объекта, &amp;lt;math&amp;gt;m_a&amp;lt;/math&amp;gt; - среднее значение числа соседей произвольного объекта.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура кластеризации:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039;  &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. Ожидаемый объем: &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; массив объектов, в котором значением i-го объекта является номер кластера, к которому он был приписан. &lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA&amp;lt;ref&amp;gt;https://github.com/cran/cba/blob/master/R/rock.r&amp;lt;/ref&amp;gt; в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka&amp;lt;ref&amp;gt;https://sourceforge.net/projects/feed4weka/files/&amp;lt;/ref&amp;gt; - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=17499</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=17499"/>
		<updated>2016-11-15T22:05:54Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Авторы: Таратута Екатерина (1.1, 1.3, 1.4, 1.5, 1.6, 1.8, 2.7), Жайлауова Шынар (1.2, 1.7, 1.9, 1.10)&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Вычислительное ядро алгоритма==&lt;br /&gt;
:Основная вычислительная нагрузка в алгоритме приходится на умножение матриц при вычислении числа связей. Оно имеет квадратичную сложность. &lt;br /&gt;
:Также большую вычислительную нагрузку дает цикл, в котором обновляются локальная и глобальная кучи после объединения двух кластеров в один.&lt;br /&gt;
&lt;br /&gt;
==Макроструктура алгоритма==&lt;br /&gt;
Как написано и в описании ядра алгоритма, основную часть метода составляют вычисление связей между объектами и объединение кластеров.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:3.jpg]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Процедура &amp;lt;math&amp;gt;compute\_links()&amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе  &amp;lt;math&amp;gt;a[i,j] = 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В общем случае не у каждой пары точек будут связи. Поэтому ожидаемый объем данных может быть намного меньше, а именно &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимальное число соседей произвольного объекта, &amp;lt;math&amp;gt;m_a&amp;lt;/math&amp;gt; - среднее значение числа соседей произвольного объекта.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура кластеризации:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039;  &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. Ожидаемый объем: &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; массив объектов, в котором значением i-го объекта является номер кластера, к которому он был приписан. &lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA&amp;lt;ref&amp;gt;https://github.com/cran/cba/blob/master/R/rock.r&amp;lt;/ref&amp;gt; в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka&amp;lt;ref&amp;gt;https://sourceforge.net/projects/feed4weka/files/&amp;lt;/ref&amp;gt; - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=17498</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=17498"/>
		<updated>2016-11-15T22:01:31Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Авторы: Таратута Екатерина (1.1, 1.3, 1.4, 1.5, 1.6, 1.8, 2.7), Жайлауова Шынар (1.2, 1.7, 1.9, 1.10)&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Вычислительное ядро алгоритма==&lt;br /&gt;
:Основная вычислительная нагрузка в алгоритме приходится на умножение матриц при вычислении числа связей. Оно имеет квадратичную сложность. &lt;br /&gt;
:Также большую вычислительную нагрузку дает цикл, в котором обновляются локальная и глобальная кучи после объединения двух кластеров в один.&lt;br /&gt;
&lt;br /&gt;
==Макроструктура алгоритма==&lt;br /&gt;
Как написано и в описании ядра алгоритма, основную часть метода составляют вычисление связей между объектами и объединение кластеров.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:1.jpg]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Процедура &amp;lt;math&amp;gt;compute\_links()&amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе  &amp;lt;math&amp;gt;a[i,j] = 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В общем случае не у каждой пары точек будут связи. Поэтому ожидаемый объем данных может быть намного меньше, а именно &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимальное число соседей произвольного объекта, &amp;lt;math&amp;gt;m_a&amp;lt;/math&amp;gt; - среднее значение числа соседей произвольного объекта.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура кластеризации:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039;  &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. Ожидаемый объем: &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; массив объектов, в котором значением i-го объекта является номер кластера, к которому он был приписан. &lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA&amp;lt;ref&amp;gt;https://github.com/cran/cba/blob/master/R/rock.r&amp;lt;/ref&amp;gt; в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka&amp;lt;ref&amp;gt;https://sourceforge.net/projects/feed4weka/files/&amp;lt;/ref&amp;gt; - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15371</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15371"/>
		<updated>2016-10-31T20:54:32Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&lt;br /&gt;
Авторы: Таратута Екатерина (1.1, 1.3, 1.4, 1.5, 1.6, 1.8, 2.7), Жайлауова Шынар (1.2, 1.7, 1.9, 1.10)&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Вычислительное ядро алгоритма==&lt;br /&gt;
:Основная вычислительная нагрузка в алгоритме приходится на умножение матриц при вычислении числа связей. Оно имеет квадратичную сложность. &lt;br /&gt;
:Также большую вычислительную нагрузку дает цикл, в котором обновляются локальная и глобальная кучи после объединения двух кластеров в один.&lt;br /&gt;
&lt;br /&gt;
==Макроструктура алгоритма==&lt;br /&gt;
Как написано и в описании ядра алгоритма, основную часть метода составляют вычисление связей между объектами и объединение кластеров.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:2.png]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Процедура &amp;lt;math&amp;gt;compute\_links()&amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе  &amp;lt;math&amp;gt;a[i,j] = 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В общем случае не у каждой пары точек будут связи. Поэтому ожидаемый объем данных может быть намного меньше, а именно &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимальное число соседей произвольного объекта, &amp;lt;math&amp;gt;m_a&amp;lt;/math&amp;gt; - среднее значение числа соседей произвольного объекта.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура кластеризации:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039;  &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. Ожидаемый объем: &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; массив объектов, в котором значением i-го объекта является номер кластера, к которому он был приписан. &lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA&amp;lt;ref&amp;gt;https://github.com/cran/cba/blob/master/R/rock.r&amp;lt;/ref&amp;gt; в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka&amp;lt;ref&amp;gt;https://sourceforge.net/projects/feed4weka/files/&amp;lt;/ref&amp;gt; - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15218</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15218"/>
		<updated>2016-10-31T18:20:19Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Авторы: Таратута Екатерина (1.1, 1.3, 1.4, 1.5, 1.6, 1.8, 2.7), Жайлауова Шынар (1.2, 1.7, 1.9, 1.10)&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Вычислительное ядро алгоритма==&lt;br /&gt;
:Основная вычислительная нагрузка в алгоритме приходится на умножение матриц при вычислении числа связей. Оно имеет квадратичную сложность. &lt;br /&gt;
:Также большую вычислительную нагрузку дает цикл, в котором обновляются локальная и глобальная кучи после объединения двух кластеров в один.&lt;br /&gt;
&lt;br /&gt;
==Макроструктура алгоритма==&lt;br /&gt;
Как написано и в описании ядра алгоритма, основную часть метода составляют вычисление связей между объектами и объединение кластеров.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:2.png]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Процедура &amp;lt;math&amp;gt;compute\_links()&amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе  &amp;lt;math&amp;gt;a[i,j] = 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В общем случае не у каждой пары точек будут связи. Поэтому ожидаемый объем данных может быть намного меньше, а именно &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимальное число соседей произвольного объекта, &amp;lt;math&amp;gt;m_a&amp;lt;/math&amp;gt; - среднее значение числа соседей произвольного объекта.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура кластеризации:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039;  &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. Ожидаемый объем: &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; массив объектов, в котором значением i-го объекта является номер кластера, к которому он был приписан. &lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA&amp;lt;ref&amp;gt;https://github.com/cran/cba/blob/master/R/rock.r&amp;lt;/ref&amp;gt; в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka&amp;lt;ref&amp;gt;https://sourceforge.net/projects/feed4weka/files/&amp;lt;/ref&amp;gt; - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15217</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15217"/>
		<updated>2016-10-31T18:19:45Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Авторы: Таратута Екатерина (1.1, 1.3, 1.4, 1.5, 1.6, 1.8), Жайлауова Шынар (1.2, 1.7, 1.9, 1.10, 2.7)&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Вычислительное ядро алгоритма==&lt;br /&gt;
:Основная вычислительная нагрузка в алгоритме приходится на умножение матриц при вычислении числа связей. Оно имеет квадратичную сложность. &lt;br /&gt;
:Также большую вычислительную нагрузку дает цикл, в котором обновляются локальная и глобальная кучи после объединения двух кластеров в один.&lt;br /&gt;
&lt;br /&gt;
==Макроструктура алгоритма==&lt;br /&gt;
Как написано и в описании ядра алгоритма, основную часть метода составляют вычисление связей между объектами и объединение кластеров.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:2.png]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Процедура &amp;lt;math&amp;gt;compute\_links()&amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе  &amp;lt;math&amp;gt;a[i,j] = 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В общем случае не у каждой пары точек будут связи. Поэтому ожидаемый объем данных может быть намного меньше, а именно &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимальное число соседей произвольного объекта, &amp;lt;math&amp;gt;m_a&amp;lt;/math&amp;gt; - среднее значение числа соседей произвольного объекта.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура кластеризации:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039;  &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. Ожидаемый объем: &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; массив объектов, в котором значением i-го объекта является номер кластера, к которому он был приписан. &lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA&amp;lt;ref&amp;gt;https://github.com/cran/cba/blob/master/R/rock.r&amp;lt;/ref&amp;gt; в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka&amp;lt;ref&amp;gt;https://sourceforge.net/projects/feed4weka/files/&amp;lt;/ref&amp;gt; - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15216</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15216"/>
		<updated>2016-10-31T18:18:59Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Авторы: Таратута Екатерина (1.1, 1.3, 1.4, 1.5, 1.6, 1.8, 1.10), Жайлауова Шынар (1.2, 1.7, 1.8, 1.9, 2.7)&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Вычислительное ядро алгоритма==&lt;br /&gt;
:Основная вычислительная нагрузка в алгоритме приходится на умножение матриц при вычислении числа связей. Оно имеет квадратичную сложность. &lt;br /&gt;
:Также большую вычислительную нагрузку дает цикл, в котором обновляются локальная и глобальная кучи после объединения двух кластеров в один.&lt;br /&gt;
&lt;br /&gt;
==Макроструктура алгоритма==&lt;br /&gt;
Как написано и в описании ядра алгоритма, основную часть метода составляют вычисление связей между объектами и объединение кластеров.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:2.png]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Процедура &amp;lt;math&amp;gt;compute\_links()&amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе  &amp;lt;math&amp;gt;a[i,j] = 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В общем случае не у каждой пары точек будут связи. Поэтому ожидаемый объем данных может быть намного меньше, а именно &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимальное число соседей произвольного объекта, &amp;lt;math&amp;gt;m_a&amp;lt;/math&amp;gt; - среднее значение числа соседей произвольного объекта.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура кластеризации:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039;  &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. Ожидаемый объем: &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; массив объектов, в котором значением i-го объекта является номер кластера, к которому он был приписан. &lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA&amp;lt;ref&amp;gt;https://github.com/cran/cba/blob/master/R/rock.r&amp;lt;/ref&amp;gt; в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka&amp;lt;ref&amp;gt;https://sourceforge.net/projects/feed4weka/files/&amp;lt;/ref&amp;gt; - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15215</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15215"/>
		<updated>2016-10-31T18:17:18Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Авторы: Таратута Екатерина (1.1, 1.3, 1.4, 1.5, 1.6, 1.8, 1.10) , Жайлауова Шынар (1.2, 1.7, 1.8, 1.9, 2.7)&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Вычислительное ядро алгоритма==&lt;br /&gt;
:Основная вычислительная нагрузка в алгоритме приходится на умножение матриц при вычислении числа связей. Оно имеет квадратичную сложность. &lt;br /&gt;
:Также большую вычислительную нагрузку дает цикл, в котором обновляются локальная и глобальная кучи после объединения двух кластеров в один.&lt;br /&gt;
&lt;br /&gt;
==Макроструктура алгоритма==&lt;br /&gt;
Как написано и в описании ядра алгоритма, основную часть метода составляют вычисление связей между объектами и объединение кластеров.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:2.png]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Процедура &amp;lt;math&amp;gt;compute\_links()&amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе  &amp;lt;math&amp;gt;a[i,j] = 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В общем случае не у каждой пары точек будут связи. Поэтому ожидаемый объем данных может быть намного меньше, а именно &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимальное число соседей произвольного объекта, &amp;lt;math&amp;gt;m_a&amp;lt;/math&amp;gt; - среднее значение числа соседей произвольного объекта.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура кластеризации:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039;  &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. Ожидаемый объем: &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; массив объектов, в котором значением i-го объекта является номер кластера, к которому он был приписан. &lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA&amp;lt;ref&amp;gt;https://github.com/cran/cba/blob/master/R/rock.r&amp;lt;/ref&amp;gt; в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka&amp;lt;ref&amp;gt;https://sourceforge.net/projects/feed4weka/files/&amp;lt;/ref&amp;gt; - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15214</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15214"/>
		<updated>2016-10-31T18:16:38Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Авторы: Таратута Екатерина (1.1, 1.3, 1.4, 1.5, 1.6, 1.10) , Жайлауова Шынар (1.2, 1.7, 1.8, 1.9, 2.7)&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Вычислительное ядро алгоритма==&lt;br /&gt;
:Основная вычислительная нагрузка в алгоритме приходится на умножение матриц при вычислении числа связей. Оно имеет квадратичную сложность. &lt;br /&gt;
:Также большую вычислительную нагрузку дает цикл, в котором обновляются локальная и глобальная кучи после объединения двух кластеров в один.&lt;br /&gt;
&lt;br /&gt;
==Макроструктура алгоритма==&lt;br /&gt;
Как написано и в описании ядра алгоритма, основную часть метода составляют вычисление связей между объектами и объединение кластеров.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:2.png]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Процедура &amp;lt;math&amp;gt;compute\_links()&amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе  &amp;lt;math&amp;gt;a[i,j] = 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В общем случае не у каждой пары точек будут связи. Поэтому ожидаемый объем данных может быть намного меньше, а именно &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимальное число соседей произвольного объекта, &amp;lt;math&amp;gt;m_a&amp;lt;/math&amp;gt; - среднее значение числа соседей произвольного объекта.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура кластеризации:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039;  &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. Ожидаемый объем: &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; массив объектов, в котором значением i-го объекта является номер кластера, к которому он был приписан. &lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA&amp;lt;ref&amp;gt;https://github.com/cran/cba/blob/master/R/rock.r&amp;lt;/ref&amp;gt; в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka&amp;lt;ref&amp;gt;https://sourceforge.net/projects/feed4weka/files/&amp;lt;/ref&amp;gt; - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15213</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15213"/>
		<updated>2016-10-31T18:15:41Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Авторы: Таратута Екатерина (1.1, 1.3, 1.4, 1.5, , Жайлауова Шынар (1.2&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Вычислительное ядро алгоритма==&lt;br /&gt;
:Основная вычислительная нагрузка в алгоритме приходится на умножение матриц при вычислении числа связей. Оно имеет квадратичную сложность. &lt;br /&gt;
:Также большую вычислительную нагрузку дает цикл, в котором обновляются локальная и глобальная кучи после объединения двух кластеров в один.&lt;br /&gt;
&lt;br /&gt;
==Макроструктура алгоритма==&lt;br /&gt;
Как написано и в описании ядра алгоритма, основную часть метода составляют вычисление связей между объектами и объединение кластеров.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:2.png]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Процедура &amp;lt;math&amp;gt;compute\_links()&amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе  &amp;lt;math&amp;gt;a[i,j] = 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В общем случае не у каждой пары точек будут связи. Поэтому ожидаемый объем данных может быть намного меньше, а именно &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимальное число соседей произвольного объекта, &amp;lt;math&amp;gt;m_a&amp;lt;/math&amp;gt; - среднее значение числа соседей произвольного объекта.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура кластеризации:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039;  &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. Ожидаемый объем: &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; массив объектов, в котором значением i-го объекта является номер кластера, к которому он был приписан. &lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA&amp;lt;ref&amp;gt;https://github.com/cran/cba/blob/master/R/rock.r&amp;lt;/ref&amp;gt; в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka&amp;lt;ref&amp;gt;https://sourceforge.net/projects/feed4weka/files/&amp;lt;/ref&amp;gt; - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15212</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15212"/>
		<updated>2016-10-31T18:13:14Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: /* Входные и выходные данные алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Вычислительное ядро алгоритма==&lt;br /&gt;
:Основная вычислительная нагрузка в алгоритме приходится на умножение матриц при вычислении числа связей. Оно имеет квадратичную сложность. &lt;br /&gt;
:Также большую вычислительную нагрузку дает цикл, в котором обновляются локальная и глобальная кучи после объединения двух кластеров в один.&lt;br /&gt;
&lt;br /&gt;
==Макроструктура алгоритма==&lt;br /&gt;
Как написано и в описании ядра алгоритма, основную часть метода составляют вычисление связей между объектами и объединение кластеров.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:2.png]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Процедура &amp;lt;math&amp;gt;compute\_links()&amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе  &amp;lt;math&amp;gt;a[i,j] = 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В общем случае не у каждой пары точек будут связи. Поэтому ожидаемый объем данных может быть намного меньше, а именно &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимальное число соседей произвольного объекта, &amp;lt;math&amp;gt;m_a&amp;lt;/math&amp;gt; - среднее значение числа соседей произвольного объекта.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура кластеризации:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039;  &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. Ожидаемый объем: &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; массив объектов, в котором значением i-го объекта является номер кластера, к которому он был приписан. &lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA&amp;lt;ref&amp;gt;https://github.com/cran/cba/blob/master/R/rock.r&amp;lt;/ref&amp;gt; в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka&amp;lt;ref&amp;gt;https://sourceforge.net/projects/feed4weka/files/&amp;lt;/ref&amp;gt; - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15208</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15208"/>
		<updated>2016-10-31T18:06:50Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: /* Макроструктура алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,n}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Вычислительное ядро алгоритма==&lt;br /&gt;
:Основная вычислительная нагрузка в алгоритме приходится на умножение матриц при вычислении числа связей. Оно имеет квадратичную сложность. &lt;br /&gt;
:Также большую вычислительную нагрузку дает цикл, в котором обновляются локальная и глобальная кучи после объединения двух кластеров в один.&lt;br /&gt;
&lt;br /&gt;
==Макроструктура алгоритма==&lt;br /&gt;
Как написано и в описании ядра алгоритма, основную часть метода составляют вычисление связей между объектами и объединение кластеров.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:2.png]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Процедура &amp;lt;math&amp;gt;compute\_links()&amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе  &amp;lt;math&amp;gt;a[i,j] = 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В общем случае не у каждой пары точек будут связи. Поэтому ожидаемый объем данных может быть намного меньше, а именно &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимальное число соседей произвольного объекта, &amp;lt;math&amp;gt;m_a&amp;lt;/math&amp;gt; - среднее значение числа соседей произвольного объекта.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура кластеризации:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039;  &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. Ожидаемый объем: &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; массив объектов, значениями которого являются номера кластера, к которому он был отнесен. &lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA&amp;lt;ref&amp;gt;https://github.com/cran/cba/blob/master/R/rock.r&amp;lt;/ref&amp;gt; в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka&amp;lt;ref&amp;gt;https://sourceforge.net/projects/feed4weka/files/&amp;lt;/ref&amp;gt; - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15200</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15200"/>
		<updated>2016-10-31T17:58:43Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: /* Входные и выходные данные алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,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;
Как записано и в описании ядра алгоритма, основную часть метода составляют &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt; обновлений содержимого локальной и глобальной куч.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:2.png]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Процедура &amp;lt;math&amp;gt;compute\_links()&amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе  &amp;lt;math&amp;gt;a[i,j] = 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В общем случае не у каждой пары точек будут связи. Поэтому ожидаемый объем данных может быть намного меньше, а именно &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимальное число соседей произвольного объекта, &amp;lt;math&amp;gt;m_a&amp;lt;/math&amp;gt; - среднее значение числа соседей произвольного объекта.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура кластеризации:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039;  &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. Ожидаемый объем: &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; массив объектов, значениями которого являются номера кластера, к которому он был отнесен. &lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA&amp;lt;ref&amp;gt;https://github.com/cran/cba/blob/master/R/rock.r&amp;lt;/ref&amp;gt; в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka&amp;lt;ref&amp;gt;https://sourceforge.net/projects/feed4weka/files/&amp;lt;/ref&amp;gt; - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15195</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15195"/>
		<updated>2016-10-31T17:41:11Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: /* Входные и выходные данные алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,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;
Как записано и в описании ядра алгоритма, основную часть метода составляют &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt; обновлений содержимого локальной и глобальной куч.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:2.png]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Процедура &amp;lt;math&amp;gt;compute\_links()&amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе  &amp;lt;math&amp;gt;a[i,j] = 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В общем случае не у каждой пары точек будут связи. Поэтому ожидаемый объем данных может быть намного меньше, а именно &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимальное число соседей произвольного объекта, &amp;lt;math&amp;gt;m_a&amp;lt;/math&amp;gt; - среднее значение числа соседей произвольного объекта.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура кластеризации:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039;  &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. Ожидаемый объем: &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; !!!!&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA&amp;lt;ref&amp;gt;https://github.com/cran/cba/blob/master/R/rock.r&amp;lt;/ref&amp;gt; в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka&amp;lt;ref&amp;gt;https://sourceforge.net/projects/feed4weka/files/&amp;lt;/ref&amp;gt; - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15194</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15194"/>
		<updated>2016-10-31T17:40:01Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: /* Существующие реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,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;
Как записано и в описании ядра алгоритма, основную часть метода составляют &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt; обновлений содержимого локальной и глобальной куч.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:2.png]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; на вход подается &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; объектов и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - количество кластеров, на которое необходимо разделить объекты и некоторое пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, принимающее значение от 0 до 1.&lt;br /&gt;
:Задаются входные данные в частном случае в виде массива длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, но так как вообще говоря данные могут иметь не один атрибут, потребуется матрица размера &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;, состоящей из 0 и 1, где &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов, а 0 и 1 стоят в зависимости от того, есть ли такой атрибут у данного объекта или нет. &lt;br /&gt;
:&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; Группа кластеризованных данных.&lt;br /&gt;
:Выходные данные представлены в виде массива из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; элементов, где каждому элементу сопоставлен номер кластера, в который он попал.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура &amp;lt;math&amp;gt;compute\_links()&amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе  &amp;lt;math&amp;gt;a[i,j] = 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В общем случае не у каждой пары точек будут связи. Поэтому ожидаемый объем данных может быть намного меньше, а именно &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимальное число соседей произвольного объекта, &amp;lt;math&amp;gt;m_a&amp;lt;/math&amp;gt; - среднее значение числа соседей произвольного объекта.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура кластеризации:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039;  &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. Ожидаемый объем: &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; !!!!&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA&amp;lt;ref&amp;gt;https://github.com/cran/cba/blob/master/R/rock.r&amp;lt;/ref&amp;gt; в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka&amp;lt;ref&amp;gt;https://sourceforge.net/projects/feed4weka/files/&amp;lt;/ref&amp;gt; - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15193</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15193"/>
		<updated>2016-10-31T17:37:48Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: /* Существующие реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,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;
Как записано и в описании ядра алгоритма, основную часть метода составляют &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt; обновлений содержимого локальной и глобальной куч.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:2.png]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; на вход подается &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; объектов и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - количество кластеров, на которое необходимо разделить объекты и некоторое пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, принимающее значение от 0 до 1.&lt;br /&gt;
:Задаются входные данные в частном случае в виде массива длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, но так как вообще говоря данные могут иметь не один атрибут, потребуется матрица размера &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;, состоящей из 0 и 1, где &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов, а 0 и 1 стоят в зависимости от того, есть ли такой атрибут у данного объекта или нет. &lt;br /&gt;
:&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; Группа кластеризованных данных.&lt;br /&gt;
:Выходные данные представлены в виде массива из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; элементов, где каждому элементу сопоставлен номер кластера, в который он попал.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура &amp;lt;math&amp;gt;compute\_links()&amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе  &amp;lt;math&amp;gt;a[i,j] = 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В общем случае не у каждой пары точек будут связи. Поэтому ожидаемый объем данных может быть намного меньше, а именно &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимальное число соседей произвольного объекта, &amp;lt;math&amp;gt;m_a&amp;lt;/math&amp;gt; - среднее значение числа соседей произвольного объекта.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура кластеризации:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039;  &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. Ожидаемый объем: &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; !!!!&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka&amp;lt;ref&amp;gt;https://sourceforge.net/projects/feed4weka/files/&amp;lt;/ref&amp;gt; - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15183</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15183"/>
		<updated>2016-10-31T16:57:04Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: /* Входные и выходные данные алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,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;
Как записано и в описании ядра алгоритма, основную часть метода составляют &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt; обновлений содержимого локальной и глобальной куч.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:2.png]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; на вход подается &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; объектов и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - количество кластеров, на которое необходимо разделить объекты и некоторое пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, принимающее значение от 0 до 1.&lt;br /&gt;
:Задаются входные данные в частном случае в виде массива длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, но так как вообще говоря данные могут иметь не один атрибут, потребуется матрица размера &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;, состоящей из 0 и 1, где &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов, а 0 и 1 стоят в зависимости от того, есть ли такой атрибут у данного объекта или нет. &lt;br /&gt;
:&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; Группа кластеризованных данных.&lt;br /&gt;
:Выходные данные представлены в виде массива из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; элементов, где каждому элементу сопоставлен номер кластера, в который он попал.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура &amp;lt;math&amp;gt;compute\_links()&amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе  &amp;lt;math&amp;gt;a[i,j] = 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В общем случае не у каждой пары точек будут связи. Поэтому ожидаемый объем данных может быть намного меньше, а именно &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимальное число соседей произвольного объекта, &amp;lt;math&amp;gt;m_a&amp;lt;/math&amp;gt; - среднее значение числа соседей произвольного объекта.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура кластеризации:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039;  &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. Ожидаемый объем: &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; !!!!&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15179</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15179"/>
		<updated>2016-10-31T16:43:56Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: /* Входные и выходные данные алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,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;
Как записано и в описании ядра алгоритма, основную часть метода составляют &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt; обновлений содержимого локальной и глобальной куч.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:2.png]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; на вход подается &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; объектов и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - количество кластеров, на которое необходимо разделить объекты и некоторое пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, принимающее значение от 0 до 1.&lt;br /&gt;
:Задаются входные данные в частном случае в виде массива длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, но так как вообще говоря данные могут иметь не один атрибут, потребуется матрица размера &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;, состоящей из 0 и 1, где &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов, а 0 и 1 стоят в зависимости от того, есть ли такой атрибут у данного объекта или нет. &lt;br /&gt;
:&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; Группа кластеризованных данных.&lt;br /&gt;
:Выходные данные представлены в виде массива из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; элементов, где каждому элементу сопоставлен номер кластера, в который он попал.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура &amp;lt;math&amp;gt;compute\_links()&amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе  &amp;lt;math&amp;gt;a[i,j] = 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В общем случае не у каждой пары точек будут связи. Поэтому ожидаемый объем данных может быть намного меньше, а именно &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимальное число соседей произвольного объекта, &amp;lt;math&amp;gt;m_a&amp;lt;/math&amp;gt; - среднее значение числа соседей произвольного объекта.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура кластеризации:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039;  &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. Ожидаемый объем: &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;a[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15176</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15176"/>
		<updated>2016-10-31T16:24:56Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: /* Входные и выходные данные алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,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;
Как записано и в описании ядра алгоритма, основную часть метода составляют &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt; обновлений содержимого локальной и глобальной куч.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:2.png]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; на вход подается &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; объектов и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - количество кластеров, на которое необходимо разделить объекты и некоторое пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, принимающее значение от 0 до 1.&lt;br /&gt;
:Задаются входные данные в частном случае в виде массива длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, но так как вообще говоря данные могут иметь не один атрибут, потребуется матрица размера &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;, состоящей из 0 и 1, где &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов, а 0 и 1 стоят в зависимости от того, есть ли такой атрибут у данного объекта или нет. &lt;br /&gt;
:&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; Группа кластеризованных данных.&lt;br /&gt;
:Выходные данные представлены в виде массива из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; элементов, где каждому элементу сопоставлен номер кластера, в который он попал.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура &amp;lt;math&amp;gt;compute\_links()&amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе  &amp;lt;math&amp;gt;a[i,j] = 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В общем случае не у каждой пары точек будут связи. Поэтому ожидаемый объем данных может быть намного меньше, а именно &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимальное число соседей произвольного объекта, &amp;lt;math&amp;gt;m_a&amp;lt;/math&amp;gt; - среднее значение числа соседей произвольного объекта.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура кластеризации:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;b[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039;  &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. Ожидаемый объем: &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;a[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В общем случае не у каждой пары точек будут связи. Поэтому ожидаемый объем данных может быть намного меньше, а именно &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимальное число соседей произвольного объекта, &amp;lt;math&amp;gt;m_a&amp;lt;/math&amp;gt; - среднее значение числа соседей произвольного объекта.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15173</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15173"/>
		<updated>2016-10-31T16:19:03Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: /* Входные и выходные данные алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,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;
Как записано и в описании ядра алгоритма, основную часть метода составляют &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt; обновлений содержимого локальной и глобальной куч.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:2.png]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; на вход подается &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; объектов и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - количество кластеров, на которое необходимо разделить объекты и некоторое пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, принимающее значение от 0 до 1.&lt;br /&gt;
:Задаются входные данные в частном случае в виде массива длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, но так как вообще говоря данные могут иметь не один атрибут, потребуется матрица размера &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;, состоящей из 0 и 1, где &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов, а 0 и 1 стоят в зависимости от того, есть ли такой атрибут у данного объекта или нет. &lt;br /&gt;
:&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; Группа кластеризованных данных.&lt;br /&gt;
:Выходные данные представлены в виде массива из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; элементов, где каждому элементу сопоставлен номер кластера, в который он попал.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура &amp;lt;math&amp;gt;compute\_links()&amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе  &amp;lt;math&amp;gt;a[i,j] = 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;a[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В общем случае не у каждой пары точек будут связи. Поэтому ожидаемый объем данных может быть намного меньше, а именно &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимальное число соседей произвольного объекта, &amp;lt;math&amp;gt;m_a&amp;lt;/math&amp;gt; - среднее значение числа соседей произвольного объекта.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура кластеризации:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;a[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;a[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В общем случае не у каждой пары точек будут связи. Поэтому ожидаемый объем данных может быть намного меньше, а именно &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимальное число соседей произвольного объекта, &amp;lt;math&amp;gt;m_a&amp;lt;/math&amp;gt; - среднее значение числа соседей произвольного объекта.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15171</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15171"/>
		<updated>2016-10-31T16:17:11Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: /* Входные и выходные данные алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,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;
Как записано и в описании ядра алгоритма, основную часть метода составляют &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt; обновлений содержимого локальной и глобальной куч.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:2.png]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; на вход подается &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; объектов и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - количество кластеров, на которое необходимо разделить объекты и некоторое пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, принимающее значение от 0 до 1.&lt;br /&gt;
:Задаются входные данные в частном случае в виде массива длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, но так как вообще говоря данные могут иметь не один атрибут, потребуется матрица размера &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;, состоящей из 0 и 1, где &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов, а 0 и 1 стоят в зависимости от того, есть ли такой атрибут у данного объекта или нет. &lt;br /&gt;
:&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; Группа кластеризованных данных.&lt;br /&gt;
:Выходные данные представлены в виде массива из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; элементов, где каждому элементу сопоставлен номер кластера, в который он попал.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура &amp;lt;math&amp;gt;compute\_links()&amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе  &amp;lt;math&amp;gt;a[i,j] = 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;a[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В общем случае не у каждой пары точек будут связи. Поэтому ожидаемый объем данных может быть намного меньше, а именно &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимальное число соседей произвольного объекта, &amp;lt;math&amp;gt;m_a&amp;lt;/math&amp;gt; - среднее значение числа соседей произвольного объекта.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15169</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15169"/>
		<updated>2016-10-31T16:13:40Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: /* Входные и выходные данные алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,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;
Как записано и в описании ядра алгоритма, основную часть метода составляют &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt; обновлений содержимого локальной и глобальной куч.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:2.png]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; на вход подается &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; объектов и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - количество кластеров, на которое необходимо разделить объекты и некоторое пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, принимающее значение от 0 до 1.&lt;br /&gt;
:Задаются входные данные в частном случае в виде массива длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, но так как вообще говоря данные могут иметь не один атрибут, потребуется матрица размера &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;, состоящей из 0 и 1, где &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов, а 0 и 1 стоят в зависимости от того, есть ли такой атрибут у данного объекта или нет. &lt;br /&gt;
:&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; Группа кластеризованных данных.&lt;br /&gt;
:Выходные данные представлены в виде массива из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; элементов, где каждому элементу сопоставлен номер кластера, в который он попал.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура &amp;lt;math&amp;gt;compute\_links()&amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе  &amp;lt;math&amp;gt;a[i,j] = 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;a[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;. В общем случае не у каждой пары точек будут связи. Поэтому ожидаемый объем данных может быть намного меньше, а именно &amp;lt;math&amp;gt;O(min\{nm_mm_a, n^2\})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15168</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15168"/>
		<updated>2016-10-31T16:09:23Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: /* Входные и выходные данные алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,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;
Как записано и в описании ядра алгоритма, основную часть метода составляют &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt; обновлений содержимого локальной и глобальной куч.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:2.png]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; на вход подается &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; объектов и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - количество кластеров, на которое необходимо разделить объекты и некоторое пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, принимающее значение от 0 до 1.&lt;br /&gt;
:Задаются входные данные в частном случае в виде массива длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, но так как вообще говоря данные могут иметь не один атрибут, потребуется матрица размера &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;, состоящей из 0 и 1, где &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов, а 0 и 1 стоят в зависимости от того, есть ли такой атрибут у данного объекта или нет. &lt;br /&gt;
:&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; Группа кластеризованных данных.&lt;br /&gt;
:Выходные данные представлены в виде массива из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; элементов, где каждому элементу сопоставлен номер кластера, в который он попал.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура &amp;lt;math&amp;gt;compute\_links()&amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе  &amp;lt;math&amp;gt;a[i,j] = 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;a[i,j]:&amp;lt;/math&amp;gt; указывает на количество связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15167</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15167"/>
		<updated>2016-10-31T16:08:38Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: /* Входные и выходные данные алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,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;
Как записано и в описании ядра алгоритма, основную часть метода составляют &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt; обновлений содержимого локальной и глобальной куч.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:2.png]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; на вход подается &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; объектов и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - количество кластеров, на которое необходимо разделить объекты и некоторое пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, принимающее значение от 0 до 1.&lt;br /&gt;
:Задаются входные данные в частном случае в виде массива длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, но так как вообще говоря данные могут иметь не один атрибут, потребуется матрица размера &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;, состоящей из 0 и 1, где &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов, а 0 и 1 стоят в зависимости от того, есть ли такой атрибут у данного объекта или нет. &lt;br /&gt;
:&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; Группа кластеризованных данных.&lt;br /&gt;
:Выходные данные представлены в виде массива из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; элементов, где каждому элементу сопоставлен номер кластера, в который он попал.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура &amp;lt;math&amp;gt;compute\_links()&amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе  &amp;lt;math&amp;gt;a[i,j] = 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;. Элемент &amp;lt;math&amp;gt;a[i,j]:&amp;lt;/math&amp;gt; указывает на количество &lt;br /&gt;
связей между соответствующими объектами.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15165</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15165"/>
		<updated>2016-10-31T16:04:55Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: /* Входные и выходные данные алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,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;
Как записано и в описании ядра алгоритма, основную часть метода составляют &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt; обновлений содержимого локальной и глобальной куч.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:2.png]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; на вход подается &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; объектов и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - количество кластеров, на которое необходимо разделить объекты и некоторое пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, принимающее значение от 0 до 1.&lt;br /&gt;
:Задаются входные данные в частном случае в виде массива длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, но так как вообще говоря данные могут иметь не один атрибут, потребуется матрица размера &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;, состоящей из 0 и 1, где &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов, а 0 и 1 стоят в зависимости от того, есть ли такой атрибут у данного объекта или нет. &lt;br /&gt;
:&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; Группа кластеризованных данных.&lt;br /&gt;
:Выходные данные представлены в виде массива из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; элементов, где каждому элементу сопоставлен номер кластера, в который он попал.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура &amp;lt;math&amp;gt;compute\_links()&amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе  &amp;lt;math&amp;gt;a[i,j] = 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; симметричная матрица связей &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15163</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15163"/>
		<updated>2016-10-31T16:03:12Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: /* Входные и выходные данные алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,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;
Как записано и в описании ядра алгоритма, основную часть метода составляют &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt; обновлений содержимого локальной и глобальной куч.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:2.png]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; на вход подается &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; объектов и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - количество кластеров, на которое необходимо разделить объекты и некоторое пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, принимающее значение от 0 до 1.&lt;br /&gt;
:Задаются входные данные в частном случае в виде массива длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, но так как вообще говоря данные могут иметь не один атрибут, потребуется матрица размера &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;, состоящей из 0 и 1, где &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов, а 0 и 1 стоят в зависимости от того, есть ли такой атрибут у данного объекта или нет. &lt;br /&gt;
:&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; Группа кластеризованных данных.&lt;br /&gt;
:Выходные данные представлены в виде массива из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; элементов, где каждому элементу сопоставлен номер кластера, в который он попал.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура &amp;lt;math&amp;gt;compute\_links()&amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе  &amp;lt;math&amp;gt;a[i,j] = 0:&amp;lt;/math&amp;gt;.&lt;br /&gt;
:*&#039;&#039;&#039;Объем данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15162</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15162"/>
		<updated>2016-10-31T16:02:22Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: /* Входные и выходные данные алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,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;
Как записано и в описании ядра алгоритма, основную часть метода составляют &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt; обновлений содержимого локальной и глобальной куч.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:2.png]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; на вход подается &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; объектов и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - количество кластеров, на которое необходимо разделить объекты и некоторое пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, принимающее значение от 0 до 1.&lt;br /&gt;
:Задаются входные данные в частном случае в виде массива длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, но так как вообще говоря данные могут иметь не один атрибут, потребуется матрица размера &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;, состоящей из 0 и 1, где &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов, а 0 и 1 стоят в зависимости от того, есть ли такой атрибут у данного объекта или нет. &lt;br /&gt;
:&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; Группа кластеризованных данных.&lt;br /&gt;
:Выходные данные представлены в виде массива из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; элементов, где каждому элементу сопоставлен номер кластера, в который он попал.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Процедура &amp;lt;math&amp;gt;compute\_links()&amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
:*&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;  на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе  &amp;lt;math&amp;gt;a[i,j] = 0:&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15160</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15160"/>
		<updated>2016-10-31T16:01:04Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: /* Входные и выходные данные алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,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;
Как записано и в описании ядра алгоритма, основную часть метода составляют &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt; обновлений содержимого локальной и глобальной куч.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:2.png]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; на вход подается &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; объектов и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - количество кластеров, на которое необходимо разделить объекты и некоторое пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, принимающее значение от 0 до 1.&lt;br /&gt;
:Задаются входные данные в частном случае в виде массива длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, но так как вообще говоря данные могут иметь не один атрибут, потребуется матрица размера &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;, состоящей из 0 и 1, где &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов, а 0 и 1 стоят в зависимости от того, есть ли такой атрибут у данного объекта или нет. &lt;br /&gt;
:&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; Группа кластеризованных данных.&lt;br /&gt;
:Выходные данные представлены в виде массива из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; элементов, где каждому элементу сопоставлен номер кластера, в который он попал.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;.&lt;br /&gt;
:*&#039;&#039;&#039;Процедура &amp;lt;math&amp;gt;compute\_links()&amp;lt;/math&amp;gt;:&#039;&#039;&#039; на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе  &amp;lt;math&amp;gt;a[i,j] = 0:&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15159</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15159"/>
		<updated>2016-10-31T16:00:11Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: /* Входные и выходные данные алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,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;
Как записано и в описании ядра алгоритма, основную часть метода составляют &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt; обновлений содержимого локальной и глобальной куч.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:2.png]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; на вход подается &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; объектов и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - количество кластеров, на которое необходимо разделить объекты и некоторое пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, принимающее значение от 0 до 1.&lt;br /&gt;
:Задаются входные данные в частном случае в виде массива длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, но так как вообще говоря данные могут иметь не один атрибут, потребуется матрица размера &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;, состоящей из 0 и 1, где &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов, а 0 и 1 стоят в зависимости от того, есть ли такой атрибут у данного объекта или нет. &lt;br /&gt;
:&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; Группа кластеризованных данных.&lt;br /&gt;
:Выходные данные представлены в виде массива из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; элементов, где каждому элементу сопоставлен номер кластера, в который он попал.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;.&lt;br /&gt;
:*&#039;&#039;&#039;Процедура &amp;lt;math&amp;gt;compute\_links()&amp;lt;/math&amp;gt;:&#039;&#039;&#039; на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе - &amp;lt;math&amp;gt;a[i,j] = 0:&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15158</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15158"/>
		<updated>2016-10-31T15:57:50Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: /* Входные и выходные данные алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,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;
Как записано и в описании ядра алгоритма, основную часть метода составляют &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt; обновлений содержимого локальной и глобальной куч.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:2.png]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; на вход подается &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; объектов и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - количество кластеров, на которое необходимо разделить объекты и некоторое пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, принимающее значение от 0 до 1.&lt;br /&gt;
:Задаются входные данные в частном случае в виде массива длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, но так как вообще говоря данные могут иметь не один атрибут, потребуется матрица размера &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;, состоящей из 0 и 1, где &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов, а 0 и 1 стоят в зависимости от того, есть ли такой атрибут у данного объекта или нет. &lt;br /&gt;
:&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; Группа кластеризованных данных.&lt;br /&gt;
:Выходные данные представлены в виде массива из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; элементов, где каждому элементу сопоставлен номер кластера, в который он попал.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;.&lt;br /&gt;
:*&#039;&#039;&#039;Процедура &amp;lt;math&amp;gt;compute_links()&amp;lt;/math&amp;gt;:&#039;&#039;&#039;на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе - &amp;lt;math&amp;gt;a[i,j] = 0:&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15157</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15157"/>
		<updated>2016-10-31T15:57:33Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: /* Входные и выходные данные алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,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;
Как записано и в описании ядра алгоритма, основную часть метода составляют &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt; обновлений содержимого локальной и глобальной куч.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:2.png]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; на вход подается &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; объектов и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - количество кластеров, на которое необходимо разделить объекты и некоторое пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, принимающее значение от 0 до 1.&lt;br /&gt;
:Задаются входные данные в частном случае в виде массива длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, но так как вообще говоря данные могут иметь не один атрибут, потребуется матрица размера &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;, состоящей из 0 и 1, где &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов, а 0 и 1 стоят в зависимости от того, есть ли такой атрибут у данного объекта или нет. &lt;br /&gt;
:&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; Группа кластеризованных данных.&lt;br /&gt;
:Выходные данные представлены в виде массива из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; элементов, где каждому элементу сопоставлен номер кластера, в который он попал.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;.&lt;br /&gt;
*:&#039;&#039;&#039;Процедура &amp;lt;math&amp;gt;compute_links()&amp;lt;/math&amp;gt;:&#039;&#039;&#039;на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе - &amp;lt;math&amp;gt;a[i,j] = 0:&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15156</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15156"/>
		<updated>2016-10-31T15:55:52Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: /* Входные и выходные данные алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,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;
Как записано и в описании ядра алгоритма, основную часть метода составляют &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt; обновлений содержимого локальной и глобальной куч.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:2.png]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; на вход подается &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; объектов и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - количество кластеров, на которое необходимо разделить объекты и некоторое пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, принимающее значение от 0 до 1.&lt;br /&gt;
:Задаются входные данные в частном случае в виде массива длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, но так как вообще говоря данные могут иметь не один атрибут, потребуется матрица размера &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;, состоящей из 0 и 1, где &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов, а 0 и 1 стоят в зависимости от того, есть ли такой атрибут у данного объекта или нет. &lt;br /&gt;
:&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; Группа кластеризованных данных.&lt;br /&gt;
:Выходные данные представлены в виде массива из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; элементов, где каждому элементу сопоставлен номер кластера, в который он попал.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе - &amp;lt;math&amp;gt;a[i,j] = 0:&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%A5%D0%BE%D0%BB%D0%B5%D1%86%D0%BA%D0%BE%D0%B3%D0%BE_(%D0%BA%D0%B2%D0%B0%D0%B4%D1%80%D0%B0%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BA%D0%BE%D1%80%D0%BD%D1%8F),_%D1%82%D0%BE%D1%87%D0%B5%D1%87%D0%BD%D1%8B%D0%B9_%D0%B2%D0%B5%D1%89%D0%B5%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%B2%D0%B0%D1%80%D0%B8%D0%B0%D0%BD%D1%82&amp;diff=15155</id>
		<title>Метод Холецкого (квадратного корня), точечный вещественный вариант</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%A5%D0%BE%D0%BB%D0%B5%D1%86%D0%BA%D0%BE%D0%B3%D0%BE_(%D0%BA%D0%B2%D0%B0%D0%B4%D1%80%D0%B0%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BA%D0%BE%D1%80%D0%BD%D1%8F),_%D1%82%D0%BE%D1%87%D0%B5%D1%87%D0%BD%D1%8B%D0%B9_%D0%B2%D0%B5%D1%89%D0%B5%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%B2%D0%B0%D1%80%D0%B8%D0%B0%D0%BD%D1%82&amp;diff=15155"/>
		<updated>2016-10-31T15:55:12Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: /* Описание входных и выходных данных */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Описание свойств и структуры алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Словесное описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Метод Холецкого&#039;&#039;&#039; (в советской математической литературе называется также &#039;&#039;&#039;методом квадратного корня&#039;&#039;&#039;) используется для разложения положительно определённых эрмитовых (&#039;&#039;в вещественном случае - симметрических&#039;&#039;) матриц в виде &amp;lt;math&amp;gt;A = L L^*&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; — левая треугольная матрица) или в виде &amp;lt;math&amp;gt;A = U^* U&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; — правая треугольная матрица; эти разложения совершенно эквивалентны друг другу по вычислениям и различаются только способом представления данных). Он заключается в реализации формул для элементов матрицы &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt;, получающихся из вышеприведённого равенства единственным образом. Получил распространение благодаря следующим особенностям: а) симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса; б) позволяет использовать так называемый &#039;&#039;режим накопления&#039;&#039;, обусловленный тем, что значительную часть вычислений составляют &#039;&#039;вычисления скалярных произведений&#039;&#039;; с его использованием разложение методом Холецкого имеет наименьшее &#039;&#039;эквивалентное возмущение&#039;&#039; из всех известных разложений матриц.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание ===&lt;br /&gt;
&lt;br /&gt;
Исходные данные: положительно определённая симметрическая матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: левая треугольная матрица &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;l_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Формулы метода:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
l_{11} &amp;amp; = \sqrt{a_{11}}, \\&lt;br /&gt;
l_{j1} &amp;amp; = \frac{a_{j1}}{l_{11}}, \quad j \in [2, n], \\&lt;br /&gt;
l_{ii} &amp;amp; = \sqrt{a_{ii} - \sum_{p = 1}^{i - 1} l_{ip}^2}, \quad i \in [2, n], \\&lt;br /&gt;
l_{ji} &amp;amp; = \left (a_{ji} - \sum_{p = 1}^{i - 1} l_{ip} l_{jp} \right ) / l_{ii}, \quad i \in [2, n - 1], j \in [i + 1, n].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Существует также блочная версия метода, однако в данном описании разобран только точечный метод.&lt;br /&gt;
&lt;br /&gt;
В ряде реализаций деление на диагональный элемент выполняется в два этапа: вычисление &amp;lt;math&amp;gt;\frac{1}{l_{ii}}&amp;lt;/math&amp;gt; и затем умножение на него всех (видоизменённых) &amp;lt;math&amp;gt;a_{ji}&amp;lt;/math&amp;gt; . Здесь мы этот вариант алгоритма не рассматриваем. Заметим только, что он имеет худшие параллельные характеристики, чем представленный.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательной версии метода Холецкого можно составить из множественных (всего их &amp;lt;math&amp;gt;\frac{n (n - 1)}{2}&amp;lt;/math&amp;gt;) вычислений скалярных произведений строк матрицы:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\sum_{p = 1}^{i - 1} l_{ip} l_{jp}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
в режиме накопления или без него, в зависимости от требований задачи. В отечественных реализациях, даже в последовательных, упомянутый способ представления не используется. Дело в том, что даже в этих реализациях метода вычисление сумм типа&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;a_{ji} - \sum_{p = 1}^{i - 1} l_{ip} l_{jp}&amp;lt;/math&amp;gt;&amp;lt;nowiki/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
в которых и встречаются скалярные произведения, ведутся не в порядке «вычислили скалярное произведение, а потом вычли его из элемента», а путём вычитания из элемента покомпонентных произведений, являющихся частями скалярных произведений. Поэтому следует считать вычислительным ядром метода не вычисления скалярных произведений, а вычисления выражений&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;a_{ji} - \sum_{p = 1}^{i - 1} l_{ip} l_{jp}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
в &#039;&#039;режиме накопления&#039;&#039; или без него.&lt;br /&gt;
&lt;br /&gt;
Тем не менее, в популярных зарубежных реализациях точечного метода Холецкого, в частности, в библиотеках LINPACK и LAPACK, основанных на BLAS, используются именно вычисления скалярных произведений в виде вызова соответствующих подпрограмм BLAS (конкретно — функции SDOT). На последовательном уровне это влечёт за собой дополнительную операцию суммирования на каждый из &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; вычисляемый элемент матрицы &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; и некоторое замедление работы программы (о других следствиях рассказано ниже в разделе «[[#Существующие реализации алгоритма|Существующие реализации алгоритма]]»). Поэтому в данных вариантах ядром метода Холецкого будут вычисления этих скалярных произведений.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как уже записано в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть метода составляют множественные (всего &amp;lt;math&amp;gt;\frac{n (n - 1)}{2}&amp;lt;/math&amp;gt;) вычисления сумм&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;a_{ji}-\sum_{p=1}^{i-1}l_{ip} l_{jp}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
в режиме накопления или без него.&lt;br /&gt;
&lt;br /&gt;
=== Описание схемы реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Чтобы понять последовательность исполнения, перепишем формулы метода так:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;l_{11}= \sqrt{a_{11}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;l_{j1}= \frac{a_{j1}}{l_{11}}&amp;lt;/math&amp;gt; (при &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; от &amp;lt;math&amp;gt;2&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;i&amp;lt;/math&amp;gt; от &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; по нарастанию выполняются &lt;br /&gt;
&lt;br /&gt;
3. &amp;lt;math&amp;gt;l_{ii} = \sqrt{a_{ii} - \sum_{p = 1}^{i - 1} l_{ip}^2}&amp;lt;/math&amp;gt; и&lt;br /&gt;
&lt;br /&gt;
4. (кроме &amp;lt;math&amp;gt;i = n&amp;lt;/math&amp;gt;): &amp;lt;nowiki/&amp;gt;&amp;lt;math&amp;gt;l_{ji} = \left (a_{ji} - \sum_{p = 1}^{i - 1} l_{ip} l_{jp} \right ) / l_{ii}&amp;lt;/math&amp;gt; (для всех &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; от &amp;lt;math&amp;gt;i + 1&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;i &amp;lt; n&amp;lt;/math&amp;gt;) происходит переход к шагу 3 с бо́льшим &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Особо отметим, что вычисления сумм вида &amp;lt;math&amp;gt;a_{ji} - \sum_{p = 1}^{i - 1} l_{ip} l_{jp}&amp;lt;/math&amp;gt; в обеих формулах производят в режиме накопления вычитанием из &amp;lt;math&amp;gt;a_{ji}&amp;lt;/math&amp;gt; произведений &amp;lt;math&amp;gt;l_{ip} l_{jp}&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;i - 1&amp;lt;/math&amp;gt;, c нарастанием &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;. Другие порядки выполнения суммирования не распространены.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для разложения матрицы порядка n методом Холецкого в последовательном (наиболее быстром) варианте требуется:&lt;br /&gt;
	&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; вычислений квадратного корня,&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n(n-1)}{2}&amp;lt;/math&amp;gt; делений,&lt;br /&gt;
* по &amp;lt;math&amp;gt;\frac{n^3-n}{6}&amp;lt;/math&amp;gt; умножений и сложений (вычитаний) — &#039;&#039;основная часть алгоритма&#039;&#039;.&lt;br /&gt;
 &lt;br /&gt;
При этом использование режима накопления требует совершения умножений и вычитаний в режиме двойной точности (или использования функции вроде DPROD в Фортране), что ещё больше увеличивает долю умножений и сложений/вычитаний во времени, требуемом для выполнения метода Холецкого.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, метод Холецкого относится к алгоритмам &#039;&#039;с кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем [[глоссарий#Граф алгоритма|граф алгоритма]] как аналитически, так и в виде рисунка. &lt;br /&gt;
&lt;br /&gt;
Граф алгоритма состоит из трёх групп вершин, расположенных в целочисленных узлах трёх областей разной размерности.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в одномерной области, соответствующая ей операция вычисляет функцию SQRT. &lt;br /&gt;
Естественно введённая единственная координата каждой из вершин &amp;lt;math&amp;gt;i&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;
* при &amp;lt;math&amp;gt;i = 1&amp;lt;/math&amp;gt; — элемент &#039;&#039;входных данных&#039;&#039;, а именно  &amp;lt;math&amp;gt;a_{11}&amp;lt;/math&amp;gt;; &lt;br /&gt;
* при &amp;lt;math&amp;gt;i &amp;gt; 1&amp;lt;/math&amp;gt; — результат срабатывания операции, соответствующей вершине из третьей группы, с координатами &amp;lt;math&amp;gt;i - 1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;i - 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
Результат срабатывания операции является &#039;&#039;выходным данным&#039;&#039; &amp;lt;math&amp;gt;l_{ii}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин расположена в одномерной области, соответствующая ей операция &amp;lt;math&amp;gt;a / b&amp;lt;/math&amp;gt;. &lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;i+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;a&amp;lt;/math&amp;gt;: &lt;br /&gt;
** при &amp;lt;math&amp;gt;i = 1&amp;lt;/math&amp;gt; — элементы &#039;&#039;входных данных&#039;&#039;, а именно &amp;lt;math&amp;gt;a_{j1}&amp;lt;/math&amp;gt;;&lt;br /&gt;
** при &amp;lt;math&amp;gt;i &amp;gt; 1&amp;lt;/math&amp;gt; — результат срабатывания операции, соответствующей вершине из третьей группы, с координатами &amp;lt;math&amp;gt;i - 1, j, i - 1&amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt; — результат срабатывания операции, соответствующей вершине из первой группы, с координатой &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Результат срабатывания операции является &#039;&#039;выходным данным&#039;&#039; &amp;lt;math&amp;gt;l_{ji}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Третья&#039;&#039;&#039; группа вершин расположена в трёхмерной области, соответствующая ей операция  &amp;lt;math&amp;gt;a - b * c&amp;lt;/math&amp;gt;. &lt;br /&gt;
Естественно введённые координаты области таковы: &lt;br /&gt;
* &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, принимая все целочисленные значения;&lt;br /&gt;
* &amp;lt;math&amp;gt;j&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;
* &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; — меняется в диапазоне  от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;i - 1&amp;lt;/math&amp;gt;, принимая все целочисленные значения.&lt;br /&gt;
&lt;br /&gt;
Аргументы операции следующие:&lt;br /&gt;
*&amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt;:&lt;br /&gt;
** при &amp;lt;math&amp;gt;p = 1&amp;lt;/math&amp;gt; элемент входных данных &amp;lt;math&amp;gt;a_{ji}&amp;lt;/math&amp;gt;; &lt;br /&gt;
** при &amp;lt;math&amp;gt;p &amp;gt; 1&amp;lt;/math&amp;gt; — результат срабатывания операции, соответствующей вершине из третьей группы, с координатами &amp;lt;math&amp;gt;i, j, p - 1&amp;lt;/math&amp;gt;;&lt;br /&gt;
*&amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt; — результат срабатывания операции, соответствующей вершине из второй группы, с координатами &amp;lt;math&amp;gt;p, i&amp;lt;/math&amp;gt;;&lt;br /&gt;
*&amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; — результат срабатывания операции, соответствующей вершине из второй группы, с координатами &amp;lt;math&amp;gt;p, j&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
Результат срабатывания операции является &#039;&#039;промежуточным данным&#039;&#039; алгоритма.&lt;br /&gt;
&lt;br /&gt;
Описанный граф можно посмотреть на рисунке, выполненном для случая &amp;lt;math&amp;gt;n = 4&amp;lt;/math&amp;gt;. Здесь вершины первой группы обозначены жёлтым цветом и буквосочетанием sq, вершины второй — зелёным цветом и знаком деления, третьей — красным цветом и буквой f. Вершины, соответствующие операциям, производящим выходные данные алгоритма, выполнены более крупно. Дублирующие друг друга дуги даны как одна. На первом изображении показан граф алгоритма согласно классическому определению , на втором к графу алгоритма добавлены вершины , соответствующие входным данным ( обозначены синим цветом ) и выходным данным ( обозначены розовым цветом ).&lt;br /&gt;
&lt;br /&gt;
[[file:Cholesky full.png|thumb|center|1400px]]&lt;br /&gt;
[[file:Cholesky full_in_out.png|thumb|center|1400px]]&lt;br /&gt;
&lt;br /&gt;
=== Описание ресурса параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для разложения матрицы порядка &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; методом Холецкого в параллельном варианте требуется последовательно выполнить следующие ярусы:&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; ярусов с вычислением квадратного корня (единичные вычисления в каждом из ярусов),&lt;br /&gt;
* &amp;lt;math&amp;gt;n - 1&amp;lt;/math&amp;gt; ярус делений (в каждом из ярусов линейное количество делений, в зависимости от яруса — от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;n - 1&amp;lt;/math&amp;gt;),&lt;br /&gt;
* по &amp;lt;math&amp;gt;n - 1&amp;lt;/math&amp;gt; ярусов умножений и сложений/вычитаний (в каждом из ярусов — квадратичное количество операций, от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;\frac{n^2 - n}{2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
Таким образом, в параллельном варианте, в отличие от последовательного, вычисления квадратных корней и делений будут определять довольно значительную долю требуемого времени. При реализации на конкретных архитектурах наличие в отдельных ярусах [[глоссарий#Ярусно-параллельная форма графа алгоритма|ЯПФ]] отдельных вычислений квадратных корней может породить и другие проблемы. Например, при реализации на ПЛИСах остальные вычисления (деления и тем более умножения и сложения/вычитания) могут быть конвейеризованы, что даёт экономию и по ресурсам на программируемых платах; вычисления же квадратных корней из-за их изолированности приведут к занятию ресурсов на платах, которые будут простаивать большую часть времени. Таким образом, общая экономия в 2 раза, из-за которой метод Холецкого предпочитают в случае симметричных задач тому же методу Гаусса, в параллельном случае уже имеет место вовсе не по всем ресурсам, и главное - не по требуемому времени.&lt;br /&gt;
&lt;br /&gt;
При этом использование режима накопления требует совершения умножений и вычитаний в режиме двойной точности, а в параллельном варианте это означает, что практически все промежуточные вычисления для выполнения метода Холецкого в режиме накопления должны быть двойной точности. В отличие от последовательного варианта это означает увеличение требуемой памяти почти в 2 раза.&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте ЯПФ, таким образом, метод Холецкого относится к алгоритмам &#039;&#039;с линейной сложностью&#039;&#039;. При классификации по ширине ЯПФ его сложность будет &#039;&#039;квадратичной&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Описание входных и выходных данных ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: плотная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
Дополнительные ограничения:&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; – симметрическая матрица, т. е. &amp;lt;math&amp;gt;a_{ij}= a_{ji}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;.&lt;br /&gt;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; – положительно определённая матрица, т. е. для любых ненулевых векторов &amp;lt;math&amp;gt;\vec{x}&amp;lt;/math&amp;gt; выполняется &amp;lt;math&amp;gt;\vec{x}^T A \vec{x} &amp;gt; 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). В разных реализациях эта экономия хранения может быть выполнена разным образом. Например, в библиотеке, реализованной в НИВЦ МГУ, матрица A хранилась в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: левая треугольная матрица &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;l_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;.&lt;br /&gt;
*Процедура  &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt;  (в силу треугольности достаточно хранить только ненулевые - диагональ и поддиагональные - элементы). В разных реализациях эта экономия хранения может быть выполнена разным образом. Например, в той же  библиотеке, созданной в НИВЦ МГУ, матрица &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; хранилась в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов, как хорошо видно, является &#039;&#039;квадратичным&#039;&#039; (отношение кубической к линейной). &lt;br /&gt;
&lt;br /&gt;
При этом вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных – всего лишь &#039;&#039;линейна&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
При этом алгоритм почти полностью детерминирован, это гарантируется теоремой о единственности разложения. Использование другого порядка выполнения ассоциативных операций может привести к накоплению ошибок округления, однако это влияние в используемых вариантах алгоритма не так велико, как, скажем, отказ от использования режима накопления.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин, соответствующих операциям квадратного корня и деления, образуют пучки т. н. рассылок линейной мощности (то есть степень исхода этих вершин и мощность работы с этими данными — линейная функция от порядка матрицы и координат этих вершин). При этом естественно наличие в этих пучках «длинных» дуг. Остальные дуги локальны. &lt;br /&gt;
&lt;br /&gt;
Наиболее известной является компактная укладка графа — его проекция на треугольник матрицы, который перевычисляется укладываемыми операциями. При этом «длинные» дуги можно убрать, заменив более дальнюю пересылку комбинацией нескольких ближних (к соседям).&lt;br /&gt;
&lt;br /&gt;
== Программная реализация ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
В простейшем (без перестановок суммирования) варианте метод Холецкого на Фортране можно записать так:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;fortran&amp;quot;&amp;gt;&lt;br /&gt;
	DO  I = 1, N&lt;br /&gt;
		S = A(I,I)&lt;br /&gt;
		DO  IP=1, I-1&lt;br /&gt;
			S = S - DPROD(A(I,P), A(I,IP))&lt;br /&gt;
		END DO&lt;br /&gt;
		A(I,I) = SQRT (S)&lt;br /&gt;
		DO  J = I+1, N&lt;br /&gt;
			S = A(J,I)&lt;br /&gt;
			DO  IP=1, I-1&lt;br /&gt;
				S = S - DPROD(A(I,P), A(J,IP))&lt;br /&gt;
			END DO&lt;br /&gt;
			A(J,I) = S/A(I,I)&lt;br /&gt;
		END DO&lt;br /&gt;
	END DO&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
При этом для реализации режима накопления переменная &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; должна быть двойной точности. &lt;br /&gt;
&lt;br /&gt;
Для метода Холецкого существует блочная версия, которая отличается от точечной не тем, что операции над числами заменены на аналоги этих операций над блоками; её построение основано на том, что практически все циклы точечной версии имеют тип SchedDo в терминах методологии, основанной на исследовании информационного графа и, следовательно, могут быть расщеплены на составляющие. Тем не менее, обычно блочную версию метода Холецкого записывают не в виде программы с расщеплёнными и переставленными циклами, а в виде программы, подобной реализации точечного метода, в которой вместо соответствующих скалярных операций присутствуют операции над блоками.&lt;br /&gt;
&lt;br /&gt;
Для обеспечения локальности работы с памятью представляется более эффективной такая схема метода Холецкого (полностью эквивалентная описанной), когда исходная матрица и её разложение хранятся не в нижнем-левом, а в правом-верхнем треугольнике. Это связано с особенностью размещения массивов в Фортране и тем, что в этом случае вычисления скалярных произведений будут идти с выборкой идущих подряд элементов массива. &lt;br /&gt;
&lt;br /&gt;
Есть и другой вариант точечной схемы: использовать вычисляемые элементы матрицы &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; в качестве аргументов непосредственно «сразу после» их вычисления. Такая программа будет выглядеть так:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;fortran&amp;quot;&amp;gt;&lt;br /&gt;
	DO  I = 1, N&lt;br /&gt;
		A(I,I) = SQRT (A(I, I))&lt;br /&gt;
		DO  J = I+1, N&lt;br /&gt;
			A(J,I) = A(J,I)/A(I,I)&lt;br /&gt;
		END DO&lt;br /&gt;
		DO  K=I+1,N&lt;br /&gt;
			DO J = K, N&lt;br /&gt;
				A(J,K) = A(J,K) - A(J,I)*A(K,I)&lt;br /&gt;
			END DO	&lt;br /&gt;
		END DO&lt;br /&gt;
	END DO&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Как видно, в этом варианте для реализации режима накопления одинарной точности мы должны будем объявить двойную точность для массива, хранящего исходные данные и результат. Подчеркнём, что [[глоссарий#Граф алгоритма|граф алгоритма]] обеих схем - один и тот же (из п.1.7), если не считать изменением замену умножения на функцию DPROD!&lt;br /&gt;
&lt;br /&gt;
=== Описание локальности данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
==== Описание локальности алгоритма ====&lt;br /&gt;
&lt;br /&gt;
==== Описание локальности реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
===== Описание структуры обращений в память и качественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
[[file:Cholesky_locality1.jpg|thumb|center|700px|Рисунок 1. Реализация метода Холецкого. Общий профиль обращений в память]]&lt;br /&gt;
&lt;br /&gt;
На рисунке 1 представлен профиль обращений в память для реализации метода Холецкого. В программе задействован только 1 массив, поэтому в данном случае обращения в профиле происходят только к элементам этого массива. Программа состоит из одного основного этапа, который, в свою очередь, состоит из последовательности подобных итераций. Пример одной итерации выделен зеленым цветом.&lt;br /&gt;
&lt;br /&gt;
Видно, что на каждой &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й итерации используются все адреса, кроме первых &amp;lt;math&amp;gt;k_i&amp;lt;/math&amp;gt;, при этом с ростом &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; увеличивается значение &amp;lt;math&amp;gt;k_i&amp;lt;/math&amp;gt;. Также можно заметить, что число обращений в память на каждой итерации растет примерно до середины работы программы, после чего уменьшается вплоть до завершения работы. Это позволяет говорить о том, что данные в программе используются неравномерно, при этом многие итерации, особенно в начале выполнения программы, задействуют большой объем данных, что приводит к ухудшению локальности.&lt;br /&gt;
&lt;br /&gt;
Однако в данном случае основным фактором, влияющим на локальность работы с памятью, является строение итерации. Рассмотрим фрагмент профиля, соответствующий нескольким первым итерациям.&lt;br /&gt;
&lt;br /&gt;
[[file:Cholesky_locality2.jpg|thumb|center|700px|Рисунок 2. Реализация метода Холецкого. Фрагмент профиля (несколько первых итераций)]]&lt;br /&gt;
&lt;br /&gt;
Исходя из рисунка 2 видно, что каждая итерация состоит из двух различных фрагментов. Фрагмент 1 – последовательный перебор (с некоторым шагом) всех адресов, начиная с некоторого начального. При этом к каждому элементу происходит мало обращений. Такой фрагмент обладает достаточно неплохой пространственной локальностью, так как шаг по памяти между соседними обращениями невелик, но плохой временно́й локальностью, поскольку данные редко используются повторно.&lt;br /&gt;
&lt;br /&gt;
Фрагмент 2 устроен гораздо лучше с точки зрения локальности. В рамках этого фрагмента выполняется большое число обращений подряд к одним и тем же данным, что обеспечивает гораздо более высокую степень как пространственной, так и временно́й локальности по сравнению с фрагментом 1.&lt;br /&gt;
&lt;br /&gt;
После рассмотрения фрагмента профиля на рис. 2 можно оценить общую локальность двух фрагментов на каждой итерации. Однако стоит рассмотреть более подробно, как устроен каждый из фрагментов. &lt;br /&gt;
&lt;br /&gt;
[[file:Cholesky_locality3.jpg|thumb|center|700px|Рисунок 3. Реализация метода Холецкого. Фрагмент профиля (часть одной итерации)]]&lt;br /&gt;
&lt;br /&gt;
Рис. 3, на котором представлена часть одной итерации общего профиля,  позволяет отметить достаточно интересный факт: строение каждого из фрагментов на самом деле заметно сложнее, чем это выглядит на рис. 2. В частности, каждый шаг фрагмента 1 состоит из нескольких обращений к соседним элементам, причем выполняется не последовательный перебор. Также можно увидеть, что фрагмент 2 на самом деле в свою очередь состоит из повторяющихся итераций, при этом видно, что каждый шаг фрагмента 1 соответствует одной итерации фрагмента 2 (выделено зеленым на рис. 3). Это лишний раз говорит о том, что для точного понимания локальной структуры профиля необходимо его рассмотреть на уровне отдельных обращений.&lt;br /&gt;
&lt;br /&gt;
Стоит отметить, что выводы на основе рис. 3 просто дополняют общее представлении о строении профиля обращений; сделанные на основе рис. 2 выводы относительно общей локальности двух фрагментов остаются верны.&lt;br /&gt;
&lt;br /&gt;
===== Количественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
Первая оценка выполняется на основе характеристики daps, которая оценивает число выполненных обращений (чтений и записей) в память в секунду. Данная характеристика является аналогом оценки flops применительно к работе с памятью и является в большей степени оценкой производительности взаимодействия с памятью, чем оценкой локальности. Однако она служит хорошим источником информации, в том числе для сравнения с результатами по следующей характеристике cvg.&lt;br /&gt;
&lt;br /&gt;
[[file:Cholesky_locality4.jpg|thumb|center|700px|Рисунок 4. Сравнение значений оценки daps]]&lt;br /&gt;
&lt;br /&gt;
На рисунке 4 значения приведены значения daps для реализаций распространенных алгоритмов, отсортированные по возрастанию (чем больше daps, тем в общем случае выше производительность). Можно увидеть, что реализация метода Холецкого характеризуется достаточно высокой скоростью взаимодействия с памятью, однако ниже, чем, например, у теста Линпак или реализации метода Якоби.&lt;br /&gt;
&lt;br /&gt;
Вторая характеристика – cvg – предназначена для получения более машинно-независимой оценки локальности. Она определяет, насколько часто в программе необходимо подтягивать данные в кэш-память. Соответственно, чем меньше значение cvg, тем реже это нужно делать, тем лучше локальность. &lt;br /&gt;
&lt;br /&gt;
[[file:Cholesky_locality5.jpg|thumb|center|700px|Рисунок 5. Сравнение значений оценки cvg]]&lt;br /&gt;
&lt;br /&gt;
На рисунке 5 значения приведены значения cvg для того же набора реализаций, отсортированные по убыванию (чем меньше cvg, тем в общем случае выше локальность). Можно увидеть, что, согласно данной оценке, реализация метода Холецкого оказалась ниже в списке по сравнению с оценкой daps.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
===== Анализ на основе теста Apex-Map =====&lt;br /&gt;
---&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности реализации параллельного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как нетрудно видеть по структуре графа алгоритма, вариантов распараллеливания алгоритма довольно много. Например, во втором варианте (см. раздел «[[#Особенности реализации последовательного алгоритма|Особенности реализации последовательного алгоритма]]») все внутренние циклы параллельны, в первом — параллелен цикл по &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt;. Тем не менее, простое распараллеливание таким способом «в лоб» вызовет такое количество пересылок между процессорами с каждым шагом по внешнему циклу, которое почти сопоставимо с количеством арифметических операций. Поэтому перед размещением операций и данных между процессорами вычислительной системы предпочтительно разбиение всего пространства вычислений на блоки, с сопутствующим разбиением обрабатываемого массива.&lt;br /&gt;
&lt;br /&gt;
Многое зависит от конкретного типа вычислительной системы. Присутствие конвейеров на узлах многопроцессорной системы делает рентабельным параллельное вычисление нескольких скалярных произведений сразу. Подобная возможность есть и на программировании ПЛИСов, но там быстродействие будет ограничено медленным последовательным выполнением операции извлечения квадратного корня. &lt;br /&gt;
	&lt;br /&gt;
В принципе, возможно и использование т. н. «скошенного» параллелизма. Однако его на практике никто не использует, из-за усложнения управляющей структуры программы.&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
==== Описание масштабируемости алгоритма ====&lt;br /&gt;
&lt;br /&gt;
==== Описание масштабируемости реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для существующих параллельных реализаций характерно отнесение всего ресурса параллелизма на блочный уровень. Относительно низкая эффективность работы связана с проблемами внутри одного узла, следующим фактором является неоптимальное соотношение между «арифметикой» и обменами. Видно, что при некотором (довольно большом) оптимальном размере блока обмены влияют не так уж сильно.&lt;br /&gt;
&lt;br /&gt;
Для проведения экспериментов использовалась реализация разложения Холецкого, представленная в пакете SCALAPACK библиотеки Intel MKL (метод pdpotrf).  Все результаты получены на суперкомпьютере «Ломоносов». Использовались процессоры Intel Xeon X5570 с пиковой производительностью в 94 Гфлопс, а также компилятор Intel с опцией –O2. &lt;br /&gt;
&lt;br /&gt;
[[file:Cholesky_efficiency1.jpg|thumb|center|700px]]&lt;br /&gt;
&lt;br /&gt;
На рисунке показана эффективность реализации разложения Холецкого (случай использования нижних треугольников матриц) для разного числа процессов и разной размерности матрицы (10000, 20000 и 50000 элементов). Видно, что общая эффективность достаточно невысока – даже при малом числе процессов менее 10 %. Однако при всех размерностях матрицы эффективность снижается очень медленно – в самом худшем случае, при N = 10000, при увеличении числа процессов с 16 до 900 (в 56 раз) эффективность падает с 7 % до 0,8 % (всего в 9 раз). При N = 50000 эффективность уменьшается еще медленнее. &lt;br /&gt;
&lt;br /&gt;
Также стоит отметить небольшое суперлинейное ускорение, полученное на 4-х процессах для N = 10000 и N = 20000 (для N = 50000 провести эксперименты на таком малом числе процессов не удалось). Помимо более эффективной работы с кэш-памятью, оно, видимо, обусловлено тем, что эти 4 процесса помещаются на ядрах одного процессора, что позволяет использовать общую память, и, соответственно, не приводит к появлению накладных расходов, связанных с пересылкой данных.&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
Как видно по показателям SCALAPACK на суперкомпьютерах, обмены при большом n хоть и уменьшают эффективность расчётов, но слабее, чем неоптимальность организации расчётов внутри одного узла. Поэтому, видимо, следует сначала оптимизировать не блочный алгоритм, а подпрограммы, используемые на отдельных процессорах: точечный метод Холецкого, перемножения матриц и др. подпрограммы. [[#Существующие реализации алгоритма|Ниже]] содержится информация о возможном направлении такой оптимизации.&lt;br /&gt;
&lt;br /&gt;
В отношении же архитектуры типа ПЛИС вполне показателен тот момент, что разработчики — наполнители библиотек для ПЛИСов пока что не докладывают об успешных и эффективных реализациях точечного метода Холецкого на ПЛИСах. Это связано со следующим свойством информационной структуры алгоритма: если операции деления или вычисления выражений &amp;lt;math&amp;gt;a - bc&amp;lt;/math&amp;gt; являются не только массовыми, но и параллельными, и потому их вычисления сравнительно легко выстраивать в конвейеры, то операции извлечения квадратных корней являются узким местом алгоритма - отведённое на эту операцию оборудование неизбежно будет простаивать большую часть времени. Поэтому для эффективной реализации на ПЛИСах алгоритмов, столь же хороших по вычислительным характеристикам, как и метод квадратного корня, следует использовать не метод Холецкого, а его давно известную модификацию без извлечения квадратных корней — разложение матрицы в произведение &amp;lt;math&amp;gt;L D L^T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Точечный метод Холецкого реализован как в основных библиотеках программ отечественных организаций, так и в западных пакетах LINPACK, LAPACK, SCALAPACK и др. &lt;br /&gt;
	&lt;br /&gt;
При этом в отечественных реализациях, как правило, выполнены стандартные требования к методу с точки зрения ошибок округления, то есть, реализован режим накопления, и обычно нет лишних операций. Правда, анахронизмом в наше время выглядит то, что ряд старых отечественных реализаций использует для экономии памяти упаковку матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; в одномерный массив. При реальных вычислениях на современных вычислительных системах данная упаковка только создаёт дополнительные накладные расходы. Однако отечественные реализации, не использующие такую упаковку, вполне отвечают требованиям современности в отношении вычислительной точности метода.  &lt;br /&gt;
	&lt;br /&gt;
Реализация точечного метода Холецкого в современных западных пакетах страдает другими недостатками, вытекающими из того, что все эти реализации, по сути, происходят из одной и той же реализации метода в LINPACK, а та использует пакет BLAS. Основным их недостатком является даже не наличие лишних операций, о котором уже написано в разделе «[[#Вычислительное ядро алгоритма|Вычислительное ядро алгоритма]]», ибо их количество всё же невелико по сравнению с главной частью, а то, что в BLAS скалярное произведение реализовано без режима накопления. Это перечёркивает имеющиеся для метода Холецкого хорошие оценки влияния ошибок округления, поскольку они выведены как раз в предположении использования режима накопления при вычислении скалярных произведений. Поэтому тот, кто использует реализации метода Холецкого из LINPACK, LAPACK, SCALAPACK и т. п. пакетов, серьёзно рискует не получить требуемую вычислительную точность, либо ему придётся для получения хороших оценок &#039;&#039;одинарной точности&#039;&#039; использовать подпрограммы &#039;&#039;двойной&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[en:Cholesky decomposition]]&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15147</id>
		<title>Участник:Екатерина/Алгоритм устойчивой кластеризации с использованием связей</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%83%D1%81%D1%82%D0%BE%D0%B9%D1%87%D0%B8%D0%B2%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_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D1%81%D0%B2%D1%8F%D0%B7%D0%B5%D0%B9&amp;diff=15147"/>
		<updated>2016-10-31T15:45:22Z</updated>

		<summary type="html">&lt;p&gt;Екатерина: /* Входные и выходные данные алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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;S=\{s_1,\ldots,s_n\}&amp;lt;/math&amp;gt; и функция расстояния/сходства между объектами &amp;lt;math&amp;gt;\rho (x_i,x_j)&amp;lt;/math&amp;gt;. Требуется разбить множество &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; на непересекающиеся подмножества, называемые кластерами, так, чтобы каждый кластер состоял из объектов, близких по метрике &amp;lt;math&amp;gt;\rho&amp;lt;/math&amp;gt;, а объекты разных кластеров существенно отличались. При этом каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; приписывается метка(номер) кластера &amp;lt;math&amp;gt;y_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм кластеризации - это функция &amp;lt;math&amp;gt;f:X\to Y&amp;lt;/math&amp;gt;, которая каждому объекту &amp;lt;math&amp;gt;s\in S&amp;lt;/math&amp;gt; ставит в соответствие метку кластера &amp;lt;math&amp;gt;y\in Y&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Кластеризация - процесс объединения объектов, имеющих похожие характеристики, в непересекающиеся группы, называемые кластерами, так чтобы каждый кластер состоял из подобных объектов, а объекты разных кластеров отличались. При этом каждый объект характеризуется рядом признаков. Решение задачи кластеризации неоднозначно. Поэтому существует несколько типов алгоритмов кластеризации:&lt;br /&gt;
*эвристические графовые алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot;&amp;gt;К. В. Воронцов Лекции по алгоритмам кластеризации и многомерного шкалирования, 21 декабря 2007 года&amp;lt;/ref&amp;gt;&lt;br /&gt;
*статистические алгоритмы; &amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt;&lt;br /&gt;
*иерархические алгоритмы.&lt;br /&gt;
:Иерархические алгоритмы кластеризации строят не одно разбиение на непересекающиеся классы, а систему вложенных разбиений. Различают 2 основных типа: дивизимные&amp;lt;ref name=&amp;quot;Voroncov&amp;quot; /&amp;gt; и алгомеративные алгоритмы. В алгомеративной иерархической кластеризации объекты объединяются во все более и более крупные кластеры.&lt;br /&gt;
:Одним из алгоритмов алгомеративной иерархической кластеризации является &#039;&#039;&#039;алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK)&#039;&#039;&#039;, предложенный Sudipto Guha (Stanford University), Rajeev Rastogi (Bell Laboratories) и Kyuseok Shim (Bell Laboratories)&amp;lt;ref&amp;gt;Sudipto Guha, Rajeev Rastogi, Kyuseok Shim: ROCK: A Robust Clustering Algorithm for Categorical Attributes, Volume 25, Issue 5, July 2000, Pages 345-366&amp;lt;/ref&amp;gt; в 2000 году.  Этот алгоритм отлично подходит для объектов с категориальными признаками, то есть признаками, принимающими свои значения из некоторого множества.&lt;br /&gt;
:В 2005 году была предложена быстрая версия этого ROCK-алгоритма &amp;quot;Quick ROCK&amp;quot;(QROCK).&amp;lt;ref&amp;gt;M. Duttaa, A. Kakoti Mahantab, Arun K. Pujaric QROCK: A quick version of the ROCK algorithm for clustering of categorical data&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Математическое описание алгоритма==&lt;br /&gt;
:Входные данные: множество объектов &amp;lt;math&amp;gt;P = \{p_1, \ldots , p_n\}&amp;lt;/math&amp;gt;, целое число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;0\leq\theta\leq 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Необходимо разделить множество &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; непересекающиеся кластеры.&lt;br /&gt;
:&#039;&#039;&#039;Определение 1.&#039;&#039;&#039; Два объекта &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; будут соседями, если они значительно близки друг к другу, то есть &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; являются соседями, если &amp;lt;math&amp;gt;sim(p_i, p_j)\geq \theta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Мера схожести пары объектов &amp;lt;math&amp;gt;sim(p_i, p_j)&amp;lt;/math&amp;gt; может быть основана на евклидовом расстоянии, коэффициенте Жаккарда или на какой-либо другой неметрической функции схожести. Предполагается, что мера &amp;lt;math&amp;gt;sim&amp;lt;/math&amp;gt; принимает значения от 0 до 1, при этом чем ближе значение меры к 1, тем больше схожи точки. Чаще всего используется мера схожести, основанная на коэффициенте Жаккарда (Jaccard coefficient)&amp;lt;ref&amp;gt;Richard O. Duda and Peter E. Hard. Pattern  Classification  and  Scene  Analysis. A Wiley-Interscience Publication, New York, 1973.&amp;lt;/ref&amp;gt;:  &amp;lt;math&amp;gt;sim(p_i,p_j) = \frac{|p_i\cap p_j|}{|p_i\cup p_j|}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|p_i|&amp;lt;/math&amp;gt; - количество атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt;. Чем больше атрибутов в &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; похожи, тем больше значение &amp;lt;math&amp;gt;|p_i\cap p_j|&amp;lt;/math&amp;gt;. Деление его на &amp;lt;math&amp;gt;|p_i\cup p_j|&amp;lt;/math&amp;gt; гарантирует, что значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; окажется в промежутке от 0 до 1. Таким образом уравнение вычисляет похожесть двух объектов на основе схожести атрибутов, входящих в них.&lt;br /&gt;
 &lt;br /&gt;
:&#039;&#039;&#039;Определение 2.&#039;&#039;&#039; Назовем функцией связи между объектами функцию &amp;lt;math&amp;gt;link(p_i, p_j)&amp;lt;/math&amp;gt;, определяемую как число общих соседей между объектами &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt;. Из определения следует, что чем больше значение функции связи, тем вероятнее, что объекты &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_j&amp;lt;/math&amp;gt; принадлежат одному кластеру.&lt;br /&gt;
:&#039;&#039;&#039;Определение 3.&#039;&#039;&#039; Назовем функцией связи между кластерами функцию &amp;lt;math&amp;gt;link[C_i, C_j] = \sum_{\begin{smallmatrix}p_q\in C_i,\; p_r\in C_j\end{smallmatrix}}^{ } link(p_{q},p_r)&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;
:&#039;&#039;&#039;Определение 4.&#039;&#039;&#039; Целевая функция качества, использующаяся при выборе кластеров для объединения:&lt;br /&gt;
:&amp;lt;math&amp;gt; g(C_i, C_j) = \frac{link[C_i,C_j]}{(n_i + n_j)^{1 + 2f(\theta )} - n_i^{1+2f(\theta )} - n_j^{1+2f(\theta )}}&amp;lt;/math&amp;gt;,  где &amp;lt;math&amp;gt;n_i&amp;lt;/math&amp;gt; - число объектов в кластере &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;, функция &amp;lt;math&amp;gt;f(\theta )&amp;lt;/math&amp;gt; выбирается пользователем, обычно &amp;lt;math&amp;gt;f(\theta ) = \frac{\theta - 1}{\theta + 1}&amp;lt;/math&amp;gt; , &amp;lt;math&amp;gt;n_i^{1+2f(\theta )}&amp;lt;/math&amp;gt; - ожидаемое число связей между парами объектов кластера &amp;lt;math&amp;gt;C_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Определение 5.&#039;&#039;&#039; Симметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; называется матрицей связей, где элемент матрицы &amp;lt;math&amp;gt;a_{ij} = link(p_i,p_j), i = \overline{1,n}, j = \overline{1,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;
Как записано и в описании ядра алгоритма, основную часть метода составляют &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt; обновлений содержимого локальной и глобальной куч.&lt;br /&gt;
&lt;br /&gt;
==Схема реализации последовательного алгоритма==&lt;br /&gt;
:Алгоритм иерархической кластеризации ROCK представлен ниже в виде двух процедур: собственно кластеризации и вычисления связей между точками.  &lt;br /&gt;
===Кластеризация===&lt;br /&gt;
:На вход алгоритм принимает некий набор &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; точек &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Кроме того, заданное значение &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров желаемого разбиения. Изначально каждая точка является отдельным кластером. На шаге 1 вычисляется количество связей между всеми парами точек. На шагах 2 и 3 для каждого &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; строится локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt;. Локальная куча &amp;lt;math&amp;gt;q[s]&amp;lt;/math&amp;gt; содержит те кластеры &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;, для которых &amp;lt;math&amp;gt;link[s,t]&amp;lt;/math&amp;gt; отлична от нуля, причем кластеры в куче упорядочены в порядке убывания, на основе целевой функции качества &amp;lt;math&amp;gt;g(s,t)&amp;lt;/math&amp;gt;. На шаге 4 вычисляется глобальная куча &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, содержащая все текущие кластеры, упорядоченные в порядке убывания на основе &amp;lt;math&amp;gt;g(s,max(q[s]))&amp;lt;/math&amp;gt;. Таким образом на каждом шаге лучший кластер в &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и соответствующий ему максимальный кластер из &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt; наилучшая пара кластеров для объединения их в один кластер.&lt;br /&gt;
:На шаге 5 начинает выполняться цикл &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;, до тех пор, пока в глобальной куче не останется только &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; кластеров. На каждой итерации &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикла на шагах 6-9 из &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; извлекается лучший кластер &amp;lt;math&amp;gt;u&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;, так как он будет объединен с &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, и больше в ней не нужен. Далее кластеры &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; объединяются в новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Далее на шагах 10-15 в цикле &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt; для каждого кластера, который содержит элементы &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; в своей локальной куче, они оттуда удаляются и заменяются на новый кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; создается новая локальная куча.&lt;br /&gt;
:На 17 шаге новый кластер добывляется в локальную кучу, а на 18 шаге уничтожаются локальные кучи для &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ cluster (S,k) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ link := compute\_links(S) \\&lt;br /&gt;
&amp;amp;2.\ \ \mathbf{for\ each}\ s\in S\ \mathbf{do} \\  &lt;br /&gt;
&amp;amp;3.\ \ \ \ q[s] := build\_local\_heap(link,s) \\&lt;br /&gt;
&amp;amp;4.\ \ Q := build\_global\_heap(S,q) \\&lt;br /&gt;
&amp;amp;5.\ \ \mathbf{while}\ size(Q)\ &amp;gt; k\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ u := extract\_max(Q) \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ v := max(q[u]) \\&lt;br /&gt;
&amp;amp;8.\ \ \ \ delete(Q,v) \\&lt;br /&gt;
&amp;amp;9.\ \ \ \ w := merge(u,v) \\&lt;br /&gt;
&amp;amp;10.\ \ \ \mathbf{for\ each}\ x\ \in \ q[u]\ \cup \ q[v]\\&lt;br /&gt;
&amp;amp;11.\ \ \ \ \ link[x,w] :=  link[x,u]\ +\ link[x,v] \\ &lt;br /&gt;
&amp;amp;12.\ \ \ \ \ delete(q[x],u);\ delete(q[x],v) \\&lt;br /&gt;
&amp;amp;13.\ \ \ \ \ insert(q[x],w,g(x,w));\ insert(q[w],x,g(x,w) \\&lt;br /&gt;
&amp;amp;14.\ \ \ \ \ update(Q,x,q[x]) \\&lt;br /&gt;
&amp;amp;15.\ \ \ \} \\&lt;br /&gt;
&amp;amp;16.\ \ \ insert(Q,w,q[w]) \\&lt;br /&gt;
&amp;amp;17.\ \ \ deallocate(q[u]);\ deallocate(q[v]) \\&lt;br /&gt;
&amp;amp;18.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вычисление связей===&lt;br /&gt;
:Для вычисления связи между всеми парами точек в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; рассматривается матрица смежности &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; равна 1 или 0, если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; являются или не являются соседями соответственно. В результате умножения &amp;lt;math&amp;gt;A*A&amp;lt;/math&amp;gt; в позиции &amp;lt;math&amp;gt;A[i,j]&amp;lt;/math&amp;gt; получим количество связей между &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. Для умножения матриц использовался алгоритм Штрассена.&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp;\mathbf{procedure}\ compute\_links(S) \\&lt;br /&gt;
&amp;amp;\mathbf{begin} \\&lt;br /&gt;
&amp;amp;1.\ \ Compute\ nbrlist[i]\ for\ every\ point\ i\ in\ S \\&lt;br /&gt;
&amp;amp;2.\ \ Set\ link[i,j]\ to\ be\ zero\ for\ all\ i,j \\  &lt;br /&gt;
&amp;amp;3.\ \ \mathbf{for}\ i := 1\ \mathbf{to}\ n\ \mathbf{do}\ \{ \\&lt;br /&gt;
&amp;amp;4.\ \ \ \ N := nbrlist[i] \\&lt;br /&gt;
&amp;amp;5.\ \ \ \ \mathbf{for}\ j := 1\ \mathbf{to}\ |N| - 1\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;6.\ \ \ \ \ \ \mathbf{for}\ l := j+1\ \mathbf{to}\ |N|\ \mathbf{do} \\&lt;br /&gt;
&amp;amp;7.\ \ \ \ \ \ \ \ link[N[j],N[l]] := link[N[j],N[l]]+1 \\&lt;br /&gt;
&amp;amp;8.\ \ \} \\&lt;br /&gt;
&amp;amp;\mathbf{end}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Последовательная сложность алгоритма==&lt;br /&gt;
:Вычислительная сложность алгоритма складывается из сложности инициализации, вычисления связей и собственно кластеризации. &lt;br /&gt;
*Инициализация глобальной кучи выполняется за время &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Инициализация локальной кучи также требует &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*Связи между парой точек можно вычислить за &amp;lt;math&amp;gt;O(n*n^{2.37})&amp;lt;/math&amp;gt; шагов, где сложность &amp;lt;math&amp;gt;O(n^{2.37})&amp;lt;/math&amp;gt; - сложность умножения матриц алгоритмом Штрассена. Но это в случае, когда все являются соседями всем. Однако на практике среднее число соседей &amp;lt;math&amp;gt;m_\alpha &amp;lt;/math&amp;gt; и максимальное число соседей &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; оказывается значительно меньше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;. С учетом этих параметров сложность можно записать как &amp;lt;math&amp;gt;O(n m_\alpha m_m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В процедуре кластеризации основные вычисления происходят в цикле &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;. Сам цикл выполняется &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; раз. Внутренний &amp;lt;math&amp;gt;for&amp;lt;/math&amp;gt;-цикл доминирует над сложностью в &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикле. Его сложность &amp;lt;math&amp;gt;O(n\log n)&amp;lt;/math&amp;gt;, так как размер каждой очереди в худшем случае &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и новый объединенный кластер &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; может нуждаться в &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; локальных очередей. Следовательно весь &amp;lt;math&amp;gt;while&amp;lt;/math&amp;gt;-цикл выполняется за &amp;lt;math&amp;gt;O(n^2\log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Время работы ROCK-алгоритма равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m_m&amp;lt;/math&amp;gt; - максимально возможное количество соседей, &amp;lt;math&amp;gt;m_\alpha&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;
* &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt; - входные данные.&lt;br /&gt;
* &amp;lt;math&amp;gt;CML&amp;lt;/math&amp;gt; - процедура, вычисляющая матрицу связей.&lt;br /&gt;
* &amp;lt;math&amp;gt;BLH&amp;lt;/math&amp;gt; - функция, строящая начальную локальную очередь для объекта &amp;lt;math&amp;gt;s_i&amp;lt;/math&amp;gt;.   &lt;br /&gt;
* &amp;lt;math&amp;gt;BGH&amp;lt;/math&amp;gt; - строит начальную глобальную очередь входных объектов.&lt;br /&gt;
* &amp;lt;math&amp;gt;EM&amp;lt;/math&amp;gt; - достает первый кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;DL&amp;lt;/math&amp;gt; - удаляет кластер из кучи.&lt;br /&gt;
* &amp;lt;math&amp;gt;MG&amp;lt;/math&amp;gt; - производит слияние двух кластеров.&lt;br /&gt;
* &amp;lt;math&amp;gt;L&amp;lt;/math&amp;gt; - сумма двух чисел.&lt;br /&gt;
* &amp;lt;math&amp;gt;IN&amp;lt;/math&amp;gt; - добавляет в  кучу новый элемент учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;U&amp;lt;/math&amp;gt; - обновление кучи учитывая целевую функцию качества.&lt;br /&gt;
* &amp;lt;math&amp;gt;FR&amp;lt;/math&amp;gt; - удаление кучи.&lt;br /&gt;
[[File:2.png]]&lt;br /&gt;
:Как видно из графа, алгоритм имеет довольно много узких мест. CML - будет записывать данные в одну и ту же матрицу. BGH - функция, строящая глобальную очередь из объектов. Вообще говоря части функций CML и BGH можно распараллелить изнутри, но об этом в следующем разделе. &lt;br /&gt;
:Также в программе есть вложенные циклы. Внутренний цикл мы можем выполнять параллельно, но вынуждены на каждой итерации делать синхронизацию. Внешний же цикл распараллелить не получится, так как там находятся зависимые по данным операции.&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
:Как видно из графа алгоритма, в алгоритме устойчивой кластеризации с использованием связей довольно сильная зависимость по данным. Параллельно обработать можно некоторые отдельные участки кода и только при больших объемах входных данных. &lt;br /&gt;
:В частности можно выполнять параллельно построение начальной локальной кучи (функция &amp;lt;math&amp;gt;build\_local\_heap&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;math&amp;gt;\frac{n}{p}&amp;lt;/math&amp;gt; локальных куч. &lt;br /&gt;
:Еще можно выполнять параллельно цикл, связанный обновлением матрицы связей, локальной и глобальной кучи после проведения операции слияния. Но после каждой итерации необходимо делать барьерную синхронизацию для операции &amp;lt;math&amp;gt;update&amp;lt;/math&amp;gt;, которая обновляет глобальную кучу.&lt;br /&gt;
:Как видно из пункту 1.6 сложность последовательного алгоритма была равна &amp;lt;math&amp;gt;O(n^2+nm_m m_\alpha + n^2\log n)&amp;lt;/math&amp;gt;. С учетом распараллеливания описанных выше участков кода на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; процессов, теоретически можно получить время выполнения &amp;lt;math&amp;gt;O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Также стоит отметить, что можно распараллелить процедуру &amp;lt;math&amp;gt;compute\_links&amp;lt;/math&amp;gt;, которая умножает матрицы алгоритмом Штрассена. Данный алгоритм имеет смысл выполнять параллельно только если порядок матрицы не менее 1287&amp;lt;ref&amp;gt;Малашонок Г. И., Аветисян А. И., Валеев Ю. Д., Зуев М. С.: Параллельные алгоритмы компьютерной алгебры, Труды Института системного программирования РАН, Выпуск 2, том 8, 2004 &amp;lt;/ref&amp;gt;.&lt;br /&gt;
:Функции &amp;lt;math&amp;gt;build\_local\_heap&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;build\_global\_heap&amp;lt;/math&amp;gt; содержат в себе задачу сортировки, которую также можно выполнить параллельно согласно http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;ref&amp;gt;http://www.intuit.ru/studies/courses/1156/190/lecture/4958&amp;lt;/ref&amp;gt; или М. В. Якобовский &amp;quot;Введение в параллельные методы решения задач: Учебное пособие&amp;quot;&amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2013. – 328 с., илл. – (Серия «Суперкомпьютерное образование») ISBN 978-5-211-06382-2&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Их распараллеливание также может дать некоторое ускорение выполнению алгоритма, но обе функции выполняются ровно один раз.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
:&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; на вход подается &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; объектов и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - количество кластеров, на которое необходимо разделить объекты и некоторое пороговое значение &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, принимающее значение от 0 до 1.&lt;br /&gt;
:Задаются входные данные в частном случае в виде массива длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, но так как вообще говоря данные могут иметь не один атрибут, потребуется матрица размера &amp;lt;math&amp;gt;n*r&amp;lt;/math&amp;gt;, состоящей из 0 и 1, где &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов, а 0 и 1 стоят в зависимости от того, есть ли такой атрибут у данного объекта или нет. &lt;br /&gt;
:&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; Группа кластеризованных данных.&lt;br /&gt;
:Выходные данные представлены в виде массива из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; элементов, где каждому элементу сопоставлен номер кластера, в который он попал.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; на вход подается матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times r&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - число объектов, &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; - количество признаков у объектов. Элемент &amp;lt;math&amp;gt;a[i,j] = 1:&amp;lt;/math&amp;gt; если &amp;lt;math&amp;gt;i-&amp;lt;/math&amp;gt;ый объект обладает &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ым атрибутом, иначе - &amp;lt;math&amp;gt;a[i,j] = 0:&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
:Отношение последовательной и параллельной сложностей: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{O(\frac{n^2}{p}+nm_m m_\alpha + \frac{n^2\log n}{p})}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:Алгоритм является детерменированным.&lt;br /&gt;
:Вычислительная сложность: &amp;lt;math&amp;gt;\frac{O(n^2+nm_m m_\alpha + n^2\log n)}{2n+2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:ROCK-алгоритм хорошо подходит для категорийных данных, таких как ключевые слова, булевские атрибуты, перечисления и т.п. Он хорошо масштабируем, авторы алгоритма создавали его так, чтобы он хорошо работал на больших объемах данных.&lt;br /&gt;
&lt;br /&gt;
=Программная реализация алгоритма=&lt;br /&gt;
==Особенности реализации последовательного алгоритма==&lt;br /&gt;
==Локальность данных и вычислений==&lt;br /&gt;
==Возможные способы и особенности параллельной реализации алгоритма==&lt;br /&gt;
==Масштабируемость алгоритма и его реализации==&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
:Алгоритм устойчивой кластеризации с использованием связей реализован в библиотеке CBA в июне 2016 года.&lt;br /&gt;
:Также он реализован в feed4weka - библиотеке, содержащей алгоритмы для кластеризации данных.&lt;br /&gt;
&lt;br /&gt;
=Литература=&lt;/div&gt;</summary>
		<author><name>Екатерина</name></author>
	</entry>
</feed>